问题描述
使用Jackson,您可以内省一个任意类以获取可用的JSON属性:
// Construct a Jackson JavaType for your class
JavaType javaType = mapper.getTypeFactory().constructType(MyDto.class);
// Introspect the given type
BeanDescription beanDescription = mapper.getSerializationConfig().introspect(javaType);
// Find properties
List<BeanPropertyDefinition> properties = beanDescription.findProperties();
该BeanPropertyDefinition
列表应为您提供有关JSON属性所需的详细信息。
在@JsonIgnoreProperties
类级别的注释不考虑与上面提到的方法。但是您可以使用AnnotationIntrospector
来获取在类级别忽略的属性:
// Get class level ignored properties
Set<String> ignoredProperties = mapper.getSerializationConfig().getAnnotationIntrospector()
.findPropertyIgnorals(beanDescription.getClassInfo()).getIgnored();
然后过滤properties
除去存在于中的属性ignoredProperties
:
// Filter properties removing the class level ignored ones
List<BeanPropertyDefinition> availableProperties = properties.stream()
.filter(property -> !ignoredProperties.contains(property.getName()))
.collect(Collectors.toList());
即使为您的班级定义了混入,此方法也有效。
该AnnotationIntrospector#findPropertyIgnorals(Annotated)
方法在Jackson
2.8中引入。该AnnotationIntrospector#findPropertiesToIgnore(Annotated,
boolean)
方法可用于旧版本(但自Jackson
2.8起已弃用)。
解决方法
我正在编写需要访问由Jackson配置定义的类的属性列表的代码。
例如,对于以下类:
@JsonIgnoreProperties(value = { "intValue" })
public class MyDto {
@JsonProperty("name")
private String stringValue;
private int intValue;
private long longValue;
@JsonIgnore
private boolean booleanValue;
// standard setters and getters are not shown
}
我会得到,[name,longValue]
因为那是Jackson序列化时实际上考虑的属性。
我不认为编写完整的代码来查找getter / setter和检查Jackson注释不是要走的路,因为那样会重新实现Jackson。
如果我能够获得ObjectMapper
用于序列化的Jackson的句柄,是否可以获取a
Class<?>
或Type
对象的属性列表?(尊重杰克逊的注释和配置)
我研究了Jackson的实现,找到了POJOPropertiesCollector
,但是我不确定如何从Jackson外部使用它(我相信我们不应该这样做)。
作为最后的选择,我可以创建要检查的类的实例,使用ObjectMapper对其进行序列化,然后解析JSON以查找属性名称,但是我也不认为这很干净(并且这样做会带来完整的探针集:null可能不会序列化,构造器中会发生什么等)。
有任何想法吗?