我正在尝试使用杰克逊从父节点获取值。
我知道使用自定义反序列器可以实现此目的,但是样板太多了,因为您突然不得不手动处理所有事情。
这听起来很简单,但没有找到解决方法。
举例说明我想要的-如果我们有一个简单的User
和Address
...
@JsonDeserialize(builder = User.Builder.class)
public class User
{
private long id;
private String firstName;
private Address address;
...
public static class Builder
{
public Builder withId(long id);
public Builder withFirstName(String value);
public Builder withAddress(Address address);
public User create();
}
}
如果我们的地址相同
@JsonDeserialize(builder = Address.Builder.class)
public class Address
{
...
public static class Builder
{
public Builder withUserId(long id); // is there a way to ask for the parent id here?
public Builder withStreetName(String value);
public Address create();
}
}
样本输入:
{
"id": 7,
"firstName" : "John",
"lastName" : "Smith",
"address" : {
"streetName": "1 str"
}
}
答案 0 :(得分:0)
不,我认为您无法使用任何现有的Jackson代码。我认为唯一可以跨越这样的父子关系的是类型序列化/反序列化和UNWRAP_ROOT_VALUE
支持。
如果您想要这样的话,则需要为User
使用自定义反序列化器,或者自定义User
构造函数以使用正确的UserId构建新地址,然后再将其添加到建造者的内部状态。这是一个示例(使用Lombok来处理生成器的样板生成):
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Value;
import lombok.experimental.Wither;
public class Scratch {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"id\":1234,\"address\":{\"street\":\"123 Main St.\"}}";
User user = mapper.readValue(json, User.class);
System.out.println(user.toString());
}
@Value
@JsonDeserialize(builder = User.UserBuilder.class)
public static class User {
private final int id;
private final Address address;
@Builder(toBuilder = true)
public User(int id, Address address) {
this.id = id;
// Build a new address with the user's ID
this.address = address.withUserId(id);
}
@JsonPOJOBuilder(withPrefix = "")
public static class UserBuilder {}
}
@Value
@Builder(toBuilder = true)
@JsonDeserialize(builder = Address.AddressBuilder.class)
public static class Address {
@Wither
private final int userId;
private final String street;
@JsonPOJOBuilder(withPrefix = "")
public static class AddressBuilder {}
}
}
这会消耗以下json:
{
"id": 1234,
"address": {
"street": "123 Main St."
}
}
并产生以下输出:
Scratch.User(id=1234, address=Scratch.Address(userId=1234, street=123 Main St.))