我想开发一个组件,该组件允许根据要序列化的对象的字段的排除算法(JSON)筛选DTO的字段。基于杰克逊注释“ @JsonProperty”中提到的名称(如果存在的话),否则使用字段本身的名称(映射不带注释)。
请问,如何基于带有注释的排除进行动态过滤?有一些有用的资源(代码,tuto等)吗?
JacksonFieldFilter类
public class JacksonFieldFilter {
public <T> T filter(T input, List<String> toExclude, Function<Object, Object> fun) throws IllegalArgumentException, IllegalAccessException {
Field[] fields = input.getClass().getFields();
for (Field field : fields) {
// check is not elementary type.
// if not ==> get its annotation
Annotation[] annaotations = field.getAnnotations();
/// Filter on Jakson annotation only with name == JSonProperty
Annotation ja = getJakson(annaotations);
/// get annotation value as String ==> annotationNameValue.
String annotationNameValue = null;
if (toExclude.contains(annotationNameValue)) {
/// found the name in excluded values list
Object prev = field.get(input);
field.set(input, fun.apply(prev));
}
}
return input;
}
Annotation getJakson(Annotation[] annaotations) {
for (Annotation annotation : annaotations) {
if (annotation.annotationType().isAssignableFrom(JsonProperty.class)) {
return annotation;
}
}
return null;
}
// Test
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
JacksonFieldFilter filter = new JacksonFieldFilter();
Item item = new Item();
item.setField1("London");
item.setField2("Paris");
Item clone = null; // item.
clone = filter.filter(clone, Arrays.asList(new String[] { "field_1" }), p -> {
System.err.println("Erasing " + p);
return null;
});
// OUTPUT ==> {"field_2":"Paris"}
System.out.println(clone);
}
}
类项目
public class Item {
@JsonProperty("field_1")
private String field1;
@JsonProperty("field_2")
private String field2;
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
}
答案 0 :(得分:0)
您的代码有一些问题:
item
对象传递给过滤器函数,因此无法复制clone
中的字段值Item
类中的字段是私有的,因此您必须使用getClass().getDeclaredFields()
和setAccessible()
来访问/写入它们。请尝试以下代码:
public static class JacksonFieldFilter {
public <T> T filter(T src, T dest, Collection<String> toExclude, Function<String, Void> callback)
throws IllegalArgumentException, IllegalAccessException {
Field[] fields = src.getClass().getDeclaredFields();
for (Field field : fields) {
JsonProperty property = field.getAnnotation(JsonProperty.class);
if (property != null) {
String value = property.value();
if (toExclude.contains(value)) {
callback.apply(value);
} else {
// Write the value from "src" to "dest"
field.setAccessible(true); // Without this we can not write into a private field
field.set(dest, field.get(src));
}
}
}
return dest;
}
}
// ...
public static void main(String[] args) throws Exception {
Item item = new Item();
item.setField1("London");
item.setField2("Paris");
Item clone = new JacksonFieldFilter().filter(item, new Item(), Arrays.asList(new String[]{"field_1"}), (f) -> {
System.out.println("Erasing " + f);
return null;
});
System.out.println(clone);
}
输出:
Erasing field_1
Item{field1=null, field2=Paris}