JSON命令混淆了

JSO*_*guy 57 java json

我试图JSONObject按照我想要的顺序打印我的页面时遇到问题.在我的代码中,我输入了这个:

JSONObject myObject = new JSONObject();
myObject.put("userid", "User 1");
myObject.put("amount", "24.23");
myObject.put("success", "NO");
Run Code Online (Sandbox Code Playgroud)

但是,当我在页面上看到显示时,它会给出:

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

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

Adr*_*ith 99

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

来自http://www.json.org/的JSON规范

对象是一组无序的名称/值对

因此,JSON库可以根据需要重新排列元素的顺序.这不是一个错误.

  • **_因此,JSON库可以根据需要重新排列元素的顺序.这不是一个错误._**只是好奇地知道,重新安排元素有什么好处.谢谢,杜莱. (7认同)
  • @durai:一些关联容器使用排序函数来排列它们的项目,因此不保留排序以允许更快的元素检索. (7认同)
  • @Thomas这是关于JSON对象,而不是JSON数组 (3认同)
  • @Ted那是GSON,*由Google开发的用于处理JSON的Java库*.如果他们想要重新排序字段,则由每个库开发人员决定. (2认同)

lem*_*han 12

我同意其他答案.您不能依赖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)
}
Run Code Online (Sandbox Code Playgroud)

通常,订单不会保留如下.

@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)
}
Run Code Online (Sandbox Code Playgroud)

您也可以查看我的帖子:http://www.flyingtomoon.com/2011/04/preserving-order-in-json.html

  • 这个解决方案对我不起作用.转换为JSONObject会引发异常.如果我构造JSONObject(map),则不保留顺序.如果我在没有转换的情况下离开赋值,则分配字符串而不是object. (3认同)
  • @FredericLeitenberger 我相信它是 Groovy,一种基于 java 的脚本语言。 (2认同)

thy*_*yzz 10

如果您使用属于 com.google.gson 的 JsonObject,则可以保留顺序:D

JsonObject responseObj = new JsonObject();
responseObj.addProperty("userid", "User 1");
responseObj.addProperty("amount", "24.23");
responseObj.addProperty("success", "NO");
Run Code Online (Sandbox Code Playgroud)

使用这个 JsonObject 甚至不需要使用 Map<>

干杯!!!


san*_*ang 5

从lemiorhan的示例中,我可以通过更改lemiorhan的代码使用的某些行来解决:

JSONObject json = new JSONObject(obj);
Run Code Online (Sandbox Code Playgroud)

代替这个:

JSONObject json = (JSONObject) obj
Run Code Online (Sandbox Code Playgroud)

所以在我的测试代码中是:

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());
Run Code Online (Sandbox Code Playgroud)


Uni*_*dow 5

真正的答案可以在规范中找到,json 是无序的。然而,作为人类读者,我按重要性排序了我的元素。它不仅是一种更符合逻辑的方式,而且碰巧更容易阅读。也许规范的作者从来不需要阅读 JSON,我会阅读 .. 所以,这里有一个修复:

/**
 * 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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ich 3

JavaScript 对象和 JSON 无法设置键的顺序。您可能会在 Java 中得到正确的结果(我真的不知道 Java 对象是如何工作的),但如果它发送到 Web 客户端或 JSON 的另一个使用者,则无法保证键的顺序。