Java 基于自定义注释的序列化忽略字段

Java 基于自定义注释的序列化忽略字段,java,jackson,Java,Jackson,考虑一个例子,我有2个对象映射器实例。 我希望必须从序列化中排除使用某些自定义注释进行注释的字段 而其他映射器包括(忽略注释) Like类有3个字段a、b、c,c用一些注释进行注释(比如@IgnoreField) (它们将包含n个类,每个类都有不打算序列化的字段) 现在,第一个对象映射器o1必须只序列化a和b。 而第二个对象映射器o2可以序列化a、b和c 任何具有不同字段的类都可能出现这种情况,其中一些字段可能会被注释。请尝试针对不同的条件进行配置 @JsonFilter("someBeanFi

考虑一个例子,我有2个对象映射器实例。 我希望必须从序列化中排除使用某些自定义注释进行注释的字段 而其他映射器包括(忽略注释)

Like类有3个字段a、b、c,c用一些注释进行注释(比如@IgnoreField) (它们将包含n个类,每个类都有不打算序列化的字段)

现在,第一个对象映射器o1必须只序列化a和b。 而第二个对象映射器o2可以序列化a、b和c

任何具有不同字段的类都可能出现这种情况,其中一些字段可能会被注释。

请尝试针对不同的条件进行配置

@JsonFilter("someBeanFilter")
public class SomeBean {
}

SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("someBeanFilter",SimpleBeanPropertyFilter.serializeAllExcept("aFild")); 

ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider); 

我建议您可以尝试在这里使用自定义注释,您可以将注释放置在所需的字段上,并且可以放置在任何数量的类上。因此,使用反射这一自定义注释的关键概念,您可以定义如何处理此注释的行为。 检查此示例:

一个明显的非答案:

这很可能是个糟糕的主意

您编写代码来传达您的意图。当您使用该注释时,您告诉“所有人”这些字段应该被忽略

一个阅读你的代码的人可能会花半天的时间问自己“它说
@IgnoreField
A
c
,那么为什么
A
c
会显示序列化数据呢?”

换句话说,无论您在这里试图解决什么问题,答案很可能不是通过侵入忽略注释有时


下一个最好的“合理”解决方案可能是:依赖不同的自定义注释,如
@IgnoreAlways
和类似
@OnlyIncludeForXyz
。换句话说:清楚地表达可能发生的事情。与其使用声明式编程,不如先“撒谎”你声明的内容。

你总是可以实现一个定制的
JsonSerializer
,然后在ObjectMapper中注册它

class Bean {
    @Ignore
    String a;
    String b;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Ignore {

}

class BeanWithIgnoredFieldsSerializer extends JsonSerializer<Bean> {

    @Override
    public void serialize(final Bean value, final JsonGenerator gen, final SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeStartObject();
        try {
            for (final Field f : Bean.class.getFields()) {
                if (f.isAnnotationPresent(Ignore.class)) {
                    gen.writeStringField(f.getName(), (String) f.get(value));
                }
            }
        } catch (final Exception e) {
            //
        }
        gen.writeEndObject();
    }

}

class BeanModule extends SimpleModule {

    BeanModule() {
        addSerializer(Bean.class, new BeanWithIgnoredFieldsSerializer());
    }
}

void configure(final ObjectMapper om) {
    om.registerModule(new BeanModule());
}
类Bean{
@忽略
字符串a;
b串;
}
@保留(RetentionPolicy.RUNTIME)
@目标(ElementType.FIELD)
@接口忽略{
}
类BeanWithIgnoredFieldsSerializer扩展JsonSerializer{
@凌驾
public void serialize(最终Bean值、最终JsonGenerator gen、最终SerializerProvider序列化程序)引发IOException、JsonProcessingException{
gen.writeStartObject();
试一试{
for(最后一个字段f:Bean.class.getFields()){
if(f.isAnnotationPresent(Ignore.class)){
gen.writeStringField(f.getName(),(String)f.get(value));
}
}
}捕获(最终异常e){
//
}
writeEndObject将军();
}
}
类BeanModule扩展了SimpleModule{
BeanModule(){
addSerializer(Bean.class,新的BeanWithIgnoredFieldsSerializer());
}
}
void配置(最终ObjectMapper om){
注册表模块(新的BeanModule());
}

注意,我没有测试这段代码,但这是如何向OM添加自定义序列化程序的一般想法。在
serialize
方法中,根据需要调整代码。

问题是什么?找到解决方案了吗?OP知道自定义注释。这不是他问题的重点,所以你的答案。。。什么都不回答。我明白你的意思,但这只是一个例子,实际的注释是@FieldDescriptor,带有一些属性。@RajatJindal,那么你应该这么说。这就是为什么人们建议你总是提供一个答案,而不是仅仅用模糊的术语描述你的问题。如果你认为它正确地回答了你的问题,你可以而且可能应该将它标记为接受。也要考虑GhostCat所说的话,并考虑一下你是否真的想那样做。