杰克逊 - 如何将字符串数组解析为对象集合

时间:2016-05-15 17:10:43

标签: java json jackson

我试图将一些数据发布到我的REST控制器。我的JSON外观的麻烦部分就像:

{
    "externalLinks": ["link1", "link2"],
    "lectureRequirements": ["requirement1", "requirement2"]
}

我需要将它解析为两个模型集合:

public class Lecture {

    // other fields...

    private List<LectureExternalLink> lectureExternalLinks;

    private List<LectureRequirement> lectureRequirements;
}

两个类--LectureExternalLink和LectureRequirement只有两个field-id和string参数。我想将传入的字符串数组解析为模型集合,其中字符串转到模型类中的相应字段。有没有办法用杰克逊注释做到这一点?

1 个答案:

答案 0 :(得分:1)

我认为没有神奇的注释可以做到这一点。如果向POJOs添加单字符串构造函数/工厂方法,LectureExternalLinkLectureRequirement可以反序列化为字符串

// OPTION 1 with constructor
private static class POJO{
    private String name;

    public POJO(String name) {
        this.name = name;
    }
}

// OPTION 2 with factory method
private static class POJO{
    private String name;

    @JsonCreator
    public static POJO POJO(String name) {
        POJOlink = new POJO();
        link.name = name;
        return link;
    }
}

您还可以使用@JsonValue上方的getName()将其序列化回{"externalLinks":["link1","link2"],"lectureRequirements":["requirement1","requirement2"]}

如果由于某种原因你不能改变你的POJO,我认为你唯一的方法是创建像这样的自定义反序列化器:

private static class MyJsonDeserializer extends JsonDeserializer<LectureExternalLink> {
    @Override
    public LectureExternalLink deserialize(JsonParser p, DeserializationContext ctxt) 
                                                           throws IOException {
        String value = p.getValueAsString();
        LectureExternalLink val= new LectureExternalLink();
        val.setName(value);
        return val;
    }
}

完整演示:

private static final String json ="{\n" +
        "    \"externalLinks\": [\"link1\", \"link2\"],\n" +
        "    \"lectureRequirements\": [\"requirement1\", \"requirement2\"]\n" +
        "}";

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    Lecture l = mapper.readValue(json,Lecture.class);
    System.out.println(mapper.writeValueAsString(l));

}

public static class Lecture {
    @JsonProperty("externalLinks")
    private List<LectureExternalLink> lectureExternalLinks;

    @JsonProperty("lectureRequirements")
    private List<LectureRequirement> lectureRequirements;

    public List<LectureExternalLink> getLectureExternalLinks() {
        return lectureExternalLinks;
    }

    public void setLectureExternalLinks(List<LectureExternalLink> lectureExternalLinks) {
        this.lectureExternalLinks = lectureExternalLinks;
    }

    public List<LectureRequirement> getLectureRequirements() {
        return lectureRequirements;
    }

    public void setLectureRequirements(List<LectureRequirement> lectureRequirements) {
        this.lectureRequirements = lectureRequirements;
    }
}

@JsonFormat(shape = JsonFormat.Shape.STRING)
private static class LectureRequirement {
    private String name;

    private Integer id;

    public LectureRequirement(String name) {
        this.name = name;
    }
    @JsonValue
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

}


@JsonDeserialize(using = MyJsonDeserializer.class)
public static class LectureExternalLink {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @JsonValue
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

private static class MyJsonDeserializer extends JsonDeserializer<LectureExternalLink> {

    @Override
    public LectureExternalLink deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = p.getValueAsString();
        LectureExternalLink val= new LectureExternalLink();
        val.setName(value);
        return val;
    }
}