Разбор строки Json с помощью Gson дает мне ошибку - PullRequest
0 голосов
/ 18 октября 2019

Не могу понять, почему я получаю

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $

Я, наверное, перебрал более 15 страниц stackoverflow и перепробовал кучу решений за целый день.

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

@Override public void onMessage(WebSocket webSocket, String text) {

    Log.d(TAG, "onMessage: Recieved: " + text);

}

возвращает строку:

{ 
   "camera_id":"e9502c54-927c-4639-a94f-8d03149c9c62",
   "posted_by":"14b07da5-1820-40db-8508 cc81261458aa",
   "posted_by_user":"david23",
   "message":"hello world"
}

Я успешно получаюкаждый элемент, используя мой класс модели

public class Message {

    private String camera_id;
    private String posted_by;
    private String posted_by_user;
    private String message;

    public String getMessage() {
        return message;
    }

    ... rest of methods
}

И внутри моего слушателя onMessage ...

try{
    Gson gson = new Gson();
    Message message = gson.fromJson(text, Message.class);
    Log.d(TAG, "onMessage: " + message.getMessage());
}catch (Exception e){
    Log.d(TAG, "onMessage: Error: " + e);
}

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

Exception: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 
Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $

Некоторые решения говорят мне, чтобы подтвердить, что json, отправленный с сервера, является строкой. Я дважды, трижды, бесчисленное количество раз проверял, что это строка. Даже убедился, используя .. String.valueOf (текст)

Может ли кто-нибудь помочь мне определить причину ошибки?

Edit1: ________________________________________________

Используя метод Roaim, чтобы проверить, содержит ли моя возвращаемая строка {}, он говорит, что нет, но мои журналы говорят мне, что это так. Как это может быть?

enter image description here

onMessage: Recieved: {"camera_id":"e9502c54-927c-4639-a94f-8d03149c9c62","posted_by":"14b07da5-1820-40db-8508-cc81261458aa","posted_by_user":"david23","message":"hello world"}

onMessage: hello world

Error: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String evan.com.websocketchatapplication.Message.getMessage()' on a null object reference

Ответы [ 3 ]

1 голос
/ 18 октября 2019

Исключение: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: ожидалось BEGIN_OBJECT, но было STRING в строке 1, путь 1 столбца $

Это исключение указывает, что GSON быложидая, что строка будет начинаться с {, но у нее есть что-то еще.

Если вы можете гарантировать, что строка начинается с {, то вышеприведенное исключение исчезнет. Позвольте мне показать вам, как вы можете убедиться, что

public Message jsonToMessage(String json) {
    if (!json.contains("{") || !json.contains("}")) return null;

    String text = json.substring(json.indexOf("{"));
    JsonReader reader = new JsonReader(new StringReader(text));
    reader.setLenient(true);

    Gson gson = new Gson();
    return gson.fromJson(reader, Message.class);
}

Ответ на Edit1:

Из наблюдения журнала, выглядитonMessage() метод вызывается дважды с одним допустимым JSON и одним недопустимым текстом, т.е. Message Processed in Lambda!. Если я не ошибаюсь, тогда просто игнорирование объекта null Message подойдет. Кстати, вы можете проверить текст, для которого мой метод возвращает значение null, чтобы выяснить проблему,

public Message jsonToMessage(String json) {
    if (!json.contains("{") || !json.contains("}")) {
        Log.d(TAG, "onMessage: jsonToMessage: " + json);
        return null;
    }

    ...
}
0 голосов
/ 18 октября 2019

В вашем классе сообщений замените -

    private String camera_id;
    private String posted_by;
    private String posted_by_user;
    private String message;

на -

    @SerializedName("camera_id")
    @Expose
    private String cameraId;
    @SerializedName("posted_by")
    @Expose
    private String postedBy;
    @SerializedName("posted_by_user")
    @Expose
    private String postedByUser;
    @SerializedName("message")
    @Expose
    private String message;

   /**
     * No args constructor for use in serialization
     *
     */
    public Message() {
    }
0 голосов
/ 18 октября 2019

Попробуйте запустить ваш API на почтальоне, он покажет фактический ответ, который вы получили от сервера в разделе «Предварительный просмотр».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...