Неверный порядок данных при преобразовании JTable в JSON [duplicate]

Я бы использовал popen () (++ waqas) .

Но иногда вам нужно читать и писать ...

Похоже, никто

(Предположим, что среда Unix / Linux / Mac, или, возможно, Windows с уровнем совместимости POSIX ...)

enum PIPE_FILE_DESCRIPTERS
{
  READ_FD  = 0,
  WRITE_FD = 1
};

enum CONSTANTS
{
  BUFFER_SIZE = 100
};

int
main()
{
  int       parentToChild[2];
  int       childToParent[2];
  pid_t     pid;
  string    dataReadFromChild;
  char      buffer[ BUFFER_SIZE + 1 ];
  ssize_t   readResult;
  int       status;

  ASSERT_IS(0, pipe(parentToChild));
  ASSERT_IS(0, pipe(childToParent));

  switch ( pid = fork() )
  {
    case -1:
      FAIL( "Fork failed" );
      exit(-1);

    case 0: /* Child */
      ASSERT_NOT(-1, dup2( parentToChild[ READ_FD  ], STDIN_FILENO  ) );
      ASSERT_NOT(-1, dup2( childToParent[ WRITE_FD ], STDOUT_FILENO ) );
      ASSERT_NOT(-1, dup2( childToParent[ WRITE_FD ], STDERR_FILENO ) );
      ASSERT_IS(  0, close( parentToChild [ WRITE_FD ] ) );
      ASSERT_IS(  0, close( childToParent [ READ_FD  ] ) );

          /*   file,  arg0,  arg1,   arg2 */
      execlp(  "ls",  "ls",  "-al",  "--color" );

      FAIL( "This line should never be reached!!!" );
      exit(-1);


    default: /* Parent */
      cout << "Child " << pid << " process running..." << endl;

      ASSERT_IS(  0, close( parentToChild [ READ_FD  ] ) );
      ASSERT_IS(  0, close( childToParent [ WRITE_FD ] ) );

      while ( true )
      {
        switch ( readResult = read( childToParent[ READ_FD ],
                                    buffer, BUFFER_SIZE ) )
        {
          case 0: /* End-of-File, or non-blocking read. */
            cout << "End of file reached..."         << endl
                 << "Data received was ("
                 << dataReadFromChild.size() << "):" << endl
                 << dataReadFromChild                << endl;

            ASSERT_IS( pid, waitpid( pid, & status, 0 ) );

            cout << endl
                 << "Child exit staus is:  " << WEXITSTATUS(status) << endl
                 << endl;

            exit(0);


          case -1:
            if ( (errno == EINTR) || (errno == EAGAIN) )
            {
              errno = 0;
              break;
            }
            else
            {
              FAIL( "read() failed" );
              exit(-1);
            }

          default:
            dataReadFromChild . append( buffer, readResult );
            break;
        }
      } /* while ( true ) */
  } /* switch ( pid = fork() )*/
}

Вы также можете играть с помощью select () и неблокирующих чтений.

fd_set          readfds;
struct timeval  timeout;

timeout.tv_sec  = 0;    /* seconds */
timeout.tv_usec = 1000; /* microseconds */

FD_ZERO(&readfds);
FD_SET( childToParent[ READ_FD ], &readfds );

switch ( select ( 1 + childToParent[READ_FD], &readfds, (fd_set*)NULL, (fd_set*)NULL, & timeout ) )
{
  case 0: /* Timeout expired */
    break;

  case -1:
    if ( (errno == EINTR) || (errno == EAGAIN) )
    {
      errno = 0;
      break;
    }
    else
    {
      FAIL( "Select() Failed" );
      exit(-1);
    }

  case 1:  /* We have input */
    readResult = read( childToParent[ READ_FD ], buffer, BUFFER_SIZE );
    // However you want to handle it...
    break;

  default:
    FAIL( "How did we see input on more than one file descriptor?" );
    exit(-1);
}
44
задан wchargin 9 May 2013 в 04:35
поделиться

11 ответов

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

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

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

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

82
ответ дан Adrian Smith 19 August 2018 в 08:19
поделиться
  • 1
    Как следствие, библиотеки JSON могут изменять порядок элементов по своему усмотрению. Это не ошибка. Любопытно знать, какая польза в переустановке элементов. Спасибо, дурай. – durai 11 July 2012 в 13:57
  • 2
    @durai: некоторые ассоциативные контейнеры используют функцию сортировки для упорядочивания своих элементов и, таким образом, не сохраняют порядок, чтобы обеспечить быстрый поиск элементов. – ereOn 29 October 2012 в 20:27
  • 3
    Ну, они заявляют следующее здесь (если это действительно gson). google-gson.googlecode.com/svn/tags/1.2.3/docs/javadocs/com/… & quot; Элементы-члены этого объекта поддерживаются в порядке их добавления. & quot; – Ted 5 August 2014 в 15:47
  • 4
    @Ted это GSON, библиотека Java , разработанная Google для обработки JSON. Это зависит от каждого разработчика библиотеки, если они хотят изменить порядок в поле или нет. – Andrew T. 20 October 2015 в 08:12
  • 5
    @Thomas Это о объекте JSON, а не JSON Array – Daniel Higueras 1 February 2016 в 12:29

Как все говорят вам, JSON не поддерживает «последовательность», но массив делает, может быть, это может вас убедить: Упорядоченный JSONObject

0
ответ дан Community 19 August 2018 в 08:19
поделиться

Загрузите «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 string

для получения дополнительной информации нажмите здесь http://androiddhina.blogspot.in/2015/09/ordered-json-string-in-android.html

2
ответ дан Dhina k 19 August 2018 в 08:19
поделиться
  • 1
    Ву человек. Наконец, это единственное решение. Огромное спасибо. – Sayka 19 March 2016 в 22:33
  • 2
    Это потрясающе. Большое спасибо,. – coolgokul 26 February 2017 в 03:13

Основная цель здесь - отправить упорядоченный объект JSON в качестве ответа. Для этого нам не нужен javax.json.JsonObject. Мы могли бы создать упорядоченный json как строку. Сначала создайте LinkedHashMap со всеми парами значений ключей в требуемом порядке. Затем сгенерируйте json в строке, как показано ниже. Это намного проще с Java 8.

public Response getJSONResponse() {
    Map<String, String> linkedHashMap = new LinkedHashMap<>();
    linkedHashMap.put("A", "1");
    linkedHashMap.put("B", "2");
    linkedHashMap.put("C", "3");

    String jsonStr = linkedHashMap.entrySet().stream()
            .map(x -> "\"" + x.getKey() + "\":\"" + x.getValue() + "\"")
            .collect(Collectors.joining(",", "{", "}"));
    return Response.ok(jsonStr).build();
}

Ответ возврата этой функцией будет следующим: {"A":"1","B":"2","C":"3"}

1
ответ дан Joy Banerjee 19 August 2018 в 08:19
поделиться

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

11
ответ дан lemiorhan 19 August 2018 в 08:19
поделиться
  • 1
    Это решение для меня не работает. Преобразование в JSONObject вызывает исключение. Если я создам JSONObject (map), то порядок не сохраняется. Если я оставлю назначение без преобразования, тогда вместо объекта будет назначаться строка. – Ernest 25 December 2014 в 10:00
  • 2
    Это сработало для меня, но мне пришлось использовать JSONObject.toJSONString(obj). В противном случае я получил ошибку преобразования как @Ernest, упомянутую выше. – Tricky12 22 July 2015 в 17:44
  • 3
    @ Tricky12 Это не имеет для меня никакого смысла: 1.) org.json.JSONObject не имеет этого метода. 2.) Метод, который, кажется, может сделать трюк org.json.JSONObject.valueToString(obj), НЕ работает, поскольку он делает это внутри: new JSONObject(map).toString(), который снова использует HashMap, а не LinkedHashMap внутри: this.map = new HashMap<String, Object>(); – Frederic Leitenberger 27 October 2017 в 10:13
  • 4
    @lemiorhan: Что (язык) это? Он немного похож на Java, но он не будет работать в Java по нескольким причинам. Помимо очевидных синтаксических ошибок, таких как отсутствие «;», ключевое слово «def» не существует в Java и, наконец: JSONObject json = (JSONObject) obj → A HashMap нельзя передать в JSONObjectClassCastException. И еще одно: ссылка в конце вашего сообщения приводит к рекламной странице (неработающая ссылка?). – Frederic Leitenberger 27 October 2017 в 11:44
  • 5
    @FredericLeitenberger toJSONString() - это метод, если у вас есть библиотека org.json.simple. Это было доступно мне в моей среде IDE. Я не смотрел на это уже пару лет, поэтому я не знаю, как еще помочь. – Tricky12 27 October 2017 в 19:26

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

2
ответ дан Mark Snidovich 19 August 2018 в 08:19
поделиться

Для 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: {// атрибуты упорядочиваются так же, как и порядок настройки получателя.}}

0
ответ дан prachi 19 August 2018 в 08:19
поделиться

из примера 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
ответ дан sang 19 August 2018 в 08:19
поделиться
  • 1
    Было бы здорово, если бы JSONObject мог быть сконструирован, если его поддерживал LinkedHashMap. Где должно / должно было быть опубликовано такое улучшение? – Frederic Leitenberger 27 October 2017 в 11:40

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 & lt;>

CHEERS !!!

1
ответ дан thyzz 19 August 2018 в 08:19
поделиться

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

0
ответ дан tsohr 19 August 2018 в 08:19
поделиться

Реальный ответ можно найти в спецификации, 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;
    }
}
3
ответ дан UnixShadow 19 August 2018 в 08:19
поделиться
  • 1
    Хорошее решение ~ hack ~. В моей версии JSONObject поле map является окончательным, но, похоже, оно работает. Если это не сработает, это дополнение должно помочь преодолеть final: stackoverflow.com/a/3301720/1520422 – Frederic Leitenberger 27 October 2017 в 12:03
Другие вопросы по тегам:

Похожие вопросы: