Замедленный заказ 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 на 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, нет никакой гарантии относительно порядка ключей.
Ответ 6
Загрузите "json simple 1.1 jar" из этого https://code.google.com/p/json-simple/downloads/detail?name=json_simple-1.1.jar&can=2&q=
И добавьте файл jar в папку lib
используя JSONValue, вы можете преобразовать LinkedHashMap в строку json
для получения дополнительной справки нажмите здесь http://androiddhina.blogspot.in/2015/09/ordered-json-string-in-android.html
Ответ 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: {//атрибуты упорядочиваются так же, как и порядок настройки получателя.}}