如何在 Jackson 视图中获取类的属性列表? [英] How to get the list of properties of a class as Jackson views it?
问题描述
我正在编写需要访问由 Jackson 配置定义的类的属性列表的代码.
I'm writing code that needs to access the list of properties of a class as defined by a Jackson configuration.
例如,对于以下类:
@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 在序列化时实际考虑的属性.
I would get [name,longValue]
because that's the properties that Jackson actually considers when serializing.
我不认为编写一整段代码来查找 getter/setter 并检查 Jackson 注释是可行的方法,因为那会重新实现 Jackson.
I don't think writing a whole piece of code to look for getters/setters and inspect Jackson annotations is the way to go, since that would be reimplementing Jackson.
如果我能够获得用于序列化的 Jackson ObjectMapper
的句柄,是否有办法获取 Class> 的属性列表?
还是 Type
对象?(尊重 Jackson 注释和配置)
If I'm able to get a handle on the Jackson ObjectMapper
used for serialization, is there a way to get a list of properties of a Class<?>
or Type
object? (respecting Jackson annotations and config)
我深入研究了 Jackson 的实现,并找到了 POJOPropertiesCollector
,但我不确定如何从 Jackson 外部使用它(我相信我们不应该这样做).
I dug a bit into Jackson's implementation, and found the POJOPropertiesCollector
, but I'm not sure about how I can use it from outside Jackson (we're not supposed to do this I believe).
作为最后的手段,我可以创建我正在检查的类的实例,使用 ObjectMapper 对其进行序列化,然后解析 JSON 以查找属性名称,但我认为这也不干净(而且它会带来它的整套问题:空值可能不会被序列化,构造函数中会发生什么等).
As a last resort, I could create an instance of the class I'm inspecting, serialize it with the ObjectMapper, and then parse the JSON to find property names, but I don't think this is clean either (and it would bring its whole set of probelms: nulls might not be serialized, what happens in the construtor etc.).
有什么想法吗?
推荐答案
使用 Jackson,您可以内省任意类获取可用的 JSON 属性:
With Jackson, you can introspect an arbitrary class to get the available JSON properties:
// 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 属性所需的详细信息.
The BeanPropertyDefinition
list should give you the details you need regarding the JSON properties.
@JsonIgnoreProperties
类级别的注释没有考虑到上述方法.但是您可以使用 AnnotationIntrospector
获取在类级别忽略的属性:
The @JsonIgnoreProperties
class level annotation is not taken into account with the above mentioned approach. But you can use an AnnotationIntrospector
to get the properties ignored on class level:
// Get class level ignored properties
Set<String> ignoredProperties = mapper.getSerializationConfig().getAnnotationIntrospector()
.findPropertyIgnorals(beanDescription.getClassInfo()).getIgnored();
然后过滤 properties
删除出现在 ignoredProperties
中的属性:
Then filter properties
removing the properties which are present in ignoredProperties
:
// Filter properties removing the class level ignored ones
List<BeanPropertyDefinition> availableProperties = properties.stream()
.filter(property -> !ignoredProperties.contains(property.getName()))
.collect(Collectors.toList());
即使您为类定义了混入,这种方法也有效.
This approach works even if you have mix-ins defined for your class.
AnnotationIntrospector#findPropertyIgnorals(Annotated)
方法是在 Jackson 2.8 中引入的.AnnotationIntrospector#findPropertiesToIgnore(Annotated, boolean)
方法可用于旧版本(但自 Jackson 2.8 起已弃用).
The AnnotationIntrospector#findPropertyIgnorals(Annotated)
method was introduced in Jackson 2.8. The AnnotationIntrospector#findPropertiesToIgnore(Annotated, boolean)
method can be used for older versions (but it's deprecated since Jackson 2.8).
这篇关于如何在 Jackson 视图中获取类的属性列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!