杰克逊生成器模式从父级获取值



我正在尝试使用杰克逊从父节点获取值。

我知道这可以通过自定义反序列化器来实现,但是有太多的样板,因为您突然必须手动处理所有内容。

这听起来很简单,但没有找到一种方法来做到这一点。

为了说明我想要什么 - 如果我们对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.))

最新更新