2010-10-16 84 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的:{//屬性順序相同作爲吸氣二傳手秩序。}}