Сохраняйте порядок ключей JSON во время преобразования JSON в CSV

82

Я использую предоставленную здесь библиотеку JSON http://www.json.org/java/index.html для преобразования имеющейся у меня строки json в CSV. Но у меня проблема в том, что порядок ключей теряется после преобразования.

Это код преобразования:

    JSONObject jo = new JSONObject(someString);
    JSONArray ja = jo.getJSONArray("items");
    String s = CDL.toString(ja);
    System.out.println(s);

Это содержимое someString:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ]
}

Вот результат:

WO,QU,WR,QA,NO
hasd,asd,qwe,end,qwer

В то время как я ожидаю сохранить порядок ключей:

WR,QU,QA,WO,NO
qwe,asd,end,hasd,qwer

Могу ли я получить такой результат с помощью этой библиотеки? Если нет, существует ли какая-либо другая библиотека, которая предоставит возможность сохранять порядок ключей в результате?

Hery
источник
4
Словари не отсортированы. Я даже не думаю, что JSON гарантирует порядок.
Falmarri
2
Спасибо за информацию. Но у меня нет выбора, кроме как использовать JSON в моем приложении, и мое приложение должно сохранять порядок ключей :(
Hery
В моем случае проблема не в отсутствии порядка, а в том, что он недетерминирован. Иногда я получаю ключ fooперед ключом, barа иногда и barраньше foo. Это затрудняет написание тестов для.
Шридхар Сарнобат,
Я тоже столкнулся с этой необходимостью, но она для быстрого сравнения журналов во время тестирования в реальном времени. Мне нужно сравнить недавно созданные журналы с ранее созданными журналами в режиме реального времени для приложения с высокой пропускной способностью. Есть и другие способы сделать это, но я бы предпочел, чтобы журналы были в формате JSON. Однако, чтобы свести к минимуму использование ЦП, я пишу собственный модуль записи JSON напрямую в строку. Мне вообще не нужна внутренняя структура, и я могу поддерживать порядок ключей для быстрого сравнения строк журналов. Есть веские причины желать предсказуемого порядка.
Джо Лапп
напишите свой собственный код для преобразования JSON в специально упорядоченный файл CSV, таким образом, вы уважаете то, что должны быть оба формата.
Martijn Scheffer

Ответы:

95

Есть (хакерские) способы сделать это ... но вы не должны.

В JSON объект определяется так:

Объект - это неупорядоченный набор пар имя / значение.

См. Http://json.org .

Большинство реализаций JSON не прилагают никаких усилий для сохранения порядка пар имя / значение объекта, поскольку он (по определению) не имеет значения.

Если вы хотите сохранить порядок, вам необходимо переопределить структуру данных; например

{
    "items":
    [
        [
            {"WR":"qwe"},
            {"QU":"asd"},
            {"QA":"end"},
            {"WO":"hasd"},
            {"NO":"qwer"}
        ],
    ]
}

или проще:

{
    "items":
    [
        {"WR":"qwe"},
        {"QU":"asd"},
        {"QA":"end"},
        {"WO":"hasd"},
        {"NO":"qwer"}
    ]
}

СЛЕДОВАТЬ ЗА

Спасибо за информацию, но у меня нет выбора, кроме как использовать JSON в моем приложении, и мое приложение должно сохранять порядок ключей независимо от определения объекта JSON ... Мне не разрешено изменять формат файла JSON также...

Вам нужно вести жесткий разговор с тем, кто разработал эту файловую структуру, и не позволит вам ее изменить. Это / они совершенно неправы. Вам нужно их убедить.

Если они действительно не позволят вам это изменить:

  • Вы должны настаивать на том, чтобы не называть его JSON ... потому что это не так.
  • Вы должны указать, что вам придется писать / изменять код специально для обработки этого «не JSON» формата ... если вы не найдете какую-либо реализацию JSON, которая сохраняет порядок. Если они платные клиенты, убедитесь, что они платят за эту дополнительную работу, которую вы должны выполнить.
  • Вы должны указать, что если «не JSON» нужно использовать каким-либо другим инструментом, это будет проблематично. Действительно, эта проблема будет повторяться снова и снова ...

Такие вещи очень плохие. С одной стороны, ваше программное обеспечение будет нарушать устоявшуюся / давнюю спецификацию, разработанную для обеспечения взаимодействия. С другой стороны, придурки, которые разработали этот убогий (не JSON!) Формат файла, вероятно, шлёпают чужие системы и т. Д., Потому что системы не могут справиться с их ерундой.

ОБНОВИТЬ

Также стоит прочитать, что говорится в JSON RFC (RFC 7159) по этому поводу. Вот несколько выдержек:

За годы, прошедшие после публикации RFC 4627, JSON нашел очень широкое применение. Этот опыт выявил определенные закономерности, которые, хотя и допускались спецификациями, вызывали проблемы взаимодействия.

Нотация объектов JavaScript (JSON) - это текстовый формат для сериализации структурированных данных. ...

JSON может представлять четыре примитивных типа (строки, числа, логические значения и null) и два структурированных типа (объекты и массивы).

Объект представляет собой неупорядоченную коллекцию из нуля или более пар имя / значение, где имя - это строка, а значение - это строка, число, логическое значение, null, объект или массив.

Было замечено, что библиотеки синтаксического анализа JSON различаются в зависимости от того, делают ли они порядок элементов объекта видимым для вызывающего программного обеспечения. Реализации, поведение которых не зависит от порядка элементов, будут взаимодействовать в том смысле, что на них не будут влиять эти различия.

Стивен С
источник
3
@YogeshSomani - «решение» состоит в том, чтобы получить правильную библиотеку JSON и «взломать» ее так, чтобы она сохраняла порядок ключей. См. Пример ответа Гэри. Но вы не должны ожидать, что стандартная библиотека JSON сделает это, потому что это ПЛОХАЯ ИДЕЯ, поощряющая злоупотребление спецификацией JSON, подобное этой. Реальное решение - исправить ваше приложение для правильного использования JSON.
Stephen C
10
Замечательно быть максимально чистым и абсолютным, но давайте не будем обманывать себя, существуют сценарии реального мира, в которых файл JSON требует сохранения упорядочения определенных значений. Передавать и принимать их в любом порядке - это фундаментальный подход json, но я считаю, что это отличается от возможности принимать документ json и сериализовать / десериализовать в равной степени. Это распространенный вариант использования - взять документ json и использовать его для формирования документа другого стандартного WDDX, HTML и т. Д., Где необходимо сохранить порядок
Эндрю Норман
3
@AndrewNorman - Если бы то, что вы сказали о «потребности», было правдой, тогда спецификация должна была быть изменена. Реальность такова, что в JSON легко представить упорядочивание другими способами.
Stephen C
2
JSON требует только, чтобы информация не была закодирована в порядке ключей; иначе это не JSON. Согласованность сериализации - это другой вопрос. В рамках одного приложения согласованность обычно можно гарантировать с помощью общей библиотеки JSON, но есть исключения, например, когда одно решение охватывает несколько платформ или фреймворков. В этих случаях вам нужно либо найти способ справиться с несогласованностью (вводя неэффективность), либо найти способ обеспечить последовательность. Оба подхода действительны.
Джо Лапп
2
«JSON требует, чтобы информация не была закодирована в порядке ключей; в противном случае это не JSON». . Я думаю, вы это неправильно написали. Правильное утверждение: «JSON не требует, чтобы информация кодировалась в порядке ключей». Между этими двумя утверждениями есть большая разница ....
Стивен С.
47

Поддерживать порядок довольно просто. У меня была такая же проблема с поддержанием порядка от уровня БД до уровня пользовательского интерфейса.

Откройте файл JSONObject.java. Он внутренне использует HashMap, который не поддерживает порядок.

Измените его на LinkedHashMap:

    //this.map = new HashMap();
    this.map = new LinkedHashMap();

Это сработало для меня. Дай мне знать в комментариях. Я предлагаю, чтобы сама библиотека JSON имела еще один класс JSONObject, который поддерживает порядок, например JSONOrderdObject.java. Я очень плохо выбираю имена.

Гэри
источник
2
svn checkout json-simple. измените файл org.json.simple.JSONObject, <code> JOSNObject расширяет LinkedHashMap ... </code> из <code> .. HashMap .. </code>, исправьте импорт, и он работает для меня. v1.1.1.
Marku
2
Это отличное однострочное решение, которое я бы никогда не подумал попробовать. Работает отлично, и мне не пришлось менять какой-либо другой код. +1
DaaaahWhoosh
Отличное исправление. Вы герой, сэр
Грегори Новаковски
не сработало, я добавил импорт, изменил его, как вы сказали, даже попытался сделать это так: this.map = new LinkedHashMap<String, Object>();все еще не работает. Пожалуйста помоги ?
Тарек
4
Хаха, да ну? Измените библиотеку JSON под свои нужды? Я могу только представить, как это войдет в базы знаний компании. «Выполните чистую установку mvn, загрузите банку, найдите ее, декомпилируйте, затем замените HashMap на LinkedHashMap». Это отлично подойдет для групп разработчиков, состоящих из нескольких человек (нет).
Крис Нев
23

JSONObject.javaберет любую карту, которую вы проходите. Это может быть LinkedHashMapили TreeMapпотребуется hashmapтолько тогда, когда карта пуста.

Вот конструктор JSONObject.javaкласса, который будет проверять карту.

 public JSONObject(Map paramMap)
  {
    this.map = (paramMap == null ? new HashMap() : paramMap);
  }

Итак, прежде чем создать конструкцию объекта json LinkedHashMapи затем передать ее конструктору следующим образом,

LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();

jsonOrderedMap.put("1","red");
jsonOrderedMap.put("2","blue");
jsonOrderedMap.put("3","green");

JSONObject orderedJson = new JSONObject(jsonOrderedMap);

JSONArray jsonArray = new JSONArray(Arrays.asList(orderedJson));

System.out.println("Ordered JSON Fianl CSV :: "+CDL.toString(jsonArray));

Так что менять JSONObject.javaкласс не нужно . Надеюсь, это кому-то поможет.

Дипак Нагарадж
источник
3
Хороший ответ, работает для нормальной java, но не работает на android. Проверяю org.json.JSONObject в android, жаль, что андроид до сих пор использует hashmap, созданный внутри. Он копирует только пары имя / значение из paramMap в HashMap ... :(
正宗 白 布鞋
Я заказал JsonObject, но когда я пытаюсь добавить этот объект в JsonArray, он дает мне неупорядоченный. Мне нужно поместить объект в массив, мне нужны объекты массива, затем я помещаю заголовок в массив и отправляю обратно. Пример: один объект; {CUSTOMER_SECTOR_ID = 611, CUSTOMER_NO = 0000003204, CUSTOMER_NAME = MARMARİS - KARAS GIDA KARAS TÜKETİM MADDELERİ GIDA LOJ.} Я получаю это, если помещаю два объекта в массив: ["{" CUSTOMER_NAME ":" СИЛАРА ГИДА ":" СИЛАРА ГИДА " 0000003122 "," CUSTOMER_SECTOR_ID ":" 611 "}, {" CUSTOMER_NAME ":" M ":" 0013114714 "," CUSTOMER_SECTOR_ID ":" 611 "}] Как видите, это неверно. Как я могу это исправить
Сахин Янлык
2
@Deepak Nagaraj. Я пробовал ваше решение, но оно не сработало, JSONObjectон не заказан как мой LinkedHashMap. Вы пользуетесь org.jsonбиблиотекой?
Ismail Sen
1
Это не org.jsonтот ... Он определяет HashMapвнутренне, что бы Mapвы ему ни дали: @Deepak, вы можете указать нам на реализацию, которую вы использовали?
Campa
8
Это не будет работать с org.jsonбиблиотекой. Когда вы создаете новый JSONObjectобъект, передавая карту в качестве аргумента, он всегда будет преобразован в HashMap. Конструктор сначала создает новую карту:, this.map = new HashMap<String, Object>();а затем перебирает вашу карту, копируя каждый элемент в свой HashMap.
Итачи
13

Более подробное, но широко применимое решение такого рода проблем состоит в использовании пары структур данных: списка, содержащего упорядочение, и карты, содержащей отношения.

Например:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ],
    "itemOrder":
        ["WR", "QU", "QA", "WO", "NO"]
}

Вы перебираете список itemOrder и используете его для поиска значений карты. Порядок сохраняется, без клуджей.

Я использовал этот метод много раз.

Роботизированные штаны
источник
Это усложняется, если ваша карта - это не просто пары ключ-значение ...
zfj3ub94rf576hc4eegm 03
10

Еще одно хакерское решение с использованием рефлекса:

JSONObject json = new JSONObject();
Field map = json.getClass().getDeclaredField("map");
map.setAccessible(true);//because the field is private final...
map.set(json, new LinkedHashMap<>());
map.setAccessible(false);//return flag
сказка
источник
1
Я не получил вашего ответа
М. Усман Хан
1
Хитрость заключается в том, чтобы изменить класс внутренне, чтобы использовать LinkedHashMap вместо HashMap по умолчанию, чтобы объект JSON имел данные в том порядке, в котором вы их помещаете, это не сортируется напрямую, но это сработало для меня, поскольку проанализированные данные уже отсортированы .
fabe
выглядит неплохо, но как разобрать Json String ПОСЛЕ map.set (json, new LinkedHashMap <> ()); потому что Json String передается в конструкторе правильно? например, новый JSONObject (jsonString).
М. Усман Хан
Кроме того, это не сработало. нет поля «карта», есть поле «nameValuePairs», которое уже является LinckedHashMap, и оно по-прежнему не работает.
М. Усман Хан
1
Какую реализацию JSONObject вы используете? Я использую org.json версии 20140107, и мне пришлось сохранить порядок, и вот как это сработало для меня.
fabe
4

Просто наткнулся на ту же проблему, я считаю, что окончательное решение, используемое автором, заключалось в использовании настраиваемого ContainerFactory:

public static Values parseJSONToMap(String msgData) {
    JSONParser parser = new JSONParser();
    ContainerFactory containerFactory = new ContainerFactory(){
        @Override
        public Map createObjectContainer() {
            return new LinkedHashMap();
        }

        @Override
        public List creatArrayContainer() {
            return null;
        }
    };
    try {
        return (Map<String,Object>)parser.parse(msgData, containerFactory);
    } catch (ParseException e) {
        log.warn("Exception parsing JSON string {}", msgData, e);
    }
    return null;
}  

см. http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/parser/JSONParser.html#parse(java.io.Reader,org.json.simple.parser.ContainerFactory)

Рафаэль
источник
действительно очень хорошее и практичное решение. Как насчет написания метода локального анонимного внутреннего класса для containerFactory?
Шайлеш Саксена
3

Решено.

Я использовал библиотеку JSON.simple отсюда https://code.google.com/p/json-simple/, чтобы прочитать строку JSON, чтобы сохранить порядок ключей и использовать библиотеку JavaCSV отсюда http://sourceforge.net/ projects / javacsv / для преобразования в формат CSV.

Hery
источник
Я удивлен, что это сработало. Согласно моему прочтению как кода, так и комментариев класса JSONObject ( code.google.com/p/json-simple/source/browse/trunk/src/main/java/… ), он ничего не делает для сохранения порядок ключей.
Stephen C
1
Я не указывал здесь полное решение, но суть в том, что json-simple предоставляет фабрику, с помощью которой вы можете указать структуру данных, используемую для хранения объектов json. Просто укажите использовать LinkedHashMap.
Hery
@ Хери, у меня такая же проблема, но я не могу ее решить. Я использую , org.jsonчтобы преобразовать , List<LinkedHahMap>чтобы JSONArrayдля того , чтобы создать CSV, то CSVсоздается , но не в том же порядке , как и мои List . Я попытался использовать две библиотеки, которые вы здесь представляете, но мне не удалось найти методы для преобразования в. CSVНе могли бы вы дать более подробную информацию.
Ismail Sen
2

Я знаю, что это решено, и вопрос был задан давно, но поскольку я имею дело с аналогичной проблемой, я хотел бы дать к этому совершенно другой подход:

Для массивов сказано: «Массив - это упорядоченный набор значений». на http://www.json.org/ - но объекты («Объект - это неупорядоченный набор пар имя / значение.») не упорядочены.

Интересно, почему этот объект находится в массиве - это подразумевает порядок, которого там нет.

{
"items":
[
    {
        "WR":"qwe",
        "QU":"asd",
        "QA":"end",
        "WO":"hasd",
        "NO":"qwer"
    },
]
}

Поэтому решением было бы поместить ключи в «настоящий» массив и добавить данные в виде объектов к каждому ключу следующим образом:

{
"items":
[
    {"WR": {"data": "qwe"}},
    {"QU": {"data": "asd"}},
    {"QA": {"data": "end"}},
    {"WO": {"data": "hasd"}},
    {"NO": {"data": "qwer"}}
]
}

Таким образом, это подход, который пытается переосмыслить исходное моделирование и его цель. Но я не тестировал (и мне интересно), сохранят ли все задействованные инструменты порядок этого исходного массива JSON.

cslotty
источник
1
это не позволяет мне искать ключ.
mickeymoon
Тогда что вам нужно - хеш или что-то заказанное !? Если вы хотите объединить и то, и другое, тогда создайте и то, и другое, и пусть одна из этих структур проиндексирует другую ... в противном случае это скорее проблема дизайна или смешение интересов.
cslotty
1
это не о смешении интересов, это довольно правдоподобный вариант использования, который в таких языках, как Java, обрабатывается такими конструкциями, как LinkedHashMap, упорядоченная карта, которая сохраняет порядок вставки. Тогда что мне нужно, я хочу, чтобы оба могли перебирать ключи в определенном порядке, а также выполнять быстрый поиск ключей. Я думаю, что ответ от @Robotic Pants в значительной степени сработает, хотя он немного хакерский.
mickeymoon
Это правда, Микки Мун, я собирался это сказать! Но в JSON этого не существует, не так ли? Тогда вам придется задействовать языки / механизмы, которые действительно предоставляют вам такую ​​возможность.
cslotty
1

В реальном мире приложение почти всегда будет иметь компонент или домен java, которые необходимо сериализовать / десериализовать в / из JSON. Уже упоминалось, что спецификация объекта JSON не гарантирует порядок, и любые манипуляции с этим поведением не оправдывают требования. У меня был тот же сценарий в моем приложении, где мне нужно было сохранить порядок только для удобства чтения. Я использовал стандартный способ Джексона для сериализации моего java-компонента в JSON:

Object object = getObject();  //the source java bean that needs conversion
String jsonString = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(object);

Чтобы создать json с упорядоченным набором элементов, я просто использую аннотацию свойств JSON в Java-компоненте, который я использовал для преобразования. Пример ниже:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"name","phone","city","id"})
public class SampleBean implements Serializable {
    private int id;
    private String name:
    private String city;
    private String phone;

    //...standard getters and setters
}

getObject (), использованный выше:

public SampleBean getObject(){
    SampleBean bean  = new SampleBean();
    bean.setId("100");
    bean.setName("SomeName");
    bean.setCity("SomeCity");
    bean.setPhone("1234567890");
    return bean;
}

Вывод отображается в соответствии с аннотацией порядка свойств Json:

{
    name: "SomeName",
    phone: "1234567890",
    city: "SomeCity",
    id: 100
}
Vishal
источник
0

Самый безопасный способ - это, вероятно, переопределить метод ключей, который используется для генерации вывода:

new JSONObject(){
  @Override
  public Iterator keys(){
    TreeSet<Object> sortedKeys = new TreeSet<Object>();
    Iterator keys = super.keys();
    while(keys.hasNext()){
      sortedKeys.add(keys.next());
    }
    return sortedKeys.iterator();
  }
};
Кардиген
источник
1
Это не решает заявленную проблему. Это приводит к сортировке ключей ... но вопрос требует сохранения порядка вставки.
Stephen C
0

patchFor (ответ @gary):

$ git diff JSONObject.java                                                         
diff --git a/JSONObject.java b/JSONObject.java
index e28c9cd..e12b7a0 100755
--- a/JSONObject.java
+++ b/JSONObject.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
@@ -152,7 +152,9 @@ public class JSONObject {
      * Construct an empty JSONObject.
      */
     public JSONObject() {
-        this.map = new HashMap<String, Object>();
+//      this.map = new HashMap<String, Object>();
+        // I want to keep order of the given data:
+        this.map = new LinkedHashMap<String, Object>();
     }

     /**
@@ -243,7 +245,7 @@ public class JSONObject {
      * @throws JSONException
      */
     public JSONObject(Map<String, Object> map) {
-        this.map = new HashMap<String, Object>();
+        this.map = new LinkedHashMap<String, Object>();
         if (map != null) {
             Iterator<Entry<String, Object>> i = map.entrySet().iterator();
             while (i.hasNext()) {
Кампа
источник
0

Вы можете использовать следующий код, чтобы выполнить заказную сериализацию ORDERED и десериализацию массива JSON (в этом примере предполагается, что вы заказываете строки, но его можно применить ко всем типам):

Сериализация

JSONArray params = new JSONArray();
int paramIndex = 0;

for (String currParam : mParams)
{
    JSONObject paramObject = new JSONObject();
    paramObject.put("index", paramIndex);
    paramObject.put("value", currParam);

    params.put(paramObject);
    ++paramIndex;
}

json.put("orderedArray", params);

Десериализация

JSONArray paramsJsonArray = json.optJSONArray("orderedArray");
if (null != paramsJsonArray)
{
    ArrayList<String> paramsArr = new ArrayList<>();
    for (int i = 0; i < paramsJsonArray.length(); i++)
    {
        JSONObject param = paramsJsonArray.optJSONObject(i);
        if (null != param)
        {
            int paramIndex = param.optInt("index", -1);
            String paramValue = param.optString("value", null);

            if (paramIndex > -1 && null != paramValue)
            {
                paramsArr.add(paramIndex, paramValue);
            }
        }
    }
}
Музикант
источник
0

Ваш пример:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ]
}

добавить элемент "itemorder"

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ],
    "itemorder":["WR","QU","QA","WO","NO"]
}

Этот код генерирует желаемый результат без строки заголовка столбца:

JSONObject output = new JSONObject(json);
JSONArray docs = output.getJSONArray("data");
JSONArray names = output.getJSONArray("itemOrder");
String csv = CDL.toString(names,docs);
Адриано
источник
Это удалило заголовок CSV, теперь я упорядочил строки, но без заголовка
Педро Хоакин
0

вместо использования jsonObject попробуйте использовать CsvSchema по-своему и напрямую преобразует объект в csv

CsvSchema schema = csvMapper.schemaFor(MyClass.class).withHeader();
        csvMapper.writer(schema).writeValueAsString(myClassList);

и он содержит идентификатор заказа, в котором в вашем pojo есть @JsonPropertyOrder

рахул
источник
0

Underscore-java сохраняет заказы для элементов при чтении json. Я сопровождаю проект.

String json = "{\n"
      + "    \"items\":\n"
      + "    [\n"
      + "        {\n"
      + "            \"WR\":\"qwe\",\n"
      + "            \"QU\":\"asd\",\n"
      + "            \"QA\":\"end\",\n"
      + "            \"WO\":\"hasd\",\n"
      + "            \"NO\":\"qwer\"\n"
      + "        }\n"
      + "    ]\n"
      + "}";
System.out.println(U.fromJson(json));

// {items=[{WR=qwe, QU=asd, QA=end, WO=hasd, NO=qwer}]}
Валентин Колесников
источник
-1

Протестировал решение подмигивания и работает нормально:

@Test
public void testJSONObject() {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    System.out.println(jsonObject.toString());
    assertTrue(jsonObject.toString().startsWith("{\"xxx\":"));
}

@Test
public void testWinkJSONObject() throws JSONException {
    org.apache.wink.json4j.JSONObject jsonObject = new OrderedJSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    assertEquals("{\"bbb\":\"xxx\",\"ccc\":\"xxx\",\"aaa\":\"xxx\",\"xxx\":\"xxx\"}", jsonObject.toString());
}
jgpelaez
источник
Зависимость Maven: <dependency> <groupId> org.apache.wink </groupId> <artifactId> wink-json4j </artifactId> <version> 1.4 </version> </dependency>
jgpelaez
Тот же ответ, что и @cypressious ... опубликованный двумя годами ранее. И этот пример не добавляет реальной ценности.
Stephen C