2010-10-16 46 views
38

我试图让我的页面打印出我想要的订单JSONObject的问题。在我的代码,我进入了这个:JSON订单混合

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

然而,当我看到我的网页上显示,它给:

JSON格式的字符串:[{"success":"NO","userid":"User 1","bid":24.23}

我需要它的用户ID的顺序,金额,然后成功。已经尝试在代码中重新排序,但无济于事。我也试过.append ....在这里需要一些帮助,谢谢!

+0

这是使用'org.json'东西?的 – skaffman 2010-10-16 09:07:33

+0

可能重复[JSONObject的:为什么的JSONObject改变属性的顺序](http://stackoverflow.com/questions/17229418/jsonobject-why-jsonobject-changing-the-order-of-attributes) – Leo 2014-01-26 13:19:48

+3

@Leo这是一个可能出现三年后发布的问题的重复,并且有与此链接的答案?如果有的话,另一个问题应该作为一个骗局关闭。 – 2014-01-26 21:47:27

回答

2

JavaScript对象和JSON无法设置键的顺序。您可能在Java中正确使用它(我不知道Java对象是如何工作的),但是如果它发送给Web客户端或JSON的其他使用者,则不能保证密钥的顺序。

+0

那么,他们在这里陈述如下(如果这确实是gson)。 http://google-gson.googlecode.com/svn/tags/1.2.3/docs/javadocs/com/google/gson/JsonObject.html“此对象的成员元素按其添加顺序进行维护。” – Ted 2014-08-05 14:46:21

79

您不能也不应该依赖JSON对象中元素的排序。

从JSON规范在http://www.json.org/

一个目的是一组无序的 名称/值对

因此, JSON库可以自由地重新排列的元素的顺序因为他们认为合适。 这不是一个错误。

+6

** _因此,JSON库可以自由地重新排列元素的顺序,因为他们认为合适。这不是一个bug ._ ** 只是想知道,重新安排元素有什么好处。 感谢, durai。 – durai 2012-07-11 12:57:19

+6

@durai:一些关联容器使用排序功能来排列它们的项目,因此不保留排序以允许更快的元素检索。 – ereOn 2012-10-29 18:27:18

+0

那么,他们在这里陈述如下(如果这确实是gson)。 http://google-gson.googlecode.com/svn/tags/1.2.3/docs/javadocs/com/google/gson/JsonObject.html“此对象的成员元素按其添加顺序进行维护。” – Ted 2014-08-05 14:47:17

11

我同意其他答案。你不能依赖于JSON元素的排序。

但是,如果我们需要有一个有序的JSON,一种解决方案可能是准备一个LinkedHashMap对象与元素并将其转换为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) 
} 

通常情况下,订单不会保留如下。

@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) 
} 

你可以检查我的帖子太:http://www.flyingtomoon.com/2011/04/preserving-order-in-json.html

+2

这个解决方案对我不适用。转换为JSONObject引发异常。如果我构造JSONObject(map),那么顺序不会被保留。如果我没有转换就离开分配,那么字符串被分配而不是对象。 – Ernest 2014-12-25 09:00:47

+1

这对我有效,但我不得不使用'JSONObject.toJSONString(obj)'。否则,我会收到上面提到的@Ernest的转换错误。 – Tricky12 2015-07-22 17:44:27

+0

@ Tricky12这对我来说没有意义:1)'org.json.JSONObject'没有这个方法。 2.)似乎可以做'org.json.JSONObject.valueToString(obj)'技巧的方法不起作用,因为它在内部执行:'new JSONObject(map).toString()',它再次使用' HashMap'而不是'LinkedHashMap'里面:'this.map = new HashMap ();' – 2017-10-27 10:13:25

3

从lemiorhan例如 我可以解决只是改变lemiorhan代码 使用的一些行:

JSONObject json = new JSONObject(obj); 

,而不是这样的:

JSONObject json = (JSONObject) obj 

所以在我的测试代码:

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()); 
+0

如果JSONObject可以构造为由LinkedHashMap支持,那将会很棒。应该在哪里发布这样的改进? – 2017-10-27 11:40:12

2

下载“JSON简单1。1罐”从这个https://code.google.com/p/json-simple/downloads/detail?name=json_simple-1.1.jar&can=2&q=

而且jar文件添加到使用JSONValue可以LinkedHashMap的转换成JSON字符串

更多参考,请点击这里您的lib文件夹

http://androiddhina.blogspot.in/2015/09/ordered-json-string-in-android.html

+0

呜呜呜。最后!!!,这是唯一的解决方案。非常感谢。 – Sayka 2016-03-19 21:33:23

+0

这是完美的。非常感谢,。 – coolgokul 2017-02-26 02:13:09

3

真正的答案可能是在说明书中发现,JSON是无序的。 但是作为一个人阅读我命令我的要素按重要性排序。它不仅是一个更逻辑的方式,它发生在更容易阅读。也许规范的作者从未有过阅读JSON,我做..所以,她E排在修复:

/** 
* 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; 
    } 
} 
+0

尼斯〜破解〜解决方案。在我的'JSONObject'版本中,'map'字段是最终的,但它似乎仍然有效。如果它不起作用,这个添加应该有助于克服'final':https://stackoverflow.com/a/3301720/1520422 – 2017-10-27 12:03:33

1

ü可以保留顺序,如果u使用的JSONObject属于com.google.gson:d本的JSONObject的

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

用途使用地图根本不屑<>

CHEERS!

0

对于那些使用maven谁的时候,请尽量com.github.tsohr/json

<!-- https://mvnrepository.com/artifact/com.github.tsohr/json --> 
<dependency> 
    <groupId>com.github.tsohr</groupId> 
    <artifactId>json</artifactId> 
    <version>0.0.1</version> 
</dependency> 

它从JSON-java分叉,但切换其映射实现with LinkedHashMap这@lemiorhan如上所述。

0

对于Java代码,为您的对象,而不是一个JSONObject创建一个POJO类。 并为您的POJO类使用JSONEncapsulator。 这种方式元素的顺序取决于POJO类中的getter setter的顺序。例如 。 POJO类就会像

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

,并在您需要将您的JSON对象响应

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

这条线的响应将是

{myObject的:{//属性顺序相同作为吸气二传手秩序。}}