我需要对两个Monos
执行操作。 困难在于,一个取决于另一个的结果。
让我解释一下:
我有一个Mono<User>
(我是从ServerRequest
得到的; User
是一个POJO)。
我需要能够从上述Mono
中提取用户电子邮件,并将其传递给UserRepository
,以便检查该电子邮件是否已存在于数据库中。
如果用户已经存在,我将抛出一个400
错误;否则,我将保存ServerRequest
中包含的用户。
这是我在handler
中尝试过的内容:
public Mono<ServerResponse> saveUser(ServerRequest serverRequest) {
return serverRequest.bodyToMono(User.class)
.flatMap(user -> userRepository
.findByEmail(user.getEmail())
.flatMap(foundUser -> {
if (foundUser != null) {
System.out.println("found:" + foundUser);
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Email already exists");
} else {
System.out.println("creating" + user);
return status(CREATED).contentType(APPLICATION_JSON).body(userRepository.save(user), User.class);
}
}));
}
User
:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
private Integer id;
@Size(min = 2)
private String firstName;
@Size(min = 2)
private String lastName;
@Email
private String email;
}
UserRepository
:
public interface UserRepository extends ReactiveCrudRepository<User, Long> {
@Query("select id, first_name, last_name, email from user u where u.email = :email")
Mono<User> findByEmail(String email);
}
但是,看来我的订阅存在问题:调用端点时,我的System.out.println
都没有被调用。有人可以帮忙吗?
编辑1 :这是router
,调用上述handler
方法:
@Configuration
public class UserRouter {
@Bean
public RouterFunction<ServerResponse> route(UserHandler userHandler) {
return RouterFunctions.route()
.GET("/api/user", accept(APPLICATION_JSON), userHandler::getUsers)
.POST("/api/sign-up", accept(APPLICATION_JSON), userHandler::saveUser)
.build();
}
}
答案 0 :(得分:2)
这里的问题是,当找不到用户时,您期望为null,但是,在反应式流中null为无效。相反,反应式流具有专用的空状态和专用的运算符来处理空情况。
在您的示例中,您可以执行以下操作:
public Mono<ServerResponse> saveUser(ServerRequest serverRequest)
{
return serverRequest.bodyToMono(User.class)
.flatMap(this::createUserIfNotExists);
}
private Mono<ServerResponse> createUserIfNotExists(User user)
{
return userRepository.findByEmail(user.getEmail())
.hasElement()
.flatMap(foundUser ->
{
if (foundUser)
{
System.out.println("found user");
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Email already exists");
} else
{
System.out.println("creating user");
return status(CREATED).contentType(APPLICATION_JSON)
.body(userRepository.save(user), User.class);
}
});
}
或另一种选择:
public Mono<ServerResponse> saveUser(ServerRequest serverRequest)
{
return serverRequest.bodyToMono(User.class)
.flatMap(this::createUserIfNotExists);
}
private Mono<ServerResponse> createUserIfNotExists(User user)
{
return userRepository.findByEmail(user.getEmail())
.flatMap(foundUser ->
status(BAD_REQUEST)
.contentType(APPLICATION_JSON)
.body(BodyInserters.fromObject("User already exists."))
)
.switchIfEmpty(
userRepository.save(user)
.flatMap(newUser -> status(CREATED).contentType(APPLICATION_JSON)
.body(BodyInserters.fromObject(newUser)))
);
}