Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson: deserialize array of Strings to List<T>

For a JSON object, Subject:

{ 
    "permissions":["foo", "bar"],
    ...
}

... I would like to deserialize to:

class Subject {
    private List<Permission> permissions;
    ...

... where Permission is:

class Permission {
    ....
    public Permission(String permission) {
    ....
    }

Permission is not a class I control, so I only have the constructor to deal with.

I'm certain Jackson can do this but I'm just not convinced I have found the best way yet. My efforts with ArrayDeserializer and @JsonDeserialize(contentAs = Permission.class) have failed and before I start subclassing a JsonDeserializer I want to verify that no built in functionality can do this.

like image 610
markdsievers Avatar asked Dec 11 '13 10:12

markdsievers


2 Answers

Ended up writing my own Deserializer.

public class PermissionDeserializer extends JsonDeserializer<List<Permission>> {

    @Override
    public List<Permission> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        if (jsonParser.getCurrentToken() == JsonToken.START_ARRAY) {
            List<Permission> permissions = new ArrayList<>();
            while(jsonParser.nextToken() != JsonToken.END_ARRAY) {
                permissions.add(new Permission(jsonParser.getValueAsString()));
            }
            return permissions;
        }
        throw deserializationContext.mappingException("Expected Permissions list");
    }
}
like image 58
markdsievers Avatar answered Nov 09 '22 07:11

markdsievers


Here is an example to guide you.

Subject.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class Subject {

    public static void main(String[] args) throws Exception, JsonMappingException, IOException {
        String json = "{\"permissions\":[\"foo\", \"bar\"]}";
        ObjectMapper mapper = new ObjectMapper();
        Subject subject = mapper.readValue(json, Subject.class);

        for(Permission p:subject.getPermissions()){
            System.out.println(p.getPermission());
        }
    }

    private List<Permission> permissions = new ArrayList<Permission>();

    public List<Permission> getPermissions() {
        return permissions;
    }


    public void setPermissions(List<Permission> permissions) {
        this.permissions = permissions;
    }
}

Permission.java

class Permission {
    private String permission;

    public Permission(String permission) {
        this.permission = permission;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }
}
like image 43
Kevin Bowersox Avatar answered Nov 09 '22 06:11

Kevin Bowersox