我需要将JSON(有两个版本)转换为对象
第一版:
{"first_name":"John","last_name":"Doe"}
第二版:
{"fName":"John","lName":"Doe"}
我需要将JSON转换为
class User {
private String fullName;
public String getFullName() {
return fullName;
}
}
我遇到的一种方法是Mixin:
@Test
public void testMixinWorks_whenDeserialize() throws IOException {
ObjectMapper mapperForV1 = new ObjectMapper();
mapperForV1.addMixInAnnotations(User.class, UserV1Mixin.class);
User userFromV1 = mapperForV1.readValue(
"{\"first_name\":\"John\",\"last_name\":\"Doe\"}", User.class);
assertThat(userFromV1.getFullName(), is("John Doe"));
ObjectMapper mapperForV2 = new ObjectMapper();
mapperForV2.addMixInAnnotations(User.class, UserV2Mixin.class);
User userFromV2 = mapperForV2.readValue(
"{\"fn\":\"John\",\"ln\":\"Doe\"}", User.class);
assertThat(userFromV2.getFullName(), is("John Doe"));
}
static abstract class UserV1Mixin {
@JsonCreator
public UserV1Mixin(@JsonProperty("first_name") String firstName,
@JsonProperty("last_name") String lastName) {
}
}
static abstract class UserV2Mixin {
@JsonCreator
public UserV2Mixin(@JsonProperty("fName") String firstName,
@JsonProperty("lName") String lastName) {
}
}
但它不起作用,因为我不知道如何连接firstName和lastName。
是否可以使用Mixin反序列化派生值?
答案 0 :(得分:1)
您可以使用基于代理的创建者。您的属性将以Map<String, Object>
格式作为构造函数的参数。
public class User {
private String fullName;
@JsonCreator
public User(Map<String, Object> props) {
String firstName = "";
String lastName = "";
if (props.get("fName") != null) {
firstName = (String) props.get("fName");
lastName = (String) props.get("lName");
}
if (props.get("first_name") != null) {
firstName = (String) props.get("first_name");
lastName = (String) props.get("last_name");
}
this.fullName = firstName + " " + lastName;
}
public String getFullName() {
return fullName;
}
}
这将接受两个输入。 @JsonCreator
还有其他用法。您可以在此博文中阅读它们:http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html
更新:
您可以为User.class
public class UserDeserializer extends JsonDeserializer<User> {
@Override
public User deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
User user = new User();
if (node.has("fName")) {
user.setFullName(node.get("fName").asText() + " " + node.get("lName").asText());
} else if (node.has("first_name")) {
user.setFullName(node.get("first_name").asText() + " " + node.get("last_name").asText());
} else {
throw new UnsupportedOperationException();
}
return user;
}
}
ObjectMapper om = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(User.class, new UserDeserializer());
om.registerModule(module);
User user = om.readValue(input, User.class);
答案 1 :(得分:1)
经过一番研究,我得到了一种使用Builder模式和Mixin的方法:
/**
* no annotation on this class therefore
* this class is JSON version agnositc
*/
class User {
private String fullName;
public User(String fullName) {
this.fullName = fullName;
}
public String getFullName() {
return fullName;
}
}
/////////////////// v1 //////////////////////
@JsonPOJOBuilder(buildMethodName = "build", withPrefix = "set")
static class UserV1MixinBuilder {
private String firstName;
private String lastName;
@JsonProperty("first_name")
public UserV1MixinBuilder setFirstName(String value) {
this.firstName = value;
return this;
}
@JsonProperty("last_name")
public UserV1MixinBuilder setLastName(String value) {
this.lastName = value;
return this;
}
public User build() {
return new User(firstName + " " + lastName);
}
}
@JsonDeserialize(builder = UserV1MixinBuilder.class)
static abstract class UserV1Mixin {
}
/////////////////// v2 //////////////////////
@JsonPOJOBuilder(buildMethodName = "build", withPrefix = "set")
static class UserV2MixinBuilder {
private String firstName;
private String lastName;
@JsonProperty("fn")
public UserV2MixinBuilder setFirstName(String value) {
this.firstName = value;
return this;
}
@JsonProperty("ln")
public UserV2MixinBuilder setLastName(String value) {
this.lastName = value;
return this;
}
public User build() {
return new User(firstName + " " + lastName);
}
}
@JsonDeserialize(builder = UserV2MixinBuilder.class)
static abstract class UserV2Mixin {
}