如何正确使用 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()字段的创建方法的解决方案