当前位置: 首页 > 知识库问答 >
问题:

如何动态忽略Jackson序列化上的属性

刘修能
2023-03-14

我有一个实体具有多个@ManyToOne关联。我正在使用spring-boot公开一个REST API。目前,我有多个REST API,它们返回整个实体的JSON响应,包括关联。

但我不想序列化所有REST API中的所有关联对象。

例如:

  • API-1应返回parent+associationA对象
  • API-2应返回parent+associationA+associationB对象
  • API-3应返回parent+associationB+associationC+AssociationOnd

注意:我对每一个都使用相同的类;我对为每个API创建DTO不感兴趣。

任何建议都非常感谢。

共有1个答案

屠嘉勋
2023-03-14

我将在Jackson中执行动态过滤的三种方法放在一起。其中一个必须适合你的需要。

您可以使用@jsonview:

public class Views {         
    interface Simple { }  
    interface Detailed extends Simple { }   
}
public class Foo {

    @JsonView(Views.Simple.class)
    private String name;

    @JsonView(Views.Detailed.class)
    private String details;

    // Getters and setters
}
@RequestMapping("/foo")
@JsonView(Views.Detailed.class)
public Foo getFoo() {
    Foo foo = new Foo();
    return foo;
}

或者,您可以使用mappingjacksonvalue动态设置视图。

@RequestMapping("/foo")
public MappingJacksonValue getFoo() {
    Foo foo = new Foo();
    MappingJacksonValue result = new MappingJacksonValue(foo);
    result.setSerializationView(Views.Detailed.class);
    return result;
}
public class CustomSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
        BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {

        // In this method you can add, remove or replace any of passed properties

        return beanProperties;
    }
}
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {

    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanSerializerModifier(new CustomSerializerModifier());
    }
});

查看这里和这里的示例。

另一种方法涉及@jsonfilter:

@JsonFilter("customPropertyFilter")
public class Foo {

    private String name;
    private String details;

    // Getters and setters
}

根据需要扩展SimpleBeanPropertyFilter并重写SerializeAsField()方法:

public class CustomPropertyFilter extends SimpleBeanPropertyFilter {

    @Override
    public void serializeAsField(Object pojo, JsonGenerator jgen,
                                 SerializerProvider provider, 
                                 PropertyWriter writer) throws Exception {

        // Serialize a field
        // writer.serializeAsField(pojo, jgen, provider, writer);

        // Omit a field from serialization
        // writer.serializeAsOmittedField(pojo, jgen, provider);
    }
}
FilterProvider filterProvider = new SimpleFilterProvider()
        .addFilter("customPropertyFilter", new CustomPropertyFilter());

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

如果希望使筛选器“全局”,即应用于所有bean,可以创建一个mix-in类,并使用@JSONFilter(“CustomPropertyFilter”)对其进行注释:

@JsonFilter("customPropertyFilter")
public class CustomPropertyFilterMixIn {

}

然后将mix-in类绑定到object:

mapper.addMixIn(Object.class, CustomPropertyFilterMixIn.class);
 类似资料:
  • 问题内容: 我想序列化一个不受我控制的POJO类,但是想避免序列化任何来自超类而不是最终类的属性。例: 您可以从示例中猜测到,该类是由JOOQ生成的,并且是从复杂的基类UpdatableRecordImpl继承的,该基类还具有一些类似于bean属性的方法,这会在序列化过程中引起问题。另外,我有几个类似的类,因此最好避免对所有生成的POJO复制相同的解决方案。 到目前为止,我已经找到以下可能的解决方

  • > 使用mixin技术忽略来自超类的特定字段,如下所示:我如何告诉jackson忽略一个我无法控制源代码的属性? 这样做的问题是,如果基类发生了变化(例如,其中出现了一个新的getAnything()方法),它可能会破坏我的实现。 实现一个自定义序列化程序并在那里处理问题。这在我看来有点矫枉过正。 但是,从纯设计的角度来看,最好的方法是告诉jackson我只想序列化最终类的属性,而忽略所有继承的属

  • 我有以下课程- 我如何通过使用Jackson JSON API动态地排除字段序列化?

  • 问题内容: 我使用以下代码来序列化从外部服务获得的响应,并作为我的服务的一部分返回json响应。但是,当外部服务返回带有时区(10:30:00.000-05.00)的时间值时,杰克逊会将其转换为15:30:00。如何忽略时区值? 问题答案: 您可以创建自定义解串器 告诉杰克逊使用您的自定义解串器 并像这样使用它: 您可以使用Jackson自定义序列化为服务响应添加时区信息

  • 我有一个这样的对象: 我是否可以使用和我的条件来仅在不为负数的情况下包含该值?或者有没有其他的解决办法我可以做到这一点?

  • 问题内容: 在这个例子中 如果JSON对象缺少属性“ age”, 有人说它不能反序列化。在反序列化期间是否有 注释 可以忽略丢失的字段? 谢谢 问题答案: 我想你想要的是 这就是Jackson 1.x的方式。我认为2.x中有一种新方法。就像是 这些将告诉Jackson仅序列化不为null的值,并且在反序列化缺少的值时不会抱怨。我认为它将只是将其设置为Java默认值。