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

如何跳过可选项。Jackson序列化期间是否有空字段?

有品
2023-03-14

我有一个带有可选字段的Java类。我正在使用Jackson 2.8.3(从SpringWeb4.3.3调用)将类序列化为JSON。

如果可选为空,我希望让序列化程序跳过该字段,如果存在则序列化包含的字符串。我正在寻找的结果示例,其中包含两个对象的列表:

[
    {
        "id": 1,
        "foo": "bar"
    },
    {
        "id": 2,
    }
]

这里,对于id为2的对象,foo选项为空。

相反,我得到的是:

[
    {
        "id": 1,
        "foo": {
            "present": true
        }
    },
    {
        "id": 2,
        "foo": {
            "present": false
        }
    }
]

这就是结果,即使我在类中注释“bar”字段,如

@JsonInclude(JsonInclude.Include.NON_ABSENT)
public Optional<String> getFoo() { ...

有没有什么方法可以使用Jackson注释或自定义序列化程序实现像第一个列表这样的结果?

共有3个答案

澹台欣怿
2023-03-14

根据需要使用JsonSerializer。

类似这样(半伪):

public class MySer extends JsonSerializer<Opional<?>> {

        @Override
        public void serialize(Optional<?> optString, JsonGenerator generator, SerializerProvider provider)
                                          throws IOException, JsonProcessingException {
        //Check Optional here...        
        generator.writeString(/* DO SOMETHING HERE WHATEVER */);
    }

//然后在您的模型中:

public class ClassWhatever {           
    @JsonSerialize(using = MySer .class)
    public Optional<String> getFoo() { ...
 }

为了避免使用@JsonSerialize-注释每个字段,您可以使用以下命令将自定义序列化程序注册到对象映射器

  ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addSerializer(new MyCustomSerializer()); // assuming serializer declares correct class to bind to
mapper.registerModule(testModule);

此外,给定的解决方案仅适用于序列化。除非编写自己的反序列化程序,否则反序列化将失败。然后,您需要使用JsonDeserializ注释每个字段,或者注册自定义反序列化器。

杨志强
2023-03-14

您可以使用objectMapper。registerModule(新Jdk8Module()) 但它使用空值序列化。

但您仍然希望从JSON中删除空值,请使用以下代码:

objectMapper.registerModule(new Jdk8Module().configureAbsentsAsNulls(true));
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
朱阳曜
2023-03-14

无需编写自定义序列化程序。用@JsonInclude(JsonInclude.Include.NON\u缺席)注释类

您还需要:

  • 包括com。fasterxml。杰克逊。数据类型:jackson-datatype-jdk8作为您的依赖项
  • 并向对象映射器注册相应的模块:<代码>对象映射器。registerModule(新Jdk8Module())
 类似资料:
  • 所以我有 我读过Baeldung的文章和其他东西,但似乎我的选项是自定义类型(这是一个原始类型)或全局类型。如何实现这种自定义序列化?

  • 问题内容: 在反序列化过程中(据我了解,这是将JSON数据转换为Java对象的过程),我如何告诉Jackson,当它读取不包含数据的对象时,应该忽略它吗? 我正在使用Jackson 2.6.6和Spring 4.2.6 我的控制器收到的JSON数据如下: 问题是对象“ containedObject”按原样解释,并且正在实例化。因此,控制器读取此JSON数据后,它将立即生成ContainedObj

  • 使用Jackson将JSON响应反序列化为DTO。 使用Gson或Jackson反序列化JSON时忽略空字段 他们仍然从那个不规则的JSON对象创建一个对象。 这意味着我需要遍历这个列表,并通过实现一个清理方法删除所有不具有属性“value”的对象。 我的带有Jackson注释的DTO: 给定JSON响应的结果是初始化了3个DTOs,而不是4个。

  • 在我们的项目(springMVC)Rest API项目中,我希望只对请求和响应使用一个模型(以避免添加大量代码将字段从一个对象复制到另一个对象) 我想用昂首阔步来处理所有的医生,但我遇到了一个小问题。例如,假设我有一个模型用户 和一个简单的控制器 现在,我希望swagger在反序列化时隐藏属性密码,而不是序列化(因此,在输入时显示它,但在输出时显示它),在Id字段中则相反。 我尝试使用@jsoni

  • 问题内容: 如果该字段的值为null,如何配置Jackson在序列化期间忽略该字段的值。 例如: 问题答案: 要使用抑制具有空值的序列化属性,可以直接配置或使用批注: 要么: 或者,你可以在中使用,以便在值不为时显示属性。

  • 我已经找了很多但仍然没有得到答案到目前为止,任何帮助是非常感谢! 我有一个简单的到字段映射,并尝试将JSON字符串读取到Java对象。 例外情况: java.lang.IllegalArgumentException:无法解析日期值“null”(格式:“dd-mmm-yyyy”):不可解析日期:“null”com.fasterxml.jackson.databind.deser.std.dateD