如何从JSON字段名获取Java对象字段的名称

huangapple go评论106阅读模式
英文:

How to get Java's object field's name from JSON fields name

问题

以下是翻译好的内容:

我想要在响应中过滤掉一些字段。过滤操作应该在将 Java 对象序列化为 JSON 之前执行。
考虑以下情况:

  1. public class Entity {
  2. @JsonProperty("some_property")
  3. String someProperty;
  4. @JsonProperty("nested_entity")
  5. @OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  6. NestedEntity nestedEntity;
  7. // 其他字段,例如 fieldA,fieldB
  8. }

API 端点:

  1. get api/entity/{id}?fields=some_property,field_a

现在的要求是,在输出中,我们只应该过滤掉 someProperty 和 fieldA 这两个字段。就像这样:

  1. {
  2. "some_property": "foo",
  3. "field_a": "bar"
  4. }

但是,由于这些是 JSON 字段,而不是 Java 对象字段,我不能通过反射来进行过滤或获取这些字段。我们是否有办法实现这一点,即根据 JSON 字段来过滤 Java 对象?

附:在序列化之前进行过滤的优点是,除非需要这些字段,否则可以避免 lazy-fields 的数据库调用。

提前感谢您的帮助!

英文:

I want to filter out some fields in the response. Filtering should be done before the Java object is serialised into the JSON.
Consider:

  1. public class Entity {
  2. @JsonProperty("some_property")
  3. String someProperty;
  4. @JsonProperty("nested_entity")
  5. @OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  6. NestedEntity nestedEntity;
  7. // other fields for eg fieldA, fieldB
  8. }

API endpoint

  1. get api/entity/{id}?fields=some_property,field_a

Now the ask is, in the o/p we should filter out only someProperty and fieldA. Like

  1. {
  2. "some_property": "foo",
  3. "field_a": "bar"
  4. }

But since these are JSON fields not Java object fields I can't filter or get these fields them by Reflection. Is there a way we can achieve this, i.e. filtering of Java object based on json fields ?

FYI: The advantage of filtering before serialization is that the lazy-fields' DB calls are saved unless these fields are required

Thanks in advance!

答案1

得分: 1

  1. 关于使用`@JsonFilter`建议来支持空的`fields`或没有字段过滤的建议以及为了支持这一点添加了JacksonConfiguration
  2. @JsonFilter("entityFilter")
  3. public class Entity {
  4. @JsonProperty("some_property")
  5. String someProperty;
  6. // 其他字段,例如 fieldA,fieldB
  7. }
  8. ---
  9. @Configuration
  10. public class JacksonConfiguration {
  11. public JacksonConfiguration(ObjectMapper objectMapper) {
  12. objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
  13. }
  14. }
  15. ---
  16. public class FieldMapper {
  17. @SneakyThrows
  18. public static Dto getFilteredFields(Dto make, String fields[]) {
  19. ObjectMapper objectMapper = new ObjectMapper();
  20. if(ArrayUtils.isNotEmpty(fields)) {
  21. FilterProvider filters = new SimpleFilterProvider().addFilter(
  22. "entityFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fields)
  23. );
  24. objectMapper.setFilterProvider(filters);
  25. } else {
  26. objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
  27. }
  28. JsonNode j = objectMapper.readTree(objectMapper.writeValueAsString(make));
  29. return objectMapper.convertValue(j, Dto.class);
  30. }
  31. }
  32. -----
  33. // 控制器代码用于获取带有字段dto的api/entity/{id}?fields=some_property,field_a
  34. Dto filteredFields = getFilteredFields(dto, fields);
  35. return filteredFields;
英文:

On the suggestion of @robocode using @JsonFilter and also to support empty fields or no fields filtering added JacksonConfiguration

  1. @JsonFilter("entityFilter")
  2. public class Entity {
  3. @JsonProperty("some_property")
  4. String someProperty;
  5. // other fields for eg fieldA, fieldB
  6. }

  1. @Configuration
  2. public class JacksonConfiguration {
  3. public JacksonConfiguration(ObjectMapper objectMapper) {
  4. objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
  5. }
  6. }

  1. public class FieldMapper {
  2. @SneakyThrows
  3. public static Dto getFilteredFields(Dto make, String fields[]) {
  4. ObjectMapper objectMapper = new ObjectMapper();
  5. if(ArrayUtils.isNotEmpty(fields)) {
  6. FilterProvider filters = new SimpleFilterProvider().addFilter(
  7. "entityFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fields)
  8. );
  9. objectMapper.setFilterProvider(filters);
  10. } else {
  11. objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
  12. }
  13. JsonNode j = objectMapper.readTree(objectMapper.writeValueAsString(make));
  14. return objectMapper.convertValue(j, Dto.class);
  15. }
  16. }

  1. // controller code to get the dto for api/entity/{id}?fields=some_property,field_a
  2. Dto filteredFields = getFilteredFields(dto, fields);
  3. return filteredFields

huangapple
  • 本文由 发表于 2020年10月16日 03:23:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/64378410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定