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

Jackson和Guava数据类型模块:忽略缺失的字段,但序列化显式空值

谷出野
2023-03-14

我正在json中存储RESTfulendpoint的测试数据。我将把测试数据反序列化为POJO,以传递给REST保证进行测试。在底层,REST保证在构建请求对象时使用Jackson序列化POJO。

我使用Guava数据类型模块来区分json中存在但设置为null的字段和根本不存在的字段。使用jackson和guava datatype模块将json反序列化为POJO时,json中缺失的字段在POJO中设置为null,而json中存在的值显式设置为null的字段则设置为Optional。缺席()。

当Rest Assured(在Jackson的帮助下)序列化POJO以构造HTTP Reguest对象时,我希望忽略“缺失”字段(POJO中为null),但要序列化存在但显式设置为null(POJO中为可选的.abside())的字段。我不能使用@JsonInclude(Include.NON\u NULL)注释,因为它排除了这两种情况,这是因为Guava数据类型模块中Guava数据类型的序列化程序处理它们的方式。我想要一种方法来覆盖此行为,同时保留我使用模块的能力。我不知道怎么做。

下面是我所说的例子:

public class Item {
    private Optional<Integer> id;
    private Optional<String> name;
    private Optional<String> description;
}

{ "name":null, "description":"Something" }

一旦上面的json String被反序列化,上面的POJO将像这样实例化:

Item: 
    id = null 
    name = Optional.<String>absent()
    description = "Something"

当POJO序列化回json时,我希望输出是测试数据中的输出:

{ "name":null, "description":"Something" }

然而,我得到的是:

{ "id":null, "name":null, "description":"Something" }

如果我使用@Json包括(包括。NON_NULL),我会得到这个:

{ "description":"Something" }

更新:

所以,我基本上是黑客模块做我想做的。以下是我所做的修改:

GuavaOptionalSerializer中,我更改了is空(可选

@Override
public boolean isEmpty(Optional<?> value) {
    return (value == null);
}

在GuavaOptionalBeanPropertyWriter中,我修改了serializeAsField方法,首先处理抑制空值,然后处理null值:

@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception
{                   
    // and then see if we must suppress certain values (default, empty)
    if (_suppressableValue != null) {       
        super.serializeAsField(bean, jgen, prov);
        return;
    }

    if (_nullSerializer == null) {
        Object value = get(bean);   
        if (Optional.absent().equals(value)) {
             return;
         }      
    }

    super.serializeAsField(bean, jgen, prov);
}

现在,如果我想包含不存在的字段(显式设置为null)并排除简单的“缺失”字段,我将使用JsonInclude(include.NON\u EMPTY)注释。


共有1个答案

公冶智刚
2023-03-14

不幸的是,在查看序列化程序的源代码时,我看不到有一种开箱即用的方法来执行您正在寻找的操作。Optional.absent()只是委托给默认的空处理行为,这将尊重@Json容纳注释。

这是合理的,因为整个动机是可选的

但是,您可以编写自己的序列化程序来实现这一点。实现与链接的GuavaOptionalSerializer非常相似,但您需要更改此函数:

@Override
public void serialize(Optional<?> value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonGenerationException {
    if(value.isPresent()){
        provider.defaultSerializeValue(value.get(), jgen);
    } else{
        // provider.defaultSerializeNull(jgen);
        // force writing null here instead of using default
    }
}
 类似资料:
  • 我们最近从Jackson json 2.8.2转移到了2.9.4,我们看到了行为上的重大变化。我们使用的是JDK1.8。 前面,我们在对象映射器级别将序列化包含设置为NON_DEFAULT,所有操作都很正常。 现在,在更改为2.9.2之后,NON_DEFAULT将忽略所有默认值,如boolean false、integer 0、....这破坏了我们的测试用例。 我们的要求是只忽略空字段和空白字段,

  • 问题内容: 我目前正在使用杰克逊2.1.4,并且在将对象转换为JSON字符串时忽略字段时遇到了一些麻烦。 这是我的类,它充当要转换的对象: 这是我如何转换它: 这是输出: 如何避免这些空值?我只想获取“订阅”目的所需的信息! 这正是我要查找的输出: 我还尝试了@JsonInclude(Include.NON_NULL)并将所有变量都设置为null,但是它也不起作用!感谢您的帮助! 问题答案: 您将

  • 下面是我的类,它充当要转换的对象: 下面是我的转换方法: 输出如下: 下面正是我要查找的输出: 我还尝试了@jsonInclude(include.non_null),并将我的所有变量置为null,但也没有起作用!谢谢你们的帮助!

  • 如何告诉 Jackson ObjectMapper 从序列化中忽略特定类型(类)的字段的情况下)? 约束条件: 不控制源类-它是第三方类。 被序列化的类类型是未知的-我猜它取消了MixIn的资格。 此类字段的名称预先未知 为了提供帮助,下面是一个单元测试,期望从序列化中忽略字段和,但它的方法是不正确的,它是按名称而不是按类型过滤它们。

  • 例如: 我知道有jackson注解可以这样做,但是我的字段已经用我的持久性注解进行了注解,所以我想避免重复,因为我已经有了我想忽略的注解的字段

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