如何正确使用 Optional 和 `@RequestBody`?
How can I use properly Optional with a `@RequestBody`?
我用的是Spring Boot 2.0.8.RELEASE.
我有一个 @RestController
方法如下所示:
@PostMapping("/message")
public PushMessageResponse sendPush(@Validated @RequestBody PushMessageRequest pushMessageRequest) {
final List<String> sentMessage = pushService.sendMessage(pushMessageRequest);
return new PushMessageResponse(sentMessage);
}
我有一个 PushMessageRequest
class 看起来像这样:
@RequiredArgsConstructor
@Data
public class PushMessageRequest {
private final Optional<UUID> clientId;
private final Optional<String> token;
private final Optional<String> text;
private final Optional<PushOptions> pushOptions;
@NotBlank
private final String appName;
}
并且如果我向该方法发送一个请求,其正文不包含某些 属性,我会看到那种 属性(那些我没有在 JSON 请求)是 null.
我已经尝试添加这样的配置:
@Configuration
public class JacksonConfiguration {
@Bean
public Module jdk8Module() {
return new Jdk8Module();
}
}
我期望看到我的 DTO 的可选 属性 不是 null 但这样的 属性 的值为 Optional.empty()
.
这里为什么要用Optional
。您可以简单地使用常规 classes,并使用 Optional.ofNullable()
在您的控制器 class.
中创建 Optional
个对象
Optional
API 主要用于 return 可能为空的值的方法,而不是传输数据。例如,您可以将消息 class 写为:
public class PushMessageRequest {
private UUID clientId;
...
}
并且在您的控制器中 class,您可以调用:
@PostMapping("/message")
public PushMessageResponse sendPush(@Validated @RequestBody PushMessageRequest pushMessageRequest) {
Optional<UUID> uuidOptional = Optional.ofNullable(pushMessageRequest.getUUID());
...
}
有关为什么不应在已序列化的 class 中使用 Optional
的更详细说明,请参阅:Why java.util.Optional is not Serializable, how to serialize the object with such fields。尽管这专门针对标准 Java 序列化,但推理也适用于 JSON 序列化。
根据@cameron1024、@AmanGarg、@RavindraRanwala 的说法,我不应该将 Optional 用作字段,因为它不打算这样做。
我选择returnOptional#ofNullable()
字段的创建方法的解决方案
我用的是Spring Boot 2.0.8.RELEASE.
我有一个 @RestController
方法如下所示:
@PostMapping("/message")
public PushMessageResponse sendPush(@Validated @RequestBody PushMessageRequest pushMessageRequest) {
final List<String> sentMessage = pushService.sendMessage(pushMessageRequest);
return new PushMessageResponse(sentMessage);
}
我有一个 PushMessageRequest
class 看起来像这样:
@RequiredArgsConstructor
@Data
public class PushMessageRequest {
private final Optional<UUID> clientId;
private final Optional<String> token;
private final Optional<String> text;
private final Optional<PushOptions> pushOptions;
@NotBlank
private final String appName;
}
并且如果我向该方法发送一个请求,其正文不包含某些 属性,我会看到那种 属性(那些我没有在 JSON 请求)是 null.
我已经尝试添加这样的配置:
@Configuration
public class JacksonConfiguration {
@Bean
public Module jdk8Module() {
return new Jdk8Module();
}
}
我期望看到我的 DTO 的可选 属性 不是 null 但这样的 属性 的值为 Optional.empty()
.
这里为什么要用Optional
。您可以简单地使用常规 classes,并使用 Optional.ofNullable()
在您的控制器 class.
Optional
个对象
Optional
API 主要用于 return 可能为空的值的方法,而不是传输数据。例如,您可以将消息 class 写为:
public class PushMessageRequest {
private UUID clientId;
...
}
并且在您的控制器中 class,您可以调用:
@PostMapping("/message")
public PushMessageResponse sendPush(@Validated @RequestBody PushMessageRequest pushMessageRequest) {
Optional<UUID> uuidOptional = Optional.ofNullable(pushMessageRequest.getUUID());
...
}
有关为什么不应在已序列化的 class 中使用 Optional
的更详细说明,请参阅:Why java.util.Optional is not Serializable, how to serialize the object with such fields。尽管这专门针对标准 Java 序列化,但推理也适用于 JSON 序列化。
根据@cameron1024、@AmanGarg、@RavindraRanwala 的说法,我不应该将 Optional 用作字段,因为它不打算这样做。
我选择returnOptional#ofNullable()
字段的创建方法的解决方案