如何在`@ RequestBody`中正确使用Optional?

时间:2019-08-08 08:32:45

标签: java spring-boot spring-mvc jackson optional

我使用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类,看起来像这样:

@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请求中传递的那些属性)为

我已经尝试添加这样的配置:

@Configuration
public class JacksonConfiguration {

    @Bean
    public Module jdk8Module() {
        return new Jdk8Module();
    }
}

我期望看到我的DTO的Optional属性不是 null ,但是该属性的值为Optional.empty()

2 个答案:

答案 0 :(得分:0)

您为什么要在这里使用Optional。您可以简单地使用常规类,并使用Optional.ofNullable()在控制器类中创建Optional对象。

Optional API最初旨在用于返回可能为空值的方法,而不是传输数据。例如,您可以将消息类编写为:

public class PushMessageRequest {
    private UUID clientId;
    ...
}

在您的控制器类中,您可以调用:

@PostMapping("/message")
public PushMessageResponse sendPush(@Validated @RequestBody PushMessageRequest pushMessageRequest) {
    Optional<UUID> uuidOptional = Optional.ofNullable(pushMessageRequest.getUUID());
    ...
}

有关为何不应该在已序列化的类中使用Optional的详细说明,请参见:Why java.util.Optional is not Serializable, how to serialize the object with such fields。尽管这特别是指标准Java序列化,但是推理也适用于JSON序列化。

答案 1 :(得分:-1)

根据@ cameron1024,@ AmanGarg,@ RavindraRanwala,我不应该将Optional用作字段,因为它不是故意的。

我选择创建返回该字段的Optional#ofNullable()的方法的解决方案。