You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 09:24:08