I'm hitting a problem in JSON I'm getting back from a Bugzilla server b开发者_JS百科ecause it sometimes returns "text" : {} and sometimes "text" : "blah blah blah". Bugzilla returns the former if no description was given for a bug. I'm mystified why it doesn't come back as the much more sensible "text" : "" but it does and that's it.
If I have a String named text in the target object for Gson, it objects when it sees the {} case because it says that's an object and not a String:
Exception in thread "main" com.google.gson.JsonParseException: The
JsonDeserializer StringTypeAdapter failed to deserialized json object {} given
the type class java.lang.String
Any suggestions on how I can make Gson parse this?
Gson requires custom deserialization for the situation in the original question. Following is one such example.
input.json:
[
{
"text":"some text"
},
{
"text":{}
}
]
Foo.java:
import java.io.FileReader;
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
public class Foo
{
public static void main(String[] args) throws Exception
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(String.class, new StringDeserializer());
Gson gson = gsonBuilder.create();
Thing[] things = gson.fromJson(new FileReader("input.json"), Thing[].class);
System.out.println(gson.toJson(things));
}
}
class Thing
{
String text;
}
class StringDeserializer implements JsonDeserializer<String>
{
@Override
public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
if (json.isJsonPrimitive()) return json.getAsString();
return "";
}
}
Output:
[{"text":"some text"},{"text":""}]
Using instead a custom deserializer for the Thing.class
type would of course be possible. This would have the benefit of not adding additional processing for every String
, but then you'd be stuck with "manual" processing all of the other attributes of Thing
.
Try declaring the text
field to be an Object
. Then do something like:
public String getTextAsString() {
if (text instanceof String) {
return (String) text;
else {
return null;
}
}
You should report this as a bug to the Bugzilla project. There's no good reason for this behavior.
精彩评论