简体   繁体   中英

Gson: Expected a string but was BEGIN_OBJECT

I am trying to read a simple JSON response:

{
  "response": "ok"
}

Here is my code:

JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
String response = null;
boolean success = false;
reader.beginObject();
if (reader.hasNext()) {
  String token = reader.nextName();
  if (token.equals("response")) {
    response = reader.nextString();
  } else {
    reader.skipValue();
  }
}
reader.endObject();
reader.close();

But I am getting this error:

java.lang.IllegalStateException: Expected STRING but was BEGIN_OBJECT

I don't understand what I am doing wrong.

Your parser is fine. If the code snippet you provided really belongs to the exception stack trace you're getting, then I believe that the response property of the JSON you're trying to parse has a value other than a string. For example,

{ "response": "ok" }

can be parsed by your parser just fine. However, the closest exception message you can get with your parser is a JSON similar to the one below:

{ "response": {"status": "ok"} }

that should fail with something like

Exception in thread "main" java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 16 path $.response

Also note that Gson reports the problematic location at least in its latest versions (I tested it with Gson 2.5). Just make sure you're getting the expected input. If you believe the response must be in the format you mentioned, then just try to trace the input stream and find the differences. Tracing an input stream in its simplest but not the most efficient implementation, and you could have a slightly more efficient tracing reader like this:

private static Reader traceReader(final Reader reader) {
    return new Reader() {
        @Override
        public int read(final char[] buffer, final int offset, final int length)
                throws IOException {
            final int read = reader.read(buffer, offset, length);
            if ( read != -1 ) {
                // or any other appropriate tracing output here
                out.print(new String(buffer, offset, read));
                out.flush();
            }
            return read;
        }

        @Override
        public void close()
                throws IOException {
            reader.close();
        }
    };
}

with:

JsonReader reader = new JsonReader(traceReader(new InputStreamReader(in, "UTF-8")))

Then just re-check if you're really getting { "response": "ok" } .

Just adding this here. In my case, I got this error because I attempted to parse an JSON object directly to an ENUM. GSON was expecting a string directly instead of a JSON object.

In my case I made a mistake modeling the reponse. My error is an object and I modeled it as a String. Taking a closer look at my API response and modeling fixed it

The idea for solving this is something like this example: Your JSON says that dCharg is an object, not a String:

"dCharg":{"TEXT":1000}

If it was supposed to be a String, it would have looked like:

"dCharg":"1000"

Maybe You could design like as follows {code:java}

public class BaseEmployee{/* stuffs */}

public class RegularEmployee extends BaseEmployee{/* stuffs */}

public class Contractors extends BaseEmployee{/* stuffs */} {code}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM