asi*_*ira 50 java jackson java-8
我试图使用Jackson将类值写入JSON,其中包含Optional作为字段:
public class Test {
Optional<String> field = Optional.of("hello, world!");
public Optional<String> getField() {
return field;
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(new Test()));
}
}
Run Code Online (Sandbox Code Playgroud)
执行时,此类生成以下输出:
{"field":{"present":true}}
Run Code Online (Sandbox Code Playgroud)
我理解当前/不存在的字段被包含在内并且可以在读取JSON数据时解决它,但是我无法解决可选的实际内容永远不会写入输出的事实.:(
除了不使用ObjectMapper之外,这里有任何变通方法吗?
Jon*_*nas 59
您可以使用jackson-datatype-jdk8,其描述如下:
支持新的JDK8特定类型,例如Optional
Sot*_*lis 13
该Optional班有一个value领域,但它没有标准的getter/setter.默认情况下,杰克逊寻找getter/setter来查找类属性.
您可以添加自定义Mixin以将该字段标识为属性
final class OptionalMixin {
private Mixin(){}
@JsonProperty
private Object value;
}
Run Code Online (Sandbox Code Playgroud)
并将其注册到您的ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Optional.class, OptionalMixin.class);
Run Code Online (Sandbox Code Playgroud)
您现在可以序列化您的对象.
System.out.println(mapper.writeValueAsString(new Test()));
Run Code Online (Sandbox Code Playgroud)
将打印
{"field":{"value":"hello, world!","present":true}}
Run Code Online (Sandbox Code Playgroud)
考虑一下jackson-datatype-guava.有一个杰克逊Module实施的番石榴类型,包括他们的Optional.它可能比我上面所示的更完整.
类似于@Manikandan的回答,但是添加@JsonProperty到私有字段而不是getter,所以你不要在公共api上公开你的工作.
public class Test {
@JsonProperty("field")
private String field;
@JsonIgnore
public Optional<String> getField() {
return Optional.of(field); // or Optional.ofNullable(field);
}
}
Run Code Online (Sandbox Code Playgroud)
您只需要注册module Jdk8Module。然后,它将序列化任何序列Optional<T>,就T好像它是否存在一样null。
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jdk8Module());
Run Code Online (Sandbox Code Playgroud)
让我们Test稍微修改一下类,以便测试一个Optional.empty()值。这与Test序列化时的原始类相似,因为对象映射器正在寻找getter(因为该字段是private)。但是,使用原始Test类也可以。
class Test {
private final String field;
public Test(String field) {
this.field = field;
}
public Optional<String> getField() {
return Optional.ofNullable(field);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在我们的主要班级:
Test testFieldNull = new Test(null);
Test testFieldNotNull = new Test("foo");
// output: {"field":null}
System.out.println(objectMapper.writeValueAsString(testFieldNull));
// output: {"field":"foo"}
System.out.println(objectMapper.writeValueAsString(testFieldNotNull));
Run Code Online (Sandbox Code Playgroud)
尝试将选项传递到@JsonInclude注释中。
例如,如果您不想显示field值何时为null。您可能需要使用 Jackson-Modules >2.8.5。
import com.fasterxml.jackson.annotation.JsonInclude;
public class Test {
@JsonInclude(JsonInclude.Include.NON_NULL)
Optional<String> field;
}
Run Code Online (Sandbox Code Playgroud)