Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有更好的方法来编写多分支单平面图_Java_Spring Webflux_Reactive - Fatal编程技术网

Java 有没有更好的方法来编写多分支单平面图

Java 有没有更好的方法来编写多分支单平面图,java,spring-webflux,reactive,Java,Spring Webflux,Reactive,非反应式样式代码如下所示: public Response handleRequest(LoginContext ctx) { String username = ctx.getParameterMap().get("username"); String password = ctx.getParameterMap().get("password"); String ipAddr = ctx.getI

非反应式样式代码如下所示:

    public Response handleRequest(LoginContext ctx) {
        String username = ctx.getParameterMap().get("username");
        String password = ctx.getParameterMap().get("password");
        String ipAddr = ctx.getIpAddr();
        if (isIpAddressBlocked(ipAddr)) {
            return new Response("Your ip is blocked");
        }
        List<User> list = userCrudRepository.findByMobile(username);
        if (CollectionUtils.isEmpty(list)) {
            return new Response("User not found");
        }
        if (list.size() > 1) {
            return new Response("Data abnormal, please contact the site administrator");
        }
        User user = list.get(0);
        if (DigestUtils.md5Hex(password).equals(user.getPassword())) {
            doWhenLoginSuccessfully(user);
            return new Response("Login successfully");
        } else {
            return new Response("Username or password error");
        }
    }
    @Autowired
    private UserCrudRepository userCrudRepository;
    
    private Map<String, Boolean> blockedIpMap = new ConcurrentHashMap<>();
    
    private Mono<Boolean> isIpAddressBlocked(String ipAddr) {
        return Mono.just(blockedIpMap.containsKey(ipAddr));
    }
    
    private Mono<Void> doWhenLoginSuccessfully(LoginContext ctx, User user) {
        ctx.getSession().getAttributes().put("loginStatus", 1);
        ctx.getSession().getAttributes().put("userId", user.getId());
        // This method is not finished yet.
        return Mono.just(0).then();
    }
    
    public Mono<Response> handleRequest(LoginContext ctx) {
        String username = ctx.getParameterMap().get("username");
        String password = ctx.getParameterMap().get("password");
        String ipAddr = ctx.getIpAddr();
        return isIpAddressBlocked(ipAddr)
                .filter((x)->x==Boolean.FALSE)
                .flatMapMany((x)->userCrudRepository.findByMobile(username))
                .collectList()
                .flatMap((x)->{
                    if (CollectionUtils.isEmpty(x)) {
                        return Mono.just(new Response("User not found"));
                    } else if (x.size() > 1) {
                        return Mono.just(new Response("Data abnormal, please contact the site administrator"));
                    } else {
                        User user = x.get(0);
                        if (DigestUtils.md5Hex(password).equals(user.getPassword())) {
                            return doWhenLoginSuccessfully(ctx, user)
                                .thenReturn(new Response("Login successfully"));
                        } else {
                            return Mono.just(new Response("Username or password error"));
                        }
                    }
                })
                .switchIfEmpty(Mono.just(new Response("Your ip is blocked")));
    }
公共响应handleRequest(LoginContext ctx){
字符串username=ctx.getParameterMap().get(“用户名”);
字符串password=ctx.getParameterMap().get(“密码”);
字符串ipAddr=ctx.getIpAddr();
如果(isIpAddressBlocked(ipAddr)){
返回新响应(“您的ip被阻止”);
}

List List=usercrudepository.findByMobile(用户名); if(CollectionUtils.isEmpty(列表)){ 返回新响应(“未找到用户”); } 如果(list.size()>1){ 返回新的响应(“数据异常,请联系站点管理员”); } User=list.get(0); if(DigestUtils.md5Hex(password).equals(user.getPassword())){ 道亨登录成功(用户); 返回新响应(“登录成功”); }否则{ 返回新的响应(“用户名或密码错误”); } }
为了将其改写为反应式风格,我将其更改为如下内容:

    public Response handleRequest(LoginContext ctx) {
        String username = ctx.getParameterMap().get("username");
        String password = ctx.getParameterMap().get("password");
        String ipAddr = ctx.getIpAddr();
        if (isIpAddressBlocked(ipAddr)) {
            return new Response("Your ip is blocked");
        }
        List<User> list = userCrudRepository.findByMobile(username);
        if (CollectionUtils.isEmpty(list)) {
            return new Response("User not found");
        }
        if (list.size() > 1) {
            return new Response("Data abnormal, please contact the site administrator");
        }
        User user = list.get(0);
        if (DigestUtils.md5Hex(password).equals(user.getPassword())) {
            doWhenLoginSuccessfully(user);
            return new Response("Login successfully");
        } else {
            return new Response("Username or password error");
        }
    }
    @Autowired
    private UserCrudRepository userCrudRepository;
    
    private Map<String, Boolean> blockedIpMap = new ConcurrentHashMap<>();
    
    private Mono<Boolean> isIpAddressBlocked(String ipAddr) {
        return Mono.just(blockedIpMap.containsKey(ipAddr));
    }
    
    private Mono<Void> doWhenLoginSuccessfully(LoginContext ctx, User user) {
        ctx.getSession().getAttributes().put("loginStatus", 1);
        ctx.getSession().getAttributes().put("userId", user.getId());
        // This method is not finished yet.
        return Mono.just(0).then();
    }
    
    public Mono<Response> handleRequest(LoginContext ctx) {
        String username = ctx.getParameterMap().get("username");
        String password = ctx.getParameterMap().get("password");
        String ipAddr = ctx.getIpAddr();
        return isIpAddressBlocked(ipAddr)
                .filter((x)->x==Boolean.FALSE)
                .flatMapMany((x)->userCrudRepository.findByMobile(username))
                .collectList()
                .flatMap((x)->{
                    if (CollectionUtils.isEmpty(x)) {
                        return Mono.just(new Response("User not found"));
                    } else if (x.size() > 1) {
                        return Mono.just(new Response("Data abnormal, please contact the site administrator"));
                    } else {
                        User user = x.get(0);
                        if (DigestUtils.md5Hex(password).equals(user.getPassword())) {
                            return doWhenLoginSuccessfully(ctx, user)
                                .thenReturn(new Response("Login successfully"));
                        } else {
                            return Mono.just(new Response("Username or password error"));
                        }
                    }
                })
                .switchIfEmpty(Mono.just(new Response("Your ip is blocked")));
    }
@Autowired
私有用户crudepository用户crudepository;
私有映射块edipmap=新的ConcurrentHashMap();
专用IPAddressBlocked(字符串ipAddr){
返回Mono.just(blockedIpMap.containsKey(ipAddr));
}
私有Mono DowhenLogin成功(LoginContext ctx,用户){
getSession().getAttributes().put(“loginStatus”,1);
ctx.getSession().getAttributes().put(“userId”,user.getId());
//这个方法还没有完成。
返回Mono.just(0.then();
}
公共Mono HandlerRequest(LoginContext ctx){
字符串username=ctx.getParameterMap().get(“用户名”);
字符串password=ctx.getParameterMap().get(“密码”);
字符串ipAddr=ctx.getIpAddr();
返回isIpAddressBlocked(ipAddr)
.filter((x)->x==Boolean.FALSE)

.flatMapMany((x)->usercrudepository.findByMobile(用户名)) .LIST() .flatMap((x)->{ if(CollectionUtils.isEmpty(x)){ 返回Mono.just(新响应(“未找到用户”); }如果(x.size()>1),则为else{ 返回Mono.just(新响应(“数据异常,请联系站点管理员”); }否则{ 用户=x.get(0); if(DigestUtils.md5Hex(password).equals(user.getPassword())){ 成功返回DoWhenLogin(ctx,用户) .thenReturn(新响应(“登录成功”); }否则{ 返回Mono.just(新响应(“用户名或密码错误”); } } }) .switchIfEmpty(Mono.just(新响应(“您的ip被阻止”)); }
然而,平面图中的ifs一点也不令人满意

我想知道是否有更好的方法来做到这一点


谢谢你的建议。

这是一个有点基于观点的问题,但这是我将如何做的想法

package com.vob.reactive.webflux.service;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

import static java.util.Arrays.asList;

@Component
@Slf4j
public class CustomService {

    private List<String> blockedIpMap =  asList("127.0.0.1");
    private List<User> users =  asList(
            new User("invalid", DigestUtils.md5Hex("password")),
            new User("invalid", DigestUtils.md5Hex("password1")),
            new User("valid", DigestUtils.md5Hex("password"))
    );

    private Mono<Boolean> isIpAddressBlocked(String ipAddr) {
        return Mono.justOrEmpty(blockedIpMap.stream().filter(ip -> ip.equals(ipAddr)).findFirst())
                .flatMap(c -> Mono.just(true))
                .defaultIfEmpty(false);
    }

    private Mono<Boolean> doWhenLoginSuccessfully(User user) {
        // This method is not finished yet.
        return Mono.just(true);
    }

    public Mono<User> findByMobile(String username, String password) {
        return Flux.fromStream(users.stream().filter(u -> u.username.equals(username)))
                .collectList()
                .flatMap(x -> {
                    if (CollectionUtils.isEmpty(x)) {
                        return Mono.error(new IllegalArgumentException("User not found"));
                    } else if (x.size() > 1) {
                        return Mono.error(new IllegalArgumentException("Data abnormal, please contact the site administrator"));
                    }
                    User user = x.get(0);
                    if (!DigestUtils.md5Hex(password).equals(user.getPassword())) {
                        return Mono.error(new IllegalArgumentException("Username or password error"));
                    }
                    return Mono.just(user);
                });
    }

    public Mono<String> handleRequest(String username, String password,  String ipAddr) {
        return isIpAddressBlocked(ipAddr)
                .flatMap(isBlocked->{
                    if(isBlocked){
                        return Mono.error(new IllegalArgumentException("Your ip is blocked"));
                    }
                    return Mono.just(false);
                })
                .flatMap((x) -> findByMobile(username, password))
                .flatMap(this::doWhenLoginSuccessfully)
                .flatMap(x-> Mono.just("Login successfully"));
    }
    

    @Data
    public class User {
        private final String username;
        private final String password;
    }

}
我喜欢这种方法,因为它将成功和错误分开,然后在控制器中您可以调用服务并将其映射到200 OK或bad request 400

public Mono<Object> handleExample(String username, String password,  String ipAddr){
    return handleRequest(username, password, ipAddr)
            .onErrorMap(err-> // Return Error response)
            .flatMap();
}
publicmono-handleExample(字符串用户名、字符串密码、字符串ipAddr){
返回HandlerRequest(用户名、密码、ipAddr)
.onErrorMap(err->//返回错误响应)
.flatMap();
}

是的,最后你仍然有这个带ifs的平面图,但不幸的是这是你的逻辑。我不太了解您的逻辑,但我更愿意使用用户和密码从数据库中进行选择,这样最终您就可以获得mono。

能否成功地添加DoWhenLogin?以及为什么使用UserCrudepository。findByMobile(loginid)可以返回许多项?请添加您在flux中使用的其他缺少的方法。我发现您的逻辑中存在多个问题,因此请提供我将尝试描述我将如何执行。很抱歉,我仍在重写过程中,因此实际上并非所有方法都已完成。UserCrudepository.findByMobile(用户名)可以生成多个项,如果数据库中存在错误数据。感谢您的建议。我还不熟悉反应式编程,所以我不确定写逻辑的好方法是什么。保持简单。