JSONObject排序问题-fastjson map 排序问题(真正的实用)

今天测试了下python

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <!--<version>1.1.36</version>-->
    <version>1.2.29</version>
</dependency>

1.1.36 A版本 和1.2.29 B版本 这2个版本的,其实影响还挺大的。首先咱们这边是使用这个玩意排序的,对排序的结果进行RSA加密。可是若是fastjson版本不一致的话,web

@org.junit.Test
public void test(){

    JSONObject jsonObject = new JSONObject();
    jsonObject.put("a","1");
    jsonObject.put("b","2");
    jsonObject.put("d","3");
    jsonObject.put("c","4");
    //String s2=JSONObject.toJSONString(jsonObject,SerializerFeature.SortField.MapSortField);
    String s2=JSONObject.toJSONString(jsonObject);
    logger.info("--"+s2);

}

上面这个demo:
若是是A版本的话:输出的结果是:json

{“a”:”1”,”b”:”2”,”c”:”4”,”d”:”3”}svg

若是是B版本的结果是:测试

{“d”:”3”,”b”:”2”,”c”:”4”,”a”:”1”}加密

这样就有一个问题,若是咱们依赖这个顺序(好比这个结果进行加密,请求放和服务方不是一个版本的)解密就失败了。
先说下缘由:JSONObject 依赖MapSerializer这类来处理:有一段这样的代码(高版本的)spa

Map<?, ?> map = (Map<?, ?>) object;
final int mapSortFieldMask = SerializerFeature.MapSortField.mask;
if ((out.features & mapSortFieldMask) != 0 || (features & mapSortFieldMask) != 0) {
    if ((!(map instanceof SortedMap)) && !(map instanceof LinkedHashMap)) {
        try {
            map = new TreeMap(map);
        } catch (Exception ex) {
            // skip
        }
    }
}

也就是你必须有SerializerFeature.MapSortField 这个参数才能够使用TreeMap(这个默认是按照key进行排序的).
这个是低版本的:code

Map<?, ?> map = (Map<?, ?>) object;

if (out.isEnabled(SerializerFeature.SortField)) {
   if ((!(map instanceof SortedMap)) && !(map instanceof LinkedHashMap)) {
     try {
         map = new TreeMap(map);
     } catch (Exception ex) {
         // skip
     }
   }
}

A版本的根本没有验证这个参数,直接使用TreeMap。说道这里基本你们就知道怎么解决了。
思路1:直接指定TreeMap以下:xml

JSONObject jsonObject = new JSONObject(new TreeMap<String, Object>());

这个也是大部分网上建议的。不过我看好多人还有本身写了这块的逻辑。
思路2:指定参数项排序

JSONObject.toJSONString(jsonObject,SerializerFeature.SortField.MapSortField)

提示:低版本的没有SerializerFeature.SortField.MapSortField这个参数。