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

如何让Jackson序列化程序在所需属性为空时失败

夏烨霖
2023-03-14

我希望Jackson JSON序列化程序在遇到空属性时失败。

我知道我可以告诉它省略空字段(mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL))。但是,另外我想声明

@NotNull // BeanValidation
private String foo;

@JsonProperty(required = true) // Jackson databinding
private String foo;

共有1个答案

戚永福
2023-03-14

我没有看到任何注释或配置选项。可以使用Hibernate验证程序在序列化之前验证对象。由于您不想添加自定义批注,因此可以通过在序列化之前验证对象来修改默认序列化程序。

首先创建一个自定义序列化程序,该序列化程序将另一个序列化程序作为构造函数参数,并使用Hibernate验证程序来验证对象并引发异常。

class ValidatingSerializer extends JsonSerializer<Object> {
    private final JsonSerializer<Object> defaultSerializer;
    private final Validator validator;

    ValidatingSerializer(final JsonSerializer<Object> defaultSerializer) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        this.validator = factory.getValidator();
        this.defaultSerializer = defaultSerializer;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider)
            throws IOException {
        if (!validator.validate(value).isEmpty()) {
            throw new IOException("Null value encountered");
        }
        defaultSerializer.serialize(value, gen, provider);
    }
}

然后创建将使用此序列化的序列化程序修饰符:

class ValidatingSerializerModifier extends BeanSerializerModifier {
    @Override
    public JsonSerializer<?> modifySerializer(SerializationConfig config,
             BeanDescription beanDesc, JsonSerializer<?> serializer) {
        return new ValidatingSerializer((JsonSerializer<Object>) serializer);
    }
}

最后,在<code>ObjectMapper</code>上使用<code>SimpleModule</code>注册此项:

SimpleModule module = new SimpleModule();
module.setSerializerModifier(new ValidatingSerializerModifier());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
@NotNull // BeanValidation
private String foo;
 类似资料:
  • 问题内容: 使用Jackson 2,我正在寻找一种 通用的 方式将对象序列化为单个值(然后序列化它们,然后再填充该单个字段),而不必重复创建JsonSerializer / JsonDeserializer来处理每种情况。@JsonIdentityInfo批注非常接近,但由于我知道,它将始终对完整的子对象进行序列化,因此略微遗漏了该标记。 这是我想做的一个例子。给定的类: 我希望Order可以序列

  • 我们有一张350列的桌子。pojo类被生成,getter命令被打乱。试图使用jackson提供的csvmapper,但它会根据getter顺序生成csv@JsonPropertyOrder也不适合使用,因为有很多列。我们用xml维护列顺序,并且可以在运行时生成字段顺序数组。我们可以在运行时重写以提供属性排序的字段名数组吗?我们可以使用注释内省器进行自定义吗?

  • 希, 我所拥有的: 公开课myPojo 我想要的是,如果Map中的一个字段不满足POJO,则使从Map到POJO的转换失败(抛出异常)。 它似乎不能使用DeserializationFeature进行任何类型的配置。我试图调整所有与空字段有关的配置

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

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

  • 鉴于这种反应: 我怎样才能将数据属性反序列化为像这样的 MapDTO 我已经尝试使用自定义反序列化器,但是按名称获取所有属性,然后基于这些属性和嵌套对象创建一个新的MapDTO对象看起来很麻烦。如果结构发生变化,我必须更改反序列化器和DTO本身。让Jackson从给定的根开始进行反序列化会更容易。我使用Jackson 2.12.4到ResAs的4.4.0。我想避免创建不必要的包装类。