我正在尝试使用杰克逊从父节点获取值。
我知道这可以通过自定义反序列化器来实现,但是有太多的样板,因为您突然必须手动处理所有内容。
这听起来很简单,但没有找到一种方法来做到这一点。
为了说明我想要什么 - 如果我们对Address
有一个简单的User
......
@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"
}
}
不,我认为你不能使用任何现有的杰克逊代码。我认为唯一可以像这样跨越父/子关系的是类型序列化/反序列化和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.))