如何为Jackson的@JsonUnwrapped字段重命名实现动态反序列化?
解决方案
方法1:使用@JsonCreator构造器(推荐)
直接给ListOfNumbers添加带@JsonCreator注解的构造器,让Jackson可以直接将JSON数组转换为ListOfNumbers实例,无需额外配置字段注解:
class ListOfNumbers { private List<String> list; // 用@JsonCreator标注接收List的构造器 @JsonCreator public ListOfNumbers(List<String> list) { this.list = list; } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } }
修改后,Person和Company类无需额外注解,就能分别正确反序列化对应的JSON结构:
- 对应
Person的JSON:
{ "name" : "Alex", "favoriteNumbers" : ["42", "9"] }
Jackson会自动将favoriteNumbers数组传入ListOfNumbers构造器,生成实例并赋值给Person.favoriteNumbers。
- 对应
Company的JSON:
{ "companyName" : "MyCompany", "phoneNumbers" : ["42343243", "234235239"] }
同理,phoneNumbers数组会被正确转换为ListOfNumbers实例。
方法2:自定义通用反序列化器
如果无法修改ListOfNumbers的构造器,可以编写通用反序列化器,在引用字段上标注使用:
步骤1:编写反序列化器
public class ListOfNumbersDeserializer extends JsonDeserializer<ListOfNumbers> { @Override public ListOfNumbers deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 将JSON数组解析为List<String> List<String> numbers = p.readValueAs(new TypeReference<List<String>>() {}); ListOfNumbers listOfNumbers = new ListOfNumbers(); listOfNumbers.setList(numbers); return listOfNumbers; } }
步骤2:在引用字段上标注
在Person和Company的对应字段添加@JsonDeserialize注解:
public class Person { private String name; @JsonDeserialize(using = ListOfNumbersDeserializer.class) private ListOfNumbers favoriteNumbers; // getter和setter省略 } public class Company { private String companyName; @JsonDeserialize(using = ListOfNumbersDeserializer.class) private ListOfNumbers phoneNumbers; // getter和setter省略 }
这种方式同样能满足需求,且无需给ListOfNumbers.list添加固定的@JsonProperty注解,保证不同字段可对应JSON中不同键名。
内容的提问来源于stack exchange,提问作者stavang
相关产品推荐
相关产品推荐

