英文:
How to get Java's object field's name from JSON fields name
问题
以下是翻译好的内容:
我想要在响应中过滤掉一些字段。过滤操作应该在将 Java 对象序列化为 JSON 之前执行。
考虑以下情况:
public class Entity {
@JsonProperty("some_property")
String someProperty;
@JsonProperty("nested_entity")
@OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
NestedEntity nestedEntity;
// 其他字段,例如 fieldA,fieldB
}
API 端点:
get api/entity/{id}?fields=some_property,field_a
现在的要求是,在输出中,我们只应该过滤掉 someProperty 和 fieldA 这两个字段。就像这样:
{
"some_property": "foo",
"field_a": "bar"
}
但是,由于这些是 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:
public class Entity {
@JsonProperty("some_property")
String someProperty;
@JsonProperty("nested_entity")
@OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
NestedEntity nestedEntity;
// other fields for eg fieldA, fieldB
}
API endpoint
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
{
"some_property": "foo",
"field_a": "bar"
}
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
关于使用`@JsonFilter`建议来支持空的`fields`或没有字段过滤的建议,以及为了支持这一点,添加了JacksonConfiguration。
@JsonFilter("entityFilter")
public class Entity {
@JsonProperty("some_property")
String someProperty;
// 其他字段,例如 fieldA,fieldB
}
---
@Configuration
public class JacksonConfiguration {
public JacksonConfiguration(ObjectMapper objectMapper) {
objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
}
}
---
public class FieldMapper {
@SneakyThrows
public static Dto getFilteredFields(Dto make, String fields[]) {
ObjectMapper objectMapper = new ObjectMapper();
if(ArrayUtils.isNotEmpty(fields)) {
FilterProvider filters = new SimpleFilterProvider().addFilter(
"entityFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fields)
);
objectMapper.setFilterProvider(filters);
} else {
objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
}
JsonNode j = objectMapper.readTree(objectMapper.writeValueAsString(make));
return objectMapper.convertValue(j, Dto.class);
}
}
-----
// 控制器代码用于获取带有字段dto的api/entity/{id}?fields=some_property,field_a
Dto filteredFields = getFilteredFields(dto, fields);
return filteredFields;
英文:
On the suggestion of @robocode using @JsonFilter
and also to support empty fields
or no fields filtering added JacksonConfiguration
@JsonFilter("entityFilter")
public class Entity {
@JsonProperty("some_property")
String someProperty;
// other fields for eg fieldA, fieldB
}
@Configuration
public class JacksonConfiguration {
public JacksonConfiguration(ObjectMapper objectMapper) {
objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
}
}
public class FieldMapper {
@SneakyThrows
public static Dto getFilteredFields(Dto make, String fields[]) {
ObjectMapper objectMapper = new ObjectMapper();
if(ArrayUtils.isNotEmpty(fields)) {
FilterProvider filters = new SimpleFilterProvider().addFilter(
"entityFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fields)
);
objectMapper.setFilterProvider(filters);
} else {
objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
}
JsonNode j = objectMapper.readTree(objectMapper.writeValueAsString(make));
return objectMapper.convertValue(j, Dto.class);
}
}
// controller code to get the dto for api/entity/{id}?fields=some_property,field_a
Dto filteredFields = getFilteredFields(dto, fields);
return filteredFields
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论