转载自:http://blog.csdn.net/ben0612/article/details/44591161
org.json.JSONObject相信很多人都用过,例如:服务端返回给客户端的数据格式是JSONObject的,那我们通过对它进行解析,把它显示在界面上。
有时候希望服务器跟客户端通信的JSONObjectt的键值对顺序是固定的。
例如:
客户端提交一个JSONObject格式的数据,里面有三个键值对,分别是"a":"a" "b":"b" "c":"c"
服务端原封不动返回给客户端,这个客户端希望接到的是这样的
- {"a":"a","b":"b","c":"c"}
但JSONObject的键值对顺序几乎不能确定的,无规律可循,验证如下:
copy
1.<prename="code"class="html">JSONObjectobject=newJSONObject();
- try{
- object.putOpt("b","b");
- object.putOpt("a","a");
- object.putOpt("c","c");
- }catch(JSONExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
object.toString(),得到的是
{"b":"b","c":"c","a":"a"}
与put进去时候的顺序不一致。
2.
JSONObjectobject=newJSONObject();
- object.putOpt("1","1");
- object.putOpt("2","2");
- object.putOpt("3","3");
- }
object.toString(),得到的是
{"3":"3","2":"2","1":"1"}
与put进去时候的顺序不一致
3.
object.putOpt("我","我");
- object.putOpt("你","你");
- object.putOpt("他","他");
- copy
{"你":"你","他":"他","我":"我"}
与put进去时候的顺序不一致。
以上三个例子,无论键和值是数字、字母还是中文,JSONObject put进去的顺序喝toString得到的顺序,是不一致的。
如果还有疑问,我们看看JSONObject的源码吧。
先看构造方法:
publicJSONObject(){
- nameValuePairs=newHashMapString,Object>();
- 再看putOpt 以及put方法:
publicJSONObjectputOpt(Stringname,Objectvalue)throwsJSONException{
- if(name==null||value==null){
- returnthis;
- }
- returnput(name,value);
-
- publicJSONObjectput(Stringname,Objectvalue)throwsJSONException{
- if(value==null){
- nameValuePairs.remove(name);
- if(valueinstanceofNumber){
- //deviatefromtheoriginalbycheckingallNumbers,notjustfloats&doubles
- JSON.checkDouble(((Number)value).doubleValue());
- nameValuePairs.put(checkName(name),248)"> returnthis;
- 这下可明白了吧,其实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{
-
- privateLinkedHashMapObject,0); font-weight:bold; background-color:inherit">>mHashMap;
- publicChatMsgJSONObject(){
- mHashMap=newLinkedHashMap }
- @Override
- //TODOAuto-generatedmethodstub
- returnput(name,value);
- publicJSONObjectput(Stringkey,Objectvalue)throwsJSONException{
- if(key==null){
- thrownewJSONException("Nullkey.");
- if(value!=null){
- testValidity(value);
- mHashMap.put(key,248)"> }else{
- remove(key);
- publicObjectremove(Stringkey){
- returnmHashMap.remove(key);
- staticvoidtestValidity(Objecto)throwsJSONException{
- if(o!=null){
- if(oinstanceofDouble){
- if(((Double)o).isInfinite()||((Double)o).isNaN()){
- thrownewJSONException("JSONdoesnotallownon-finitenumbers.");
- }elseif(oinstanceofFloat){
- if(((Float)o).isInfinite()||((Float)o).isNaN()){
- publicStringtoString(){
- try{
- IteratorObject>keys=mHashMap.keySet().iterator();
- StringBuffersb=newStringBuffer("{");
- while(keys.hasNext()){
- if(sb.length()>1){
- sb.append(',');
- Objecto=keys.next();
- sb.append(quote(o.toString()));
- sb.append(':');
- sb.append(valueToString(mHashMap.get(o)));
- sb.append('}');
- returnsb.toString();
- }catch(Exceptione){
- returnnull;
- staticStringvalueToString(Objectvalue)throwsJSONException{
- if(value==null||value.equals(null)){
- return"null";
- if(valueinstanceofJSONStringer){
- Objecto;
- o=((JSONStringer)value).toString();
- }catch(Exceptione){
- thrownewJSONException(e.getMessage());
- if(oinstanceofString){
- return(String)o;
- thrownewJSONException("BadvaluefromtoJSONString:"+o);
- returnnumberToString((Number)value);
- if(valueinstanceofBoolean||valueinstanceofJSONObject||valueinstanceofJSONArray){
- returnvalue.toString();
- if(valueinstanceofMap){
- returnnewJSONObject((Map)value).toString();
- if(valueinstanceofCollection){
- returnnewJSONArray((Collection)value).toString();
- returnquote(value.toString());
- }
2.使用fastjson.jar中的com.alibaba.fastjson.annotation.JSONType,用@JSONType来标注实体类
importcom.alibaba.fastjson.annotation.JSONType;
- @JSONType(orders={"type","content","locationUrl"})
- publicclassMessageDto{
- privateStingtype;
- privateStringcontent;
- privateStringlocationUrl;
- publicMessageDto(){
- publicStringgetType(){
- returntype;
- publicvoidsetType(Stringtype){
- this.type=type;
- publicStringgetContent(){
- returncontent;
- publicvoidsetContent(Stringcontent){
- this.content=content;
- publicStringgetLocationUrl(){
- returnlocationUrl;
- publicvoidsetLocationUrl(StringlocationUrl){
- this.locationUrl=locationUrl;
- 使用如下:
copy
MessageDtomsg=newMessageDto();
- msg.setContent("1");
- msg.setLocationUrl("2");
- msg.setType(3);
那么com.alibaba.fastjson.JSON.toJSONString(msg),得到的就是
{"type":"3","content":"1","locationUrl":"2"},
这跟标注的
(orders={"type","locationUrl"})
一致。
以上仅从技术角度来讨论。可能有的人会说,肯定不会有这样的需求,但我确实遇到过这样的需求。多谢。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|