简体   繁体   English

Spring Webflux非阻塞响应

[英]Spring webflux non-blocking response

I have a request method that use 'username' and 'password' body parameters to find real user from database, validate it by using request password and if everything is fine - return generated token as String. 我有一个请求方法,该方法使用“用户名”和“密码”主体参数从数据库中查找真实用户,并使用请求密码进行验证,如果一切正常,则将生成的令牌作为String返回。

public Mono<ServerResponse> handleLogin(ServerRequest request) {
    User body = request.bodyToMono(User.class).block();
    return userRepository.findById(body.getUsername())
            .filter(user -> passwordEncoder.matches(body.getPassword(), user.getPassword()))
            .flatMap(user -> ServerResponse.ok().body(Mono.just(tokens.store(user)), String.class))
            .switchIfEmpty(ServerResponse.badRequest().build());
}

This method works fine, but i'm trying to make it as non-blocking and i'm not sure how to achieve it. 这种方法效果很好,但是我正在尝试使其成为非阻塞性的,并且我不确定如何实现。 Any help appreciated. 任何帮助表示赞赏。

Updated 更新

For now i changed my method content to 现在我将方法内容更改为

    return request.bodyToMono(User.class)
            .flatMap(body -> userRepository.findById(body.getUsername()).flatMap(user -> Mono.just(new Object[]{body.getPassword(), user})))
            .filter(obj -> {
                User user = (User) obj[1];
                return user.isActive() && passwordEncoder.matches((CharSequence) obj[0], user.getPassword());
            })
            .flatMap(obj -> {
                User user = (User) obj[1];
                return ServerResponse.ok().body(Mono.just(tokens.store(user)), String.class);
            })
            .switchIfEmpty(ServerResponse.badRequest().build());

This is non-blocking, but looks like not so elegant solution. 这是非阻塞的,但看起来并不是那么优雅的解决方案。 Can it be improved/simplified somehow? 可以通过某种方式对其进行改进/简化吗?

Remember 记得

1) Everything is stream. 1)一切都是流。

2) Keep your flow composed 2)保持流程顺畅

3) No blocking operation at all. 3)完全没有阻塞操作。

Solution

So, keep your flow composed without blocking operation 因此,保持流程顺畅而不会阻塞操作

public Mono<ServerResponse> handleLogin(ServerRequest request) {

    return request.bodyToMono(User.class)
                  .flatMap(body -> userRepository.findById(body.getUsername())
                  .filter(user -> passwordEncoder.matches(body.getPassword(), user.getPassword()))
                  .flatMap(user -> ServerResponse.ok().body(Mono.just(tokens.store(user)), String.class))
                  .switchIfEmpty(ServerResponse.badRequest().build());
}

Regarding the last update 关于最近的更新

Regarding the last update, from my point of view, the code might be optimized in a next way: 在我看来,关于最后一次更新,可以通过以下方式优化代码:

return request.bodyToMono(User.class)
            .flatMap(body -> userRepository.findById(body.getUsername())                              
                                           .filter(user -> user.isActive())
                                           .filter(user -> passwordEncoder.matches(body.getPassword(), user.getPassword()))
            )
            .flatMap(user -> ServerResponse.ok().syncBody(tokens.store(user)))
            .switchIfEmpty(ServerResponse.badRequest().build());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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