使用 Jackson 只解包一些属性

Unwrap only some properties with Jackson

假设我有这个对象:

class Person {
   String name;
   Household getHousehold();
}

class Household {
   Set<Address> getAddresses();
   String householdId;
}

通常会序列化如下

{
  "name": "XXX",
  "household": {
    "addresses": [...]
  }
}

有没有办法用注释/混合配置 Jackson 来获得这个(即不使用 DTO)?

{
  "name": "XXX",
  "addresses": [...],
  "household": {
    "householdId": 123
  }
}

您可以通过使用 mixins 和注释来配置特定 属性 的解包:

1.混合

假设您定义了以下 mixin:

public abstract class UnwrappedAddresses {

        @JsonUnwrapped
        public abstract Household getHouseHold();

    }

然后将自定义模块添加到您的 objectMapper,它将 mixin 应用到 Person class,如下所示:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper .registerModule(new SimpleModule() {
            @Override
            public void setupModule(SetupContext context) {
                context.setMixInAnnotations(Person.class, UnwrappedAddresses.class);
            }

        });

此方法不会将 Household 序列化更改为单个项目,而只是在将家庭项目封装在 Person 对象中时对其进行解包。

2。注释

只需将 @JsonUnwrapped 添加到您的 getHouseHold() 方法中。

编辑:post 更改后。

你想要的基本上是改变 json 的输出,这可以通过使用 @JsonAnyGetter 注释来完成(它可以动态地向你的 pojo 添加新属性)。

您可以通过忽略家庭 属性 并在 @JsonAnyGetter 的帮助下展开它来实现您的预​​期结果。

@JsonIgnoreProperties("houseHold")
public static class Person {
   String name;

   Household houseHold;

    @JsonAnyGetter
    public Map<String,Object> properties(){
      Map<String,Object> additionalProps=new HashMap<>();
      additionalProps.put("addresses", new ArrayList<>(houseHold.getAddresses()));
      Map<String,Object> houseHolProps=new HashMap<>();
      houseHolProps.put("houseHoldId", houseHold.id);
      additionalProps.put("houseHold", houseHolProps);
      return additionalProps;
     }
        ..getters&setters omitted
}

序列化后return

{"name":"name",
 "houseHold":{"houseHoldId":0},
 "addresses":[
         {"houseNo":2,"street":"abc"},
         {"houseNo":1,"street":"str"}
  ]
 }