Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent GSON from serializing JSON string

I'm new to gson, and have newby question which I have not found an answer to, so please bear with me. StackOverflow and google were not my friend :(

I have a java class "User", and one of its properties, "externalProfile" is a Java String containing already serialized JSON. When gson serializes the User object, it will treat externalProfile as primitive and thus escaping the JSON adding extra slashes etc. I want gson to leave the string alone, just using it "as is", because it is already valid and usable JSON.

To distinguish the JSON string, I created a simple class called JSONString, and I've tried using reader/writers, registerTypeAdapter, but nothing works. Can you help me out?

public class User {
    private JSONString externalProfile;
    public void setExternalProfile(JSONString externalProfile) { this.externalProfile = externalProfile; }

}

public final class JSONString {
    private String simpleString;
    public JSONString(String simpleString) { this.simpleString = simpleString; }
}

public customJsonBuilder(Object object) {
    GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(GregorianCalendar.class, new JsonSerializer<GregorianCalendar>() {
            public JsonElement serialize(GregorianCalendar src, Type type, JsonSerializationContext context) {
                if (src == null) {
                    return null;
                }
                return new JsonPrimitive(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(src.getTime()));
            }
        });
        Gson gson = builder.create();
        return gson.toJson(object);
}

As en example, the externalProfile will hold (as String value):

{"profile":{"registrationNumber": 11111}}

After I store it as JSONString in the User object, and we convert the user object to JSON:

User user = new User();
user.setExternalProfile(new JSONString(externalProfile)),  
String json = customJsonBuilder(user);

json will hold something like:

{\"profile\":{\"registrationNumber\": 11111}}

So, the externalProfile JSONString is serialized by gson as String primitive, adding the extra slashes in front of the doublequotes. I want gson to leave this JSONString as is, because it already is usable JSON. I'm looking for a type adapter / reader-writer to do this, but I can't get it to work.

like image 910
TheXL Avatar asked Jun 13 '15 07:06

TheXL


People also ask

How can you prevent Gson from expressing integers as floats?

One option is to define a custom JsonDeserializer, however better would be to not use a HashMap (and definitely don't use Hashtable!) and instead give Gson more information about the type of data it's expecting. Show activity on this post. Show activity on this post. Show activity on this post.

Does Gson ignore extra fields?

3. Deserialize JSON With Extra Unknown Fields to Object. As you can see, Gson will ignore the unknown fields and simply match the fields that it's able to.

How do I ignore fields in JSON response Gson?

GSON provide two ways to exclude fields from JSON by GsonBuilder: @Expose Annotation. Custom Annotation.

Does Gson ignore transient fields?

Gson serializer will ignore every field declared as transient: String jsonString = new Gson().


2 Answers

As stated by Alexis C:

store the externalProfile as a JsonObject first:

new Gson().fromJson(externalProfile, JsonObject.class));

And let gson serialize this again when outputting the User object. Will produce exactly the same JSON!

like image 185
TheXL Avatar answered Nov 04 '22 09:11

TheXL


I solved it without the unnecessary deserialisation-serialization. Create class:

public class RawJsonGsonAdapter extends TypeAdapter<String> {

    @Override
    public void write(final JsonWriter out, final String value) throws IOException {
        out.jsonValue(value);
    }

    @Override
    public String read(final JsonReader in) throws IOException {
        return null; // Not supported
    }
}

And use it by annotation where needed. For example:

public class MyPojo {
    @JsonAdapter(RawJsonGsonAdapter.class)
    public String someJsonInAString;

    public String normalString;
}

That's it. Use Gson as normal.

like image 21
Daniel Avatar answered Nov 04 '22 08:11

Daniel