加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

【Android 一般进阶】固定JSONObject.toString()键值对顺序

发布时间:2020-12-16 19:00:03 所属栏目:百科 来源:网络整理
导读:转载自:http://blog.csdn.net/ben0612/article/details/44591161 org.json.JSONObject相信很多人都用过,例如:服务端返回给客户端的数据格式是JSONObject的,那我们通过对它进行解析,把它显示在界面上。 有时候希望服务器跟客户端通信的JSONObjectt的键值

转载自:http://blog.csdn.net/ben0612/article/details/44591161

org.json.JSONObject相信很多人都用过,例如:服务端返回给客户端的数据格式是JSONObject的,那我们通过对它进行解析,把它显示在界面上。

有时候希望服务器跟客户端通信的JSONObjectt的键值对顺序是固定的。

例如:

客户端提交一个JSONObject格式的数据,里面有三个键值对,分别是"a":"a" "b":"b" "c":"c"

服务端原封不动返回给客户端,这个客户端希望接到的是这样的

[html] view plain copy
  1. {"a":"a","b":"b","c":"c"}

但JSONObject的键值对顺序几乎不能确定的,无规律可循,验证如下:

copy

    1.<prename="code"class="html">JSONObjectobject=newJSONObject();
  1. try{
  2. object.putOpt("b","b");
  3. object.putOpt("a","a");
  4. object.putOpt("c","c");
  5. }catch(JSONExceptione){
  6. //TODOAuto-generatedcatchblock
  7. e.printStackTrace();
  8. }
 

object.toString(),得到的是

copy
    {"b":"b","c":"c","a":"a"}
与put进去时候的顺序不一致。

2.

copy
    JSONObjectobject=newJSONObject();
  1. object.putOpt("1","1");
  2. object.putOpt("2","2");
  3. object.putOpt("3","3");
  4. }
object.toString(),得到的是
copy
    {"3":"3","2":"2","1":"1"}
与put进去时候的顺序不一致

3.
copy
    object.putOpt("我","我");
  1. object.putOpt("你","你");
  2. object.putOpt("他","他");
  3. copy
      {"你":"你","他":"他","我":"我"}

    与put进去时候的顺序不一致。

    以上三个例子,无论键和值是数字、字母还是中文,JSONObject put进去的顺序喝toString得到的顺序,是不一致的。


    如果还有疑问,我们看看JSONObject的源码吧。

    先看构造方法:

    copy
      publicJSONObject(){
    1. nameValuePairs=newHashMapString,Object>();
    2. 再看putOpt 以及put方法:
      copy
        publicJSONObjectputOpt(Stringname,Objectvalue)throwsJSONException{
      1. if(name==null||value==null){
      2. returnthis;
      3. }
      4. returnput(name,value);
      5. publicJSONObjectput(Stringname,Objectvalue)throwsJSONException{
      6. if(value==null){
      7. nameValuePairs.remove(name);
      8. if(valueinstanceofNumber){
      9. //deviatefromtheoriginalbycheckingallNumbers,notjustfloats&doubles
      10. JSON.checkDouble(((Number)value).doubleValue());
      11. nameValuePairs.put(checkName(name),248)"> returnthis;
      12. 这下可明白了吧,其实JSONObject本质是用HashMap实现的,而HashMap是散列的,是链式存储结构。

        HashMap的存储过程,根据该元素自身提供的hashcode计算出散列值(在这一点上,就可以知道,元素放进去的位置是无法确定的,只有在获取hashcode后才知道),该值就是数组的下标,然后将该元素放入数组位置的链表中。

        那么如何固定它的顺序呢,put进去是我们想要的呢?有两个方法:自定义JSONObject(不用HashMap改用LinkHashMap实现)或使用com.alibaba.fastjson.annotation.JSONType标注

        1.自定义JSONObject(不用HashMap改用LinkHashMap实现),LinkedHashMap是有序的,代替无序的HashMap,把父类用到HashMap的地方都改成LinkedHashMap即可,主要是put跟toString的几个方法。

        copy

          publicclassMyJSONObjectextendsJSONObject{
        1. privateLinkedHashMapObject,0); font-weight:bold; background-color:inherit">>mHashMap;
        2. publicChatMsgJSONObject(){
        3. mHashMap=newLinkedHashMap }
        4. @Override
        5. //TODOAuto-generatedmethodstub
        6. returnput(name,value);
        7. publicJSONObjectput(Stringkey,Objectvalue)throwsJSONException{
        8. if(key==null){
        9. thrownewJSONException("Nullkey.");
        10. if(value!=null){
        11. testValidity(value);
        12. mHashMap.put(key,248)"> }else{
        13. remove(key);
        14. publicObjectremove(Stringkey){
        15. returnmHashMap.remove(key);
        16. staticvoidtestValidity(Objecto)throwsJSONException{
        17. if(o!=null){
        18. if(oinstanceofDouble){
        19. if(((Double)o).isInfinite()||((Double)o).isNaN()){
        20. thrownewJSONException("JSONdoesnotallownon-finitenumbers.");
        21. }elseif(oinstanceofFloat){
        22. if(((Float)o).isInfinite()||((Float)o).isNaN()){
        23. publicStringtoString(){
        24. try{
        25. IteratorObject>keys=mHashMap.keySet().iterator();
        26. StringBuffersb=newStringBuffer("{");
        27. while(keys.hasNext()){
        28. if(sb.length()>1){
        29. sb.append(',');
        30. Objecto=keys.next();
        31. sb.append(quote(o.toString()));
        32. sb.append(':');
        33. sb.append(valueToString(mHashMap.get(o)));
        34. sb.append('}');
        35. returnsb.toString();
        36. }catch(Exceptione){
        37. returnnull;
        38. staticStringvalueToString(Objectvalue)throwsJSONException{
        39. if(value==null||value.equals(null)){
        40. return"null";
        41. if(valueinstanceofJSONStringer){
        42. Objecto;
        43. o=((JSONStringer)value).toString();
        44. }catch(Exceptione){
        45. thrownewJSONException(e.getMessage());
        46. if(oinstanceofString){
        47. return(String)o;
        48. thrownewJSONException("BadvaluefromtoJSONString:"+o);
        49. returnnumberToString((Number)value);
        50. if(valueinstanceofBoolean||valueinstanceofJSONObject||valueinstanceofJSONArray){
        51. returnvalue.toString();
        52. if(valueinstanceofMap){
        53. returnnewJSONObject((Map)value).toString();
        54. if(valueinstanceofCollection){
        55. returnnewJSONArray((Collection)value).toString();
        56. returnquote(value.toString());
        57. }
        2.使用fastjson.jar中的com.alibaba.fastjson.annotation.JSONType,用@JSONType来标注实体类
        copy
          importcom.alibaba.fastjson.annotation.JSONType;
        1. @JSONType(orders={"type","content","locationUrl"})
        2. publicclassMessageDto{
        3. privateStingtype;
        4. privateStringcontent;
        5. privateStringlocationUrl;
        6. publicMessageDto(){
        7. publicStringgetType(){
        8. returntype;
        9. publicvoidsetType(Stringtype){
        10. this.type=type;
        11. publicStringgetContent(){
        12. returncontent;
        13. publicvoidsetContent(Stringcontent){
        14. this.content=content;
        15. publicStringgetLocationUrl(){
        16. returnlocationUrl;
        17. publicvoidsetLocationUrl(StringlocationUrl){
        18. this.locationUrl=locationUrl;
        19. 使用如下:

          copy

            MessageDtomsg=newMessageDto();
          1. msg.setContent("1");
          2. msg.setLocationUrl("2");
          3. msg.setType(3);
          那么com.alibaba.fastjson.JSON.toJSONString(msg),得到的就是
          copy
            {"type":"3","content":"1","locationUrl":"2"},
          这跟标注的
          copy
            (orders={"type","locationUrl"})
          一致。

          以上仅从技术角度来讨论。可能有的人会说,肯定不会有这样的需求,但我确实遇到过这样的需求。多谢。

          (编辑:李大同)

          【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读