Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialize list of objects with inner list with Jackson

Tags:

java

json

jackson

I have such an entity:

public class User {

    private Long id;
    private String email;
    private String password;
    private List<Role> roles;

    //set of constructors, getters, setters...

and related JSON:

[
  {
    "email": "user@email",
    "roles": ["REGISTERED_USER"]
  }
]

I'm trying to deserialize it in Spring MVC @Controller in such way:

List<User> users = Arrays.asList(objectMapper.readValue(multipartFile.getBytes(), User[].class));

Before adding List<Role> it worked perfect, but after I still have no luck. It seems I need some custom deserializer, could you help with approach for solving? Thank you!

like image 852
Dmitry Adonin Avatar asked Oct 17 '25 03:10

Dmitry Adonin


1 Answers

If you have access to Role class you can just add such constructor:

private Role(String role) {
   this.role = role;
}

or static factory methods:

@JsonCreator
public static Role fromJson(String value){
    Role role = new Role();
    role.setRole(value);
    return role;
}

@JsonValue
public String toJson() {
    return role;
}

Otherwise you will have to write custom deserealizer and register it on object mapper like this:

public static class RoleSerializer extends JsonSerializer {
    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeString(((Role) value).getRole());
    }
}

public static class RoleDeserializer extends JsonDeserializer {
    @Override
    public Role deserialize(JsonParser jsonParser,DeserializationContext deserializationContext) throws IOException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        Role role =  new Role();
        role.setRole(node.asText());
        return role;
    }
}

Here is demo: https://gist.github.com/varren/84ce830d07932b6a9c18

FROM: [{"email": "user@email","roles": ["REGISTERED_USER"]}]

TO OBJ: [User{id=null, email='user@email', password='null', roles=Role{role='REGISTERED_USER'}}]

TO JSON:[{"email":"user@email","roles":["REGISTERED_USER"]}]

Ps: If you use ObjectMapper like this

Arrays.asList(objectMapper.readValue(multipartFile.getBytes(), User[].class));

then code from demo will work, but you will probably have to set custom Bean in Spring for jackson ObjectMapper to make RoleDeserializer and RoleSerializer work everywhere. Here is more info: Spring, Jackson and Customization (e.g. CustomDeserializer)

like image 180
varren Avatar answered Oct 18 '25 19:10

varren