Подтвердить что ты не робот

Замедленный заказ 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.... нужна помощь здесь спасибо!

4b9b3361

Ответ 1

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

Из спецификации JSON на http://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)
}

Вы также можете проверить мой пост: http://www.flyingtomoon.com/2011/04/preserving-order-in-json.html

Ответ 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());

Ответ 4

Реальный ответ можно найти в спецификации, 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;
    }
}

Ответ 5

Объекты JavaScript и JSON не имеют способа установить порядок для ключей. Вы можете получить это правильно на Java (я не знаю, как работают объекты Java), но если это произойдет с веб-клиентом или другим пользователем JSON, нет никакой гарантии относительно порядка ключей.

Ответ 7

Как вам все говорят, JSON не поддерживает "последовательность", но массив делает, может быть, это может вас убедить: Заказ JSONObject

Ответ 8

u может сохранить порядок, если u использует JsonObject, принадлежащий com.google.gson: D

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

Использование этого JsonObject даже не требует использования Map < >

CHEERS!!!

Ответ 9

Для тех, кто использует 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, но переключает его реализацию карты с LinkedHashMap, который отмечен выше.

Ответ 10

Для Java-кода создайте класс POJO для вашего объекта вместо JSONObject. и используйте JSONEncapsulator для вашего класса POJO. таким образом, порядок элементов зависит от порядка геттер-сеттеров в вашем классе POJO. например. Класс 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: {//атрибуты упорядочиваются так же, как и порядок настройки получателя.}}