1

I'm hitting a problem in JSON I'm getting back from a Bugzilla server because 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?

2
  • What JSON interface are you using in Bugzilla? I'm the author of the JSON-RPC interface, and I can't imagine any situation in which that would happen. If this is the REST API, that's a different story--that's a separate product maintained separately. Commented Jan 4, 2011 at 8:22
  • It's the REST API that I'm using. Commented Jan 4, 2011 at 13:06

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

If "text" were declared to be type Object, then Gson still chokes on "text":{}, complaining, "Type information is unavailable, and the target object is not a primitive: {}".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.