JSON order mixed up

匿名 (未验证) 提交于 2019-12-03 01:49:02

问题:

I've a problem trying to making my page printing out the JSONObject in the order i want. In my code, I entered this:

JSONObject myObject = new JSONObject(); myObject.put("userid", "User 1"); myObject.put("amount", "24.23"); myObject.put("success", "NO"); 

However, when I see the display on my page, it gives:

JSON formatted string: [{"success":"NO","userid":"User 1","bid":24.23}

I need it in the order of userid, amount, then success. Already tried re-ordering in the code, but to no avail. I've also tried .append....need some help here thanks!!

回答1:

You cannot and should not rely on the ordering of elements within a JSON object.

From the JSON specification at http://www.json.org/

An object is an unordered set of name/value pairs

As a consequence, JSON libraries are free to rearrange the order of the elements as they see fit. This is not a bug.



回答2:

I agree with the other answers. You cannot rely on the ordering of JSON elements.

However if we need to have an ordered JSON, one solution might be to prepare a LinkedHashMap object with elements and convert it to JSONObject.

@Test def void testOrdered() {     Map obj = new LinkedHashMap()     obj.put("a", "foo1")     obj.put("b", new Integer(100))     obj.put("c", new Double(1000.21))     obj.put("d", new Boolean(true))     obj.put("e", "foo2")     obj.put("f", "foo3")     obj.put("g", "foo4")     obj.put("h", "foo5")     obj.put("x", null)      JSONObject json = (JSONObject) obj     logger.info("Ordered Json : %s", json.toString())      String expectedJsonString = """{"a":"foo1","b":100,"c":1000.21,"d":true,"e":"foo2","f":"foo3","g":"foo4","h":"foo5"}"""     assertEquals(expectedJsonString, json.toString())     JSONAssert.assertEquals(JSONSerializer.toJSON(expectedJsonString), json) } 

Normally the order is not preserved as below.

@Test def void testUnordered() {     Map obj = new HashMap()     obj.put("a", "foo1")     obj.put("b", new Integer(100))     obj.put("c", new Double(1000.21))     obj.put("d", new Boolean(true))     obj.put("e", "foo2")     obj.put("f", "foo3")     obj.put("g", "foo4")     obj.put("h", "foo5")     obj.put("x", null)      JSONObject json = (JSONObject) obj     logger.info("Unordered Json : %s", json.toString(3, 3))      String unexpectedJsonString = """{"a":"foo1","b":100,"c":1000.21,"d":true,"e":"foo2","f":"foo3","g":"foo4","h":"foo5"}"""      // string representation of json objects are different     assertFalse(unexpectedJsonString.equals(json.toString()))     // json objects are equal     JSONAssert.assertEquals(JSONSerializer.toJSON(unexpectedJsonString), json) } 

You may check my post too: http://www.flyingtomoon.com/2011/04/preserving-order-in-json.html



回答3:

from lemiorhan example i can solve with just change some line of lemiorhan's code use:

JSONObject json = new JSONObject(obj); 

instead of this:

JSONObject json = (JSONObject) obj 

so in my test code is :

Map item_sub2 = new LinkedHashMap(); item_sub2.put("name", "flare"); item_sub2.put("val1", "val1"); item_sub2.put("val2", "val2"); item_sub2.put("size",102);  JSONArray itemarray2 = new JSONArray(); itemarray2.add(item_sub2); itemarray2.add(item_sub2);//just for test itemarray2.add(item_sub2);//just for test   Map item_sub1 = new LinkedHashMap(); item_sub1.put("name", "flare"); item_sub1.put("val1", "val1"); item_sub1.put("val2", "val2"); item_sub1.put("children",itemarray2);  JSONArray itemarray = new JSONArray(); itemarray.add(item_sub1); itemarray.add(item_sub1);//just for test itemarray.add(item_sub1);//just for test  Map item_root = new LinkedHashMap(); item_root.put("name", "flare"); item_root.put("children",itemarray);  JSONObject json = new JSONObject(item_root);  System.out.println(json.toJSONString()); 


回答4:

Real answer can be found in specification, json is unordered. However as a human reader I ordered my elements in order of importance. Not only is it a more logic way, it happened to be easier to read. Maybe the author of the specification never had to read JSON, I do.. So, Here comes a fix:

/**  * I got really tired of JSON rearranging added properties.  * Specification states:  * "An object is an unordered set of name/value pairs"  * StackOverflow states:  * As a consequence, JSON libraries are free to rearrange the order of the elements as they see fit.  * I state:  * My implementation will freely arrange added properties, IN SEQUENCE ORDER!  * Why did I do it? Cause of readability of created JSON document!  */ private static class OrderedJSONObjectFactory {     private static Logger log = Logger.getLogger(OrderedJSONObjectFactory.class.getName());     private static boolean setupDone = false;     private static Field JSONObjectMapField = null;      private static void setupFieldAccessor() {         if( !setupDone ) {             setupDone = true;             try {                 JSONObjectMapField = JSONObject.class.getDeclaredField("map");                 JSONObjectMapField.setAccessible(true);             } catch (NoSuchFieldException ignored) {                 log.warning("JSONObject implementation has changed, returning unmodified instance");             }         }     }      private static JSONObject create() {         setupFieldAccessor();         JSONObject result = new JSONObject();         try {             if (JSONObjectMapField != null) {                 JSONObjectMapField.set(result, new LinkedHashMap());             }         }catch (IllegalAccessException ignored) {}         return result;     } } 


回答5:

JavaScript objects, and JSON, have no way to set the order for the keys. You might get it right in Java (I don't know how Java objects work, really) but if it's going to a web client or another consumer of the JSON, there is no guarantee as to the order of keys.



回答6:

Download "json simple 1.1 jar" from this https://code.google.com/p/json-simple/downloads/detail?name=json_simple-1.1.jar&can=2&q=

And add the jar file to your lib folder

using JSONValue you can convert LinkedHashMap to json string

for more reference click here http://androiddhina.blogspot.in/2015/09/ordered-json-string-in-android.html



回答7:

u can retain the order, if u use JsonObject that belongs to com.google.gson :D

JsonObject responseObj = new JsonObject(); responseObj.addProperty("userid", "User 1"); responseObj.addProperty("amount", "24.23"); responseObj.addProperty("success", "NO"); 

Usage of this JsonObject doesn't even bother using Map

CHEERS!!!



回答8:

As all are telling you, JSON does not maintain "sequence" but array does, maybe this could convince you: Ordered JSONObject



回答9:

For those who're using maven, please try com.github.tsohr/json

 com.github.tsohrjson0.0.1

It's forked from JSON-java but switch its map implementation with LinkedHashMap which @lemiorhan noted above.



回答10:

For Java code, Create a POJO class for your object instead of a JSONObject. and use JSONEncapsulator for your POJO class. that way order of elements depends on the order of getter setters in your POJO class. for eg. POJO class will be like

Class myObj{ String userID; String amount; String success; // getter setters in any order that you want 

and where you need to send your json object in response

JSONContentEncapsulator JSONObject = new JSONEncapsulator("myObject"); JSONObject.setObject(myObj); return Response.status(Status.OK).entity(JSONObject).build(); 

The response of this line will be

{myObject : {//attributes order same as getter setter order.}}



文章来源: JSON order mixed up
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!