Вопрос-ответ

JSON order mixed up

Перепутан порядок JSON

У меня проблема при попытке заставить мою страницу печатать JSONObject в нужном мне порядке. В своем коде я ввел это:

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}]

Мне это нужно в порядке идентификатора пользователя, суммы, затем успеха. Уже пробовал изменить порядок в коде, но безрезультатно. Я тоже пробовал .append.... нужна помощь, спасибо!!

Переведено автоматически
Ответ 1

Вы не можете и не должны полагаться на порядок элементов внутри объекта JSON.

Из спецификации JSON на https://www.json.org /


Объект представляет собой неупорядоченный набор пар имя / значение


Как следствие, библиотеки JSON могут свободно изменять порядок элементов по своему усмотрению. Это не ошибка.

Ответ 2

Я согласен с другими ответами. Вы не можете полагаться на порядок элементов 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)
}

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

Ответ 3

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!!!

Ответ 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;
}
}
java json