Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON: use deserializing name different than serializing name json

Tags:

java

json

gson

I have one class User, I received JSON (for User class) from system1 and I should read info , validate then forward to system2, I can't touch these 2 systems, the problem is the names of keys are different, I want to differentiate between deserialized and serialized name received JSON is :

{"userId":"user1","pwd":"123456","country":"US"}

"{"username":"user1","password":"123456","country":"US"}"

But the sent should be like this

I am using Gson lib, and this is my code:

User class:

class User implements Cloneable {

    @SerializedName("username")
    private String username ;
    
    @SerializedName("password")
    private String password ;
    
    @SerializedName("country")
    private String country ;

}

TestJson class

class TestJson {

    private static GsonBuilder gsonBuilder;
    private static Gson gson;

    public static Object fromJson(String json, Class clz) {
        gson = new Gson();
        return gson.fromJson(json, clz);
    }

    public static String toJson(Object obj) {
        gsonBuilder = new GsonBuilder();
        gson = gsonBuilder.create();
        String json = gson.toJson(obj);
        return json;
    }
    
    public static void main(String[] args) {
        
        String json2 = "{\"userId\":\"user1\",\"pwd\":\"123456\",\"country\":\"US\"}";
        User user = (User) TestJson.fromJson(json2, User.class); 
        System.out.println(user.getPassword());
        User u = new User("user1","123456","US");
        String json1 = TestJson.toJson(u);
        System.out.println(json1);
        
    }
}
like image 259
Safwan Hijazi Avatar asked Feb 09 '23 15:02

Safwan Hijazi


2 Answers

If there are alternative names of field just use alternate param of @SerializedName

public class User {

   @SerializedName(value="username", alternate={"userId", "useriD"})
   private String username ;
   ...
}
like image 193
ashakirov Avatar answered Feb 12 '23 07:02

ashakirov


You can create custom serializer/deserializer for this purpose.

Serializer:

public class UserSerializer implements JsonSerializer<User> {
    @Override public JsonElement serialize(User obj, Type type, JsonSerializationContext jsonSerializationContext) {
        ..........
    }
}

Deserializer:

public class UserDeserializer implements JsonDeserializer<User> {
    @Override public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        ...........
    }
}

and to create Gson instance:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(User.class, new UserSerializer());
gsonBuilder.registerTypeAdapter(User.class, new UserDeserializer());
Gson gson = gsonBuilder.create();

Example

Edit: this is an example of a custom deserializer which might fit into your need. We don't need a custom serializer in this case.

Add this UserDeserializer.java:

public class UserDeserializer implements JsonDeserializer<User> {
    @Override
    public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject obj = json.getAsJsonObject();
        User user = new User(obj.get("userId").getAsString(), obj.get("pwd").getAsString(), obj.get("country").getAsString());
        return user;
    }
}

Replace your fromJson implementation with this (I use generic to avoid the need for casting when calling fromJson):

public static <T> T fromJson(String json, Class<T> clz) {
    gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(User.class, new UserDeserializer());
    gson = gsonBuilder.create();
    return gson.fromJson(json, clz);
}
like image 35
habsq Avatar answered Feb 12 '23 07:02

habsq