如何使用Jackson ObjectMapper将相同的@JsonAlias映射到不同的对象字段 &



在我的DTO类中,可能有可能具有相同的@JsonAlias值的字段,但这似乎不适用于Jackson ObjectMapper。

似乎ObjectMapper只适用于@JsonAlias的第一次出现,它不工作的其余@JsonAlias具有相同的值。我尝试在下面为引用创建一个示例,在该示例中,Person类有两个名称为@JsonAlias值的字段。

<<p>代码片段/strong>:
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<String, String> values = new HashMap<>();
values.put("name", "TEST NAME");
Person person = new ObjectMapper().convertValue(values, Person.class);
System.out.println("name1: " + person.getName1());
System.out.println("name2: " + person.getName2());
}
static class Person {
@JsonAlias("name")
String name1;
@JsonAlias("name")
String name2;
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
}
}

:

name1: TEST NAME
name2: null

在上面的输出中。我还在等"测试名"呢。

在Jackson ObjectMapper中是否有任何配置可以帮助我实现这一点?

Jackson version - Jackson -databind-2.11.4.jar

解决方案1,@JsonGetter@JsonSetter指向自定义gettersetter
我们可以使用@JsonGetter("name")和@JsonSetter("name")注释将一个JSON属性值映射到处理两个属性的setter

public class Person {
@JsonIgnore
private String name1;
@JsonIgnore
private String name2;
@JsonSetter("name")
public void setName(String name) {
this.name1 = name;
this.name2 = name;
}
@JsonGetter("name")
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
}

方案二、@JsonAlias与特定setter
我们可以忽略一个字段,第二个标记使用别名,并添加一个自定义setNamesetter,将一个JSON值映射到几个字段。

public class Person {
@JsonAlias("name")
private String name1;
@JsonIgnore
private String name2;
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name1) {
this.name1 = name1;
}
public void setName(String name) {
this.name1 = name;
this.name2 = name;
}
}

或者直接在原始代码中添加自定义setNamesetter

public class Person {
@JsonAlias("name")
String name1;
@JsonAlias("name")
String name2;
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name1) {
this.name1 = name1;
}
public void setName(String name) {
this.name1 = name;
this.name2 = name;
}
}

解决方案3,@JsonProperty与特定setter
与方案2相同,但使用@JsonProperty("name")

public class Person {
@JsonProperty("name")
private String name1;
@JsonIgnore
private String name2;
public String getName1() {
return name1;
}
@JsonIgnore
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name1) {
this.name1 = name1;
}
public void setName(String name) {
this.name1 = name;
this.name2 = name;
}
}

更新:
如果您不能修改DTO对象,自定义反序列化器可以解决这个问题。

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
public class PersonDeserializer extends StdDeserializer<Person> {
public PersonDeserializer() {
this(null);
}
public PersonDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Person deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
Person person = new Person();
JsonNode node = jp.getCodec().readTree(jp);
String name =  node.get("name").asText();
person.setName1(name);
person.setName2(name);
return person;
}
}

对DTO对象应用反序列化器:

@JsonDeserialize(using = PersonDeserializer.class)
public class Person {
private String name1;
private String name2;
//getters and setters
}

ObjectMapper上的OR寄存器自定义反序列化器

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Person.class, new PersonDeserializer());
mapper.registerModule(module);

最新更新