6

I'm parsing a JSON string by using Gson and Retrofit. I have this JSON string:

{"message":["Email has already been taken"]}

I get the below exception still and don't know why:

java.io.EOFException: End of input at line 1 column 1 path $
    at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1393)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:549)
    at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:205)
    at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:260)
    at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:273)

People who know how to get the value of message field please help me.

BaseApiDto.java

public class BaseApiDto {

    @SerializedName("message")
    public String[] message;

    public String getError() {
        return message[0];
    }

}

HandErrorUtils.java

public static void handleError(FragmentActivity activity, Throwable e) {
    String msg = null;
    if(e instanceof HttpException){
        // Error message in json
        Gson gson = new Gson();
        TypeAdapter<BaseApiDto> adapter = gson.getAdapter(BaseApiDto.class);
        ResponseBody body = ((HttpException) e).response().errorBody();

        // Status code
        HttpException httpException = (HttpException) e;
        int statusCode = httpException.code();

        if (statusCode == 500) {
            showErrorDialog(activity, activity.getString(R.string.dialog_msg_error_401), true);
        } else if (statusCode == 401) {
            showErrorDialog(activity, activity.getString(R.string.dialog_msg_error_401), true);
        } else {
            try {
                Timber.w("body.string() " + body.string());

                // TODO : EXCEPTION HAPPEN IN HERE
                BaseApiDto errorDto = adapter.fromJson(body.string());

                msg = errorDto.getError();

                Timber.w("msg " + msg);
            } catch (Exception ex) {
                // TODO : EXCEPTION HAPPEN IN HERE
                ex.printStackTrace();
            }

            showErrorDialog(activity, msg, false);
        }

    }
}

UPDATE I assign body.toString() to variable, somehow it worked.

String response = body.string();

BaseApiDto errorDto = adapter.fromJson(response);
Huy Tower
  • 7,769
  • 16
  • 61
  • 86
  • 1
    Your body string representation is empty. – Lyubomyr Shaydariv Apr 18 '17 at 09:39
  • Try chaning your JSON to `{"message":"Email has already been taken"}` remove the `[]` braces they indicate an array in JSON. And your `String message` should not be an array of strings. – Yantes Apr 18 '17 at 09:39
  • @TheLearner : No, My case need array list. – Huy Tower Apr 18 '17 at 10:51
  • @LyubomyrShaydariv : It is not empty, `W: body.string() {"message":["Email has already been taken"]}` – Huy Tower Apr 18 '17 at 10:57
  • 1
    @HuyTower I bet it is. I don't know how `body.string()` works and where it comes from at all, but it seems that `body.string()` tries to read the "remaining" stream, thus the second call, I suspect, can make a subsequent read. Introduce a variable, assign `body.string()` result to it, and then use it twice, or more times if necessary. – Lyubomyr Shaydariv Apr 18 '17 at 11:02
  • @LyubomyrShaydariv : somehow it worked by define follow your way. Assign it to variable, now it worked. :( – Huy Tower Apr 19 '17 at 03:20
  • 2
    @HuyTower Why "somehow"? Resource streams are disposable by definition. `string()` works via `readString()`, so you cannot read twice. – Lyubomyr Shaydariv Apr 19 '17 at 06:12

1 Answers1

1

It worked because I didn't call body.string() twice.

I assign body.toString() to variable, somehow it worked.

String response = body.string();

BaseApiDto errorDto = adapter.fromJson(response);
Huy Tower
  • 7,769
  • 16
  • 61
  • 86