GSON: MalformedJsonException при запуске файла jar (отлично работает в Eclipse)

Это мой первый пост здесь, надеюсь, кто-то может мне помочь, потому что я не могу понять, что не так.

У меня есть java-метод, который анализирует строку JSON

    public static String getFieldFrom(String field, String event) {
    try {
        JsonElement jelement = new JsonParser().parse(event);
        JsonObject  obj = jelement.getAsJsonObject();
        return obj.getAsJsonObject("from").get(field).getAsString();            
    }catch(Exception e) {
        System.out.println("Error parsing field " + field + ": " + e);
    }       
    return "-1";
}

Где событие - это строка, а поле - это поле, которое меня интересует. Программа отлично работает при запуске на eclipse. Если я скомпилирую его как банку и попытаюсь запустить, я получу исключение:

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 3 path $

Обрабатываемая строка JSON такая же, вот эта (мне кажется):

{"event": "message", "id": "00000000b0a2a54e1a01000000000000d", "flags": 258, "fwd_from": {"id": "$01000000428d8006442ef91f3ed48e27", "peer_type": "user", "peer_id": 109088066, "print_name": "Sample_Name", "flags": 1, "first_name": "Name", "last_name": "Sample", "username": "sampleuser"}, "fwd_date": 1522850949, "from": {"id": "$050023200b0a234e82865474b11fd9cd", "peer_type": "channel", "peer_id": 123232323, "print_name": "ChnNameTest", "flags": 19609, "title": "ChnNameTest", "participants_count": 0, "admins_count": 0, "kicked_count": 0}, "to": {"id": "$011200000b0a2a54e812345674b47fd9cd", "peer_type": "channel", "peer_id": 1319412121236, "print_name": "ChnNameTest", "flags": 196609, "title": "ChnNameTest", "participants_count": 0, "admins_count": 0, "kicked_count": 0}, "out": true, "unread": false, "service": false, "date": 1522850949, "text": "This is the message text"}

Я пытаюсь получить поле "id" под объектом "from". Я также пробовал с другой библиотекой (org.json), но поведение такое же. Опять же, если я запустил код в eclipse, он заработает. Я действительно не знаю, что попробовать ... Надеюсь, кто-нибудь сможет мне помочь! Спасибо!

Обновлено: Проблема, похоже, связана с переданной строкой. Итак, это фрагмент кода, который считывает стандартный вывод сценария, который я вызываю (который отправляет обратно текст json).

    Process child = Runtime.getRuntime().exec(command);
    InputStream in = child.getInputStream();
    int c;
    char ca;
    String line = "";
    while ((c = in.read()) != -1) { //Read stdout char by char
          ca=(char)c;
          if (ca=='\n' || ca=='\r') { //Got a line
            if (line.contains("{\"event\":")) {  
                System.out.println(getFieldFrom("id",line)));
            }                   
            line = "";
          }else {
            line=line+ca;
          }
      }
      in.close();

Вы уверены, что на самом деле получаете тот же предполагаемый файл JSON при запуске своей банки (из того, что я считаю командной строкой)?

Mena 04.04.2018 17:28

Да. Строка JSON, которую вы видите, была напечатана в предложении catch

Mirco Ianese 04.04.2018 17:29

Я больше не знаком с GSON, но, возможно, проблема в этом символе $ ... Не знаю, как настройки смягчения JsonReader могут отличаться при запуске из вашей IDE и командной строки, но это может быть ключом для вас чтобы отладить это.

Mena 04.04.2018 17:32

Спасибо за ответ @Mena К сожалению, не повезло. Удаление $ не помогло

Mirco Ianese 04.04.2018 17:36

Без проблем. Надеюсь, кто-нибудь еще лучше поймет.

Mena 04.04.2018 17:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
789
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это работает для меня.

        String json = "{\"event\": \"message\", \"id\": \"00000000b0a2a54e1a01000000000000d\", \"flags\": 258, \"fwd_from\": {\"id\": \"$01000000428d8006442ef91f3ed48e27\", \"peer_type\": \"user\", \"peer_id\": 109088066, \"print_name\": \"Sample_Name\", \"flags\": 1, \"first_name\": \"Name\", \"last_name\": \"Sample\", \"username\": \"sampleuser\"}, \"fwd_date\": 1522850949, \"from\": {\"id\": \"$050023200b0a234e82865474b11fd9cd\", \"peer_type\": \"channel\", \"peer_id\": 123232323, \"print_name\": \"ChnNameTest\", \"flags\": 19609, \"title\": \"ChnNameTest\", \"participants_count\": 0, \"admins_count\": 0, \"kicked_count\": 0}, \"to\": {\"id\": \"$011200000b0a2a54e812345674b47fd9cd\", \"peer_type\": \"channel\", \"peer_id\": 1319412121236, \"print_name\": \"ChnNameTest\", \"flags\": 196609, \"title\": \"ChnNameTest\", \"participants_count\": 0, \"admins_count\": 0, \"kicked_count\": 0}, \"out\": true, \"unread\": false, \"service\": false, \"date\": 1522850949, \"text\": \"This is the message text\"}";
    Gson gson = new Gson();
    JsonObject obj = gson.fromJson(json, JsonElement.class).getAsJsonObject();
    String str = obj.getAsJsonObject("from").get("id").getAsString();
    System.out.println(str);

Выход:

$050023200b0a234e82865474b11fd9cd

Спасибо. Если я укажу JSON как String внутри кода, у меня тоже будет работать. Если я получу строку из stdout, этого не произойдет. Я скопировал обе струны, и они выглядят одинаково. Может где-то есть невидимый гольц?

Mirco Ianese 04.04.2018 18:19

Можете ли вы проверить это - Gson gson = new GsonBuilder().setLenient().create();

Nephilim 04.04.2018 19:28
Error parsing field id: com.google.gson.JsonIOException: JSON document was not fully consumed. com.google.gson.JsonIOException: JSON document was not fully consumed. at com.google.gson.Gson.assertFullConsumption(Gson.java:861) at com.google.gson.Gson.fromJson(Gson.java:854) at com.google.gson.Gson.fromJson(Gson.java:802) at com.google.gson.Gson.fromJson(Gson.java:774) at base.CliServer.getFieldFrom(CliServer.java:123) at base.CliServer.messageListener(CliServer.java:41) at base.Main.main(Main.java:6) Он все еще не может проанализировать строку JSON
Mirco Ianese 04.04.2018 21:08

И последнее, можете ли вы попробовать сделать следующее - event=event.trim(); JsonObject obj = gson.fromJson(event, JsonElement.class).getAsJsonObject();

Nephilim 04.04.2018 21:47

Это решило проблему! event.trim показывает скрытый символ в начале строки. Удаление этого символа делает JSON действительным. Спасибо

Mirco Ianese 05.04.2018 10:58

Спасибо, @Nephilim!

Решил это, выполнив:

event=event.trim();
event=event.replace("[K","");

После event.trim(); строка имеет в начале «[K», которого раньше не было видно. После удаления этого "[K" все работает! Вероятно, это был какой-то скрытый уголь, который «расширял» отделку.

Другие вопросы по теме