java - Jackson 在反序列化过程中对属性进行动态过滤

标签 java json filtering jackson deserialization

我有一个 REST WS 来更新接收 JSON 字符串作为输入的 bean 对象。

ABean entity = svc.findEntity(...);
objectMapper.readerForUpdating(entity).readValue(json);
[...]
svc.save(entity);

ABean 是一种复杂类型,还包含其他对象 例如:

class ABean {
    public BBean b;
    public CBean c;

    public String d;
}

svc.save(...) 将保存 bean 和嵌入的对象

出于安全原因,我想过滤掉一些可以由 JSON 字符串更新的属性,但我想动态地执行此操作,以便对于每个 WS(或用户角色)我可以决定要阻止哪些属性被更新(所以我不能简单地使用 Jackson Views)

总而言之,有什么方法可以在 JSON 反序列化期间动态过滤掉属性?

最佳答案

另一种方法是使用 BeanDeserializerModifier:

private static class BeanDeserializerModifierForIgnorables extends BeanDeserializerModifier {

        private java.lang.Class<?> type;
        private List<String> ignorables;

        public BeanDeserializerModifierForIgnorables(java.lang.Class clazz, String... properties) {
            ignorables = new ArrayList<>();
            for(String property : properties) {
                ignorables.add(property);
            }
            this.type = clazz;
        }

        @Override
        public BeanDeserializerBuilder updateBuilder(
                DeserializationConfig config, BeanDescription beanDesc,
                BeanDeserializerBuilder builder) {
            if(!type.equals(beanDesc.getBeanClass())) {
                return builder;
            }

            for(String ignorable : ignorables) {
                builder.addIgnorable(ignorable);                
            }

            return builder;
        }

        @Override
        public List<BeanPropertyDefinition> updateProperties(
                DeserializationConfig config, BeanDescription beanDesc,
                List<BeanPropertyDefinition> propDefs) {
            if(!type.equals(beanDesc.getBeanClass())) {
                return propDefs;
            }

            List<BeanPropertyDefinition> newPropDefs = new ArrayList<>();
            for(BeanPropertyDefinition propDef : propDefs) {
                if(!ignorables.contains(propDef.getName())) {
                    newPropDefs.add(propDef);
                }
            }
            return newPropDefs;
        }
    }

您可以通过以下方式将修改器注册到 ObjectMapper:

BeanDeserializerModifier modifier = new BeanDeserializerModifierForIgnorables(YourType.class, "name");
DeserializerFactory dFactory = BeanDeserializerFactory.instance.withDeserializerModifier(modifier);
ObjectMapper mapper = new ObjectMapper(null, null, new DefaultDeserializationContext.Impl(dFactory));

然后忽略定义的属性。如果使用@JsonAnySetter 注释,则可以忽略 updateBuilder 方法。

您好, 马丁

关于java - Jackson 在反序列化过程中对属性进行动态过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12305438/

相关文章:

java.lang.ClassCastException : org. apache.xerces.jaxp.DocumentBuilderFactoryImpl 无法转换为 javax.xml.parsers.DocumentBuilderFactory

Java Firestore Android 在查询中使用数组列表来显示来自关注用户的帖子

search - Grails 搜索/过滤多个参数 - Controller 逻辑

json - NetcatSource:客户端发送的长度超过最大长度

php - 空 json_encode

c# - 如何使用 LINQ MVC 基于 AND 条件应用搜索过滤

Python:访问与循环数组的当前位置相匹配的移动窗口数组的索引

java - 获取 Class<Array> 的代号

java - 使用 Jni4net 运行 Bridge.LoadAndRegisterAssemblyFrom(File arg0) 时出现 System.IO.FileNotFoundException

objective-c - 使用 NSJSONSerialization JSONObjectWithData : 解析 JSON 字符串上的真值和假值