简体   繁体   中英

How can I use properly Optional with a `@RequestBody`?

I use the Spring Boot 2.0.8.RELEASE.

I have a @RestController method looks like this:

    @PostMapping("/message")
    public PushMessageResponse sendPush(@Validated @RequestBody PushMessageRequest pushMessageRequest) {
        final List<String> sentMessage = pushService.sendMessage(pushMessageRequest);

        return new PushMessageResponse(sentMessage);
    }

And I have a PushMessageRequest class that looks like this:

@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;

}

And If I send a request to this method with a body that doesn't contain some property I see that that kind of property(those that I didn't pass in the JSON request) is null .

I've already tried to add such configuration:

@Configuration
public class JacksonConfiguration {

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

I have expected to see that the Optional property of my DTO isn't null but such property has a value of Optional.empty() .

According to @cameron1024, @AmanGarg, @RavindraRanwala I shouldn't use Optional as a field, because it is not intended to.

I choose the solution of creating methods that return Optional#ofNullable() of the field.

Why do you want to use Optional here. You can simply use regular classes, and use Optional.ofNullable() to create Optional objects inside your controller class.

The Optional API was primarily intended to be used for methods that return a value that may be null, rather than transmitting data. For example, you can write your message class as:

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

and in your controller class, you can call:

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

For a more detailed explanation of why you should not use Optional in a class that is serialized, refer to: Why java.util.Optional is not Serializable, how to serialize the object with such fields . Although this refers specifically to standard Java serialization, the reasoning applies to JSON serialization as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM