我挖掘了杰克逊的文档并找到了两个解决方案。
这是我的Java类:
public class User {
protected String name;
protected String email;
protected int age;
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name + ": [ " + email + ", " + age + " ]";
}
}
第一个解决方案是创建自定义 PropertyNamingStrategy:
public class MappingPropertyNamingStrategy extends PropertyNamingStrategy {
Map<String, String> nameMap = new HashMap<String, String>();
public void setMap(Map<String, String> map) {
nameMap = map;
}
@Override
public String nameForGetterMethod(MapperConfig<?> cfg,
AnnotatedMethod method,
String defaultName) {
return mapName(defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> cfg,
AnnotatedMethod method,
String defaultName) {
return mapName(defaultName);
}
@Override
public String nameForField(MapperConfig<?> cfg,
AnnotatedField field,
String defaultName) {
return mapName(defaultName);
}
protected String mapName(String name) {
if (nameMap.containsKey(name)) {
return nameMap.get(name);
} else {
return name;
}
}
}
然后,您可以定义从用户字段到适当 JSON 字段的映射:
String json1 = "{ \"user\": { \"name\": \"John\", \"age\": 21, \"email\": \"john@mail.com\", \"location\": \"NYC\" }}";
String json2 = "{ \"user\": \"John\", \"mail\": \"john@mail.com\", \"age\": \"21\" }";
String json3 = "{ \"who\": \"John\", \"contacts\": \"john@mail.com\", \"age\": 21 }";
ObjectMapper mapper = new ObjectMapper();
MappingPropertyNamingStrategy namingStrategy = new MappingPropertyNamingStrategy();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Map<String, User> res = mapper.readValue(json1, new TypeReference<Map<String, User>>() {});
System.out.println(res.get("user"));
mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(namingStrategy);
namingStrategy.setMap(new HashMap<String, String>() {{
put("name", "user");
put("email", "mail");
}});
System.out.println(mapper.readValue(json2, new TypeReference<User>(){}));
mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(namingStrategy);
namingStrategy.setMap(new HashMap<String, String>() {{
put("name", "who");
put("email", "contacts");
}});
System.out.println(mapper.readValue(json3, new TypeReference<User>(){}));
另一种解决方案是使用 mixins:
@JsonIgnoreProperties({"location"})
abstract class FirstFormat {
}
abstract class SecondFormat {
@JsonProperty("user")
public abstract void setName(String name);
@JsonProperty("mail")
public abstract void setEmail(String email);
public abstract void setAge(int age);
}
abstract class ThirdFormat {
@JsonProperty("who")
public abstract void setName(String name);
@JsonProperty("contacts")
public abstract void setEmail(String email);
public abstract void setAge(int age);
}
然后你只需要将它与 User 类相关联:
mapper = new ObjectMapper();
mapper.addMixInAnnotations(User.class, FirstFormat.class);
Map<String, User> res = mapper.readValue(json1, new TypeReference<Map<String, User>>() {});
System.out.println(res.get("user"));
mapper = new ObjectMapper();
mapper.addMixInAnnotations(User.class, SecondFormat.class);
System.out.println(mapper.readValue(json2, new TypeReference<User>(){}));
mapper = new ObjectMapper();
mapper.addMixInAnnotations(User.class, ThirdFormat.class);
System.out.println(mapper.readValue(json3, new TypeReference<User>(){}));
我认为,mixins 是最好的解决方案,因为它提供了更多的控制。