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(用户名)可以生成多个项,如果数据库中存在错误数据。感谢您的建议。我还不熟悉反应式编程,所以我不确定写逻辑的好方法是什么。保持简单。