我有一个班级,并希望有Optional<T>
这样的值Optional<Integer> value;
。
在这个项目中,Springboot
用于创建Web控制器,客户端通过json
发送/接收。
当客户端发布或发布,并且java
中的解析类具有Optional<T>
类型参数时,它会失败;否则它工作正常。然而; Optional<T>
是首选,因为我们希望客户端能够在不使用字段时省略字段。
例如:
这有效:
public class TestClass {
private final int testValue;
public TestClass(@JsonProperty("testValue") int testValue) {
this.testValue = testValue;
}
public int getTestValue() {
return testValue;
}
}
这不是:
public class TestClass {
private final Optional<Integer> testValue;
public TestClass(@JsonProperty("testValue") Optional<Integer> testValue) {
this.testValue = testValue;
}
public Optional<Integer> getTestValue() {
return testValue;
}
}
以下是Gradle的一些版本行。
springBootVersion = '1.5.8.RELEASE'
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.6.4'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: '2.6.3'
当用Postman POSTing并且值是int
事情工作。当我使用Optional<Integer>
时,我从网络电话获得以下错误响应。
总结如下:
“exception”:“org.springframework.http.converter.HttpMessageNotReadableException”,“message”:“JSON解析错误:0;嵌套异常是com.fasterxml.jackson.databind.JsonMappingException:0(通过引用链:...(我的类) path)... [\“actions \”] - > java.util.ArrayList [3])“,
没有改变任何现有的代码升级杰克逊版本2.8.6
修复它。
我确实按照上面的另一个答案,奇怪的是,升级到更高版本的`2.9.6'不起作用。但它确实给了我一条新的错误消息,最终导致我进入一个其他人也不得不降级的线程。
您需要将第二个示例更改为
public TestClass(@JsonProperty("testValue") int testValue) {
this.testValue = Optional.of(testValue);
}
有一个Jackson模块可以帮助序列化/反序列化Optional
参数。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.9.6</version>
</dependency>
然后使用ObjectMapper
注册模块:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
java.util.Optional不可序列化
可选意味着它不一定有你想要的对象!所以你可以简单地使用包装器。您可以返回对象(如果对象存在),或者如果您的对象不存在,则可以返回404状态。
public static <X> ResponseEntity<X> wrapOrNotFound(Optional<X> maybeResponse, HttpHeaders header) {
return maybeResponse.map(response -> ResponseEntity.ok().headers(header).body(response))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}