Jackson 映射中标准属性和动态属性的混合

问题描述 投票:0回答:2

我们正在使用一个 REST 服务,该服务提供包含一些标准属性以及许多动态属性的 json。

例如:

{
  id: 123,
  name: "some name",
  custom_name: "Some value",
  some_other_custom_name: "Some other value",
}

理想情况下,我希望课程设计如下:

public class MyObject{
  @JsonProperty int id;
  @JsonProperty String name;
  private Map<String, String> customVals;

  public int getId(){
    return id;
  }

  public String getName(){
    return name;
  }

  public String getCustomVal(String key){
    return customVals.get(key);
  }
}

有什么方法可以说服 Jackson 将自定义值推送到 Map 中(或实现等效功能)?

现在,我只是将整个对象反序列化为 Map,并将其包装在我的业务对象中,但它并不像反序列化处理它那样优雅。

java json jackson
2个回答
7
投票

您可以使用 Jackson @JsonAnySetter 和 @JsonAnyGetter 注释

这是一个完整的示例:

public class JacksonAnyGetter {

    static final String JSON = "{"
            + "  \"id\": 123,"
            + "  \"name\": \"some name\","
            + "  \"custom_name\": \"Some value\","
            + "  \"some_other_custom_name\": \"Some other value\""
            + "}";

    static class Bean {
        public int id;
        public String name;
        private Map<String, Object> properties = new HashMap<>();

        @JsonAnySetter
        public void add(String key, String value) {
            properties.put(key, value);
        }

        @JsonAnyGetter
        public Map<String, Object> getProperties() {
            return properties;
        }

        @Override
        public String toString() {
            return "Bean{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", properties=" + properties +
                    '}';
        }
    }

    public static void main(String[] args) throws IOException {
        final ObjectMapper mapper = new ObjectMapper();
        final Bean bean = mapper.readValue(JSON, Bean.class);
        System.out.println(bean);
        final String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
        System.out.println(json);
    }
}

输出:

Bean{id=123, name='some name', properties={custom_name=Some value, some_other_custom_name=Some other value}}

{
  "id" : 123,
  "name" : "some name",
  "custom_name" : "Some value",
  "some_other_custom_name" : "Some other value"
}

1
投票

动态属性的问题(例如在 Spring 3.0

ProblemDetail
)和 Jackson 字段类型序列化:

  jackson.visibility:
    field: any
    getter: none
    setter: none
    is-getter: none

答案中的道具重复:

{
  "type": "about:blank",
  "title": null,
  "status": 400,
  "detail": "Invalid request content.",
  "instance": "/api/register",
  "properties": {
    "email": "должно иметь формат адреса электронной почты"
  },
  "email": "должно иметь формат адреса электронной почты"
}

@JsonIgnoreProperties({"properties"})
到处删除
email

找到修复:

    @JsonAutoDetect(fieldVisibility = NONE, getterVisibility = ANY)
    interface MixIn {
        @JsonAnyGetter
        Map<String, Object> getProperties();
    }

or

    @JsonAutoDetect(fieldVisibility = NONE, getterVisibility = ANY)
    interface MixIn extends ProblemDetailJacksonMixin{}

and

    @Autowired
    void configureAndStoreObjectMapper(ObjectMapper objectMapper) {
        // https://stackoverflow.com/questions/7421474/548473
        objectMapper.addMixIn(ProblemDetail.class, MixIn.class);
    }
© www.soinside.com 2019 - 2024. All rights reserved.