我在json中存储RESTful端点的测试数据。我将测试数据反序列化为POJO以传递给REST Assured进行测试。在引擎盖下,REST Assured在构造请求对象时使用Jackson序列化POJO。
我使用Guava数据类型模块来区分json中存在但设置为null的字段和根本不存在的字段。当json使用带有可选字段的guava数据类型模块的jackson反序列化为POJO时,json中缺少的字段在POJO中设置为null,而json中存在的值显式为null的字段设置为null到Optional.absent()。
当Rest Assured(在杰克逊的帮助下)将POJO序列化以构建HTTP Reguest对象时,我希望'缺少'要忽略的字段(在POJO中为null),但是那些存在的字段,但显式设置为null(POJO中的Optional.absent())要序列化。我不能使用@JsonInclude(Include.NON_NULL)注释,因为它排除了两种情况,因为Guava数据类型模块中的Guava数据类型的Serializer处理它们的方式。我想要一种方法来覆盖这种行为,同时保留我使用该模块的能力。我不确定该怎么做。
以下是我所谈论的例子:
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" }
如果我使用@JsonInclude(Include.NON_NULL),我明白了:
{ "description":"Something" }
更新:
所以,我基本上攻击了模块来做我想做的事情。以下是我做的改动:
在GuavaOptionalSerializer
中,我将isEmpty(Optional<?> value)
更改为仅在值为null
时才返回true,而不是null
或absent
。
@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);
}
现在,如果我想要包含absent
字段(明确设置为null
)并排除简单&#39;缺少的字段,我会使用{{1} }。
答案 0 :(得分:2)
不幸的是,看着the source for the serializer,我并没有看到有一种开箱即用的方式去做你正在寻找的东西。 Optional.absent()
只委托默认的空值处理行为,这将遵循@JsonInclude
注释。
这是合理的,因为Optional<>
的整体动机是不应将null
分配给Optional<>
引用。
但是,您始终可以编写自己的序列化程序来为您执行此操作。实现与链接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
}
}