如何获取Jackson @JsonView视角下对应类的属性列表?
解决方案
实现思路
不要手动反射扫描类字段的@JsonView注解,直接复用Jackson内置的元数据解析能力,得到的属性列表和Jackson实际序列化时的过滤规则完全一致,避免遗漏混合注解、方法注解、字段重命名等特殊场景的适配。
完整代码实现
import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition; import java.util.ArrayList; import java.util.List; import java.util.Set; public class JsonViewPropertyUtils { /** * 获取指定JsonView视角下,Jackson序列化时会输出的类属性列表 * @param mapper 业务使用的ObjectMapper实例,会自动适配其配置规则 * @param targetClazz 目标DTO类 * @param viewClazz 指定的JsonView视角类 * @return 符合规则的属性名列表 */ public static List<String> getPropertiesByView(ObjectMapper mapper, Class<?> targetClazz, Class<?> viewClazz) { // 解析目标类的类型元数据 JavaType javaType = mapper.getTypeFactory().constructType(targetClazz); // 从序列化配置中获取类的完整属性描述 BeanDescription beanDescription = mapper.getSerializationConfig().introspect(javaType); List<BeanPropertyDefinition> allProperties = beanDescription.findProperties(); // 适配ObjectMapper的全局视图包含配置:无@JsonView注解的属性是否默认对所有视图可见 boolean defaultViewInclusion = mapper.getSerializationConfig().isEnabled( com.fasterxml.jackson.databind.MapperFeature.DEFAULT_VIEW_INCLUSION ); List<String> matchedProperties = new ArrayList<>(); for (BeanPropertyDefinition prop : allProperties) { Set<Class<?>> propViews = prop.findViews(); // 处理无视图配置的属性 if (propViews.isEmpty()) { if (defaultViewInclusion) { matchedProperties.add(prop.getName()); } continue; } // 匹配视图(支持视图类的继承关系) for (Class<?> pv : propViews) { if (pv.isAssignableFrom(viewClazz)) { matchedProperties.add(prop.getName()); break; } } } return matchedProperties; } // 测试示例 public static void main(String[] args) { ObjectMapper objectMapper = new ObjectMapper(); // 查询A视角下的属性 System.out.println(getPropertiesByView(objectMapper, MyDto.class, A.class)); // 输出:[intValue1, intValue3] // 查询B视角下的属性 System.out.println(getPropertiesByView(objectMapper, MyDto.class, B.class)); // 输出:[intValue2, intValue3] } } // 测试用视图类 class A {} class B {}
注意事项
- 该实现完全复用Jackson的解析逻辑,自动适配字段重命名、混合注解、
@JsonView加在getter方法上等场景,和实际序列化的属性输出结果完全一致 - 自动适配
DEFAULT_VIEW_INCLUSION全局配置,无需额外处理 - 天然支持视图类继承:如果视图类B继承自A,查询A视角时会自动包含所有标注了B视图的属性
内容的提问来源于stack exchange,提问作者Marcus Chiu
相关产品推荐
相关产品推荐

