diff --git a/src/main/java/ink/wgink/gateway/annoation/CheckBooleanAnnotation.java b/src/main/java/ink/wgink/gateway/annoation/CheckBooleanAnnotation.java new file mode 100644 index 0000000..e549b66 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/annoation/CheckBooleanAnnotation.java @@ -0,0 +1,18 @@ +package ink.wgink.gateway.annoation; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: CheckBooleanAnnotation + * @Description: TODO + * @Author: WangGeng + * @Date: 2019/11/14 14:50 + * @Version: 1.0 + **/ +public @interface CheckBooleanAnnotation { + + String name(); + + String[] types() default {}; +} diff --git a/src/main/java/ink/wgink/gateway/annoation/CheckEmptyAnnotation.java b/src/main/java/ink/wgink/gateway/annoation/CheckEmptyAnnotation.java new file mode 100644 index 0000000..90ca4a3 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/annoation/CheckEmptyAnnotation.java @@ -0,0 +1,28 @@ +package ink.wgink.gateway.annoation; + +import java.lang.annotation.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: CheckEmptyAnnotation + * @Description: 校验空 + * @Author: WangGeng + * @Date: 2019/11/14 14:05 + * @Version: 1.0 + **/ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface CheckEmptyAnnotation { + + String name(); + + String[] types() default {}; + + String verifyType() default ""; + + String regex() default ""; + +} diff --git a/src/main/java/ink/wgink/gateway/annoation/CheckListAnnotation.java b/src/main/java/ink/wgink/gateway/annoation/CheckListAnnotation.java new file mode 100644 index 0000000..344b339 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/annoation/CheckListAnnotation.java @@ -0,0 +1,22 @@ +package ink.wgink.gateway.annoation; + +import java.lang.annotation.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: CheckListAnnotation + * @Description: 校验List + * @Author: WangGeng + * @Date: 2019/11/15 14:39 + * @Version: 1.0 + **/ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface CheckListAnnotation { + + String name(); + +} diff --git a/src/main/java/ink/wgink/gateway/annoation/CheckNullAnnotation.java b/src/main/java/ink/wgink/gateway/annoation/CheckNullAnnotation.java new file mode 100644 index 0000000..2d06ce1 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/annoation/CheckNullAnnotation.java @@ -0,0 +1,23 @@ +package ink.wgink.gateway.annoation; + +import java.lang.annotation.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: CheckNullAnno + * @Description: 字段为空校验 + * @Author: WangGeng + * @Date: 2019/11/14 11:31 + * @Version: 1.0 + **/ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface CheckNullAnnotation { + + String name(); + + String[] types() default {}; +} diff --git a/src/main/java/ink/wgink/gateway/annoation/CheckNumberAnnotation.java b/src/main/java/ink/wgink/gateway/annoation/CheckNumberAnnotation.java new file mode 100644 index 0000000..16ffb08 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/annoation/CheckNumberAnnotation.java @@ -0,0 +1,28 @@ +package ink.wgink.gateway.annoation; + +import java.lang.annotation.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: CheckNumberAnnotation + * @Description: 字段为数字校验 + * @Author: WangGeng + * @Date: 2019/11/14 11:31 + * @Version: 1.0 + **/ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface CheckNumberAnnotation { + + String name(); + + String[] types() default {}; + + double max() default Integer.MAX_VALUE; + + double min() default Integer.MIN_VALUE; + +} diff --git a/src/main/java/ink/wgink/gateway/component/MongoRouteDefinitionRepository.java b/src/main/java/ink/wgink/gateway/component/MongoRouteDefinitionRepository.java index 27a3191..bcbf1b2 100644 --- a/src/main/java/ink/wgink/gateway/component/MongoRouteDefinitionRepository.java +++ b/src/main/java/ink/wgink/gateway/component/MongoRouteDefinitionRepository.java @@ -1,11 +1,16 @@ package ink.wgink.gateway.component; +import ink.wgink.gateway.consts.ISystemConst; import ink.wgink.gateway.dao.route.IRouteDao; import ink.wgink.gateway.handler.route.RouteHandler; +import ink.wgink.gateway.pojo.route.Route; import ink.wgink.gateway.util.UUIDUtil; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.*; +import org.springframework.cloud.gateway.filter.FilterDefinition; +import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory; import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; +import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory; import org.springframework.cloud.gateway.route.RouteDefinition; import org.springframework.cloud.gateway.route.RouteDefinitionRepository; import org.springframework.cloud.gateway.route.RouteLocator; @@ -35,15 +40,15 @@ import java.util.Map; @Component public class MongoRouteDefinitionRepository implements RouteDefinitionRepository { - public RouteHandler routeHandler; + public IRouteDao routeDao; - public MongoRouteDefinitionRepository(RouteHandler routeHandler) { - this.routeHandler = routeHandler; + public MongoRouteDefinitionRepository(IRouteDao routeDao) { + this.routeDao = routeDao; } @Override public Flux getRouteDefinitions() { - return routeHandler.routeDefinitionFlux(); + return this.routeDefinitionFlux(); } @Override @@ -55,4 +60,62 @@ public class MongoRouteDefinitionRepository implements RouteDefinitionRepository public Mono delete(Mono routeId) { return null; } + + /** + * 路由定义 + * + * @return + */ + private Flux routeDefinitionFlux() { + return routeDao.findAll().flatMap(route -> { + // 定义路由 + RouteDefinition routeDefinition = new RouteDefinition(); + routeDefinition.setId(UUIDUtil.getUUID()); + routeDefinition.setUri(UriComponentsBuilder.fromUriString(route.getUri()).build().toUri()); + routeDefinition.setPredicates(this.listPredicateDefinition(route)); + // 过滤器 + routeDefinition.setFilters(this.listFilterDefinition(route)); + return Flux.just(routeDefinition); + }); + } + + /** + * 路由断言列表 + * + * @param route + * @return + */ + private List listPredicateDefinition(Route route) { + // 定义断言 + List predicateDefinitions = new ArrayList<>(); + // 路由断言 + PredicateDefinition pathPredicateDefinition = new PredicateDefinition(); + Map pathPredicateDefinitionMap = new HashMap<>(2); + pathPredicateDefinitionMap.put(RoutePredicateFactory.PATTERN_KEY, ISystemConst.ROUTE_PREFIX + route.getPath()); + pathPredicateDefinition.setName("Path"); + pathPredicateDefinition.setArgs(pathPredicateDefinitionMap); + // 添加路由断言 + predicateDefinitions.add(pathPredicateDefinition); + return predicateDefinitions; + } + + /** + * 过滤器列表 + * + * @return + */ + private List listFilterDefinition(Route route) { + // 定义过滤器 + List filterDefinitions = new ArrayList<>(); + FilterDefinition rewritePathFilterDefinition = new FilterDefinition(); + Map rewritePathFilterDefinitionMap = new HashMap<>(2); + rewritePathFilterDefinitionMap.put(RewritePathGatewayFilterFactory.REGEXP_KEY, ISystemConst.ROUTE_PREFIX + "/?(?.*)"); + rewritePathFilterDefinitionMap.put(RewritePathGatewayFilterFactory.REPLACEMENT_KEY, "/$\\{segment}"); + rewritePathFilterDefinition.setArgs(rewritePathFilterDefinitionMap); + rewritePathFilterDefinition.setName("RewritePath"); + // 添加重写过滤 + filterDefinitions.add(rewritePathFilterDefinition); + return filterDefinitions; + } + } diff --git a/src/main/java/ink/wgink/gateway/consts/ISystemConst.java b/src/main/java/ink/wgink/gateway/consts/ISystemConst.java index 622c060..2d9c9ca 100644 --- a/src/main/java/ink/wgink/gateway/consts/ISystemConst.java +++ b/src/main/java/ink/wgink/gateway/consts/ISystemConst.java @@ -13,7 +13,12 @@ package ink.wgink.gateway.consts; public interface ISystemConst { String UUID = "uuid"; - String COUNT = "count"; + String SESSION_USER = "SESSION_USER"; + String USER_ADMIN_USERNAME = "admin"; + String USER_ADMIN_PASSWORD = "aaa111!!!"; + String ADMIN_ROUTER_PREFIX = "/wg"; + String PAGE_LOGIN = "/wg/login.html"; + String ROUTE_PREFIX = "/gw"; } diff --git a/src/main/java/ink/wgink/gateway/enums/ErrorResultCodeEnum.java b/src/main/java/ink/wgink/gateway/enums/ErrorResultCodeEnum.java new file mode 100644 index 0000000..16f9b68 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/enums/ErrorResultCodeEnum.java @@ -0,0 +1,49 @@ +package ink.wgink.gateway.enums; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: ErrorResultCodeEnum + * @Description: 错误类型枚举 + * @Author: wanggeng + * @Date: 2021/4/23 3:27 下午 + * @Version: 1.0 + */ +public enum ErrorResultCodeEnum { + + /** + * 错误类型 + */ + SYSTEM_ERROR(40001), + ENCODE_ERROR(40002), + DECODE_ERROR(40003), + APP_DEPENDENCY_ERROR(40004), + PROPERTIES_ERROR(40005), + TEXT_ILLEGAL(40101), + PARAMS_ERROR(40102), + QUERY_ERROR(40101), + SAVE_ERROR(40102), + UPDATE_ERROR(40103), + REMOVE_ERROR(40104), + FILE_ERROR(40401), + TEST_ERROR(40201), + LOGIN_OUT(40301), + TOKEN_ERROR(40302), + USERNAME_PASSWORD_ERROR(40303), + USER_EXIST(40304), + PERMISSION_ERROR(40401), + DEVICE_ERROR(40501), + DEVICE_VERSION_ERROR(40502); + + private int value; + + ErrorResultCodeEnum(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + +} diff --git a/src/main/java/ink/wgink/gateway/exception/ParamsException.java b/src/main/java/ink/wgink/gateway/exception/ParamsException.java new file mode 100644 index 0000000..bdd36bc --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/ParamsException.java @@ -0,0 +1,32 @@ +package ink.wgink.gateway.exception; + + +/** + * @ClassName: ParamsException + * @Description: 参数异常 + * @Author: WangGeng + * @Date: 2019/2/26 3:53 PM + * @Version: 1.0 + **/ +public class ParamsException extends SystemException { + + public ParamsException() { + super(); + } + + public ParamsException(String message) { + super(message); + } + + public ParamsException(String message, Throwable cause) { + super(message, cause); + } + + public ParamsException(Throwable cause) { + super(cause); + } + + protected ParamsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/PropertiesException.java b/src/main/java/ink/wgink/gateway/exception/PropertiesException.java new file mode 100644 index 0000000..67b7839 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/PropertiesException.java @@ -0,0 +1,34 @@ +package ink.wgink.gateway.exception; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: PropertiesException + * @Description: 属性异常 + * @Author: wanggeng + * @Date: 2021/4/8 5:22 下午 + * @Version: 1.0 + */ +public class PropertiesException extends SystemException { + + public PropertiesException() { + super(); + } + + public PropertiesException(String message) { + super(message); + } + + public PropertiesException(String message, Throwable cause) { + super(message, cause); + } + + public PropertiesException(Throwable cause) { + super(cause); + } + + protected PropertiesException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/RemoveException.java b/src/main/java/ink/wgink/gateway/exception/RemoveException.java new file mode 100644 index 0000000..9ed2bcf --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/RemoveException.java @@ -0,0 +1,32 @@ +package ink.wgink.gateway.exception; + + +/** + * @ClassName: RemoveException + * @Description: 删除异常 + * @Author: WangGeng + * @Date: 2019/2/26 5:26 PM + * @Version: 1.0 + **/ +public class RemoveException extends SystemException { + + public RemoveException() { + super(); + } + + public RemoveException(String message) { + super(message); + } + + public RemoveException(String message, Throwable cause) { + super(message, cause); + } + + public RemoveException(Throwable cause) { + super(cause); + } + + protected RemoveException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/SaveException.java b/src/main/java/ink/wgink/gateway/exception/SaveException.java new file mode 100644 index 0000000..95fe1fa --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/SaveException.java @@ -0,0 +1,32 @@ +package ink.wgink.gateway.exception; + + +/** + * @ClassName: SaveException + * @Description: 新增异常 + * @Author: WangGeng + * @Date: 2019/2/26 5:24 PM + * @Version: 1.0 + **/ +public class SaveException extends SystemException { + + public SaveException() { + super(); + } + + public SaveException(String message) { + super(message); + } + + public SaveException(String message, Throwable cause) { + super(message, cause); + } + + public SaveException(Throwable cause) { + super(cause); + } + + protected SaveException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/SearchException.java b/src/main/java/ink/wgink/gateway/exception/SearchException.java new file mode 100644 index 0000000..51dca98 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/SearchException.java @@ -0,0 +1,32 @@ +package ink.wgink.gateway.exception; + + +/** + * @ClassName: SearchException + * @Description: 查询异常 + * @Author: WangGeng + * @Date: 2019/2/26 5:26 PM + * @Version: 1.0 + **/ +public class SearchException extends SystemException { + + public SearchException() { + super(); + } + + public SearchException(String message) { + super(message); + } + + public SearchException(String message, Throwable cause) { + super(message, cause); + } + + public SearchException(Throwable cause) { + super(cause); + } + + protected SearchException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/SignException.java b/src/main/java/ink/wgink/gateway/exception/SignException.java new file mode 100644 index 0000000..74ac34b --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/SignException.java @@ -0,0 +1,33 @@ +package ink.wgink.gateway.exception; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: SignException + * @Description: 登录、出异常 + * @Author: wanggeng + * @Date: 2021/4/23 3:08 下午 + * @Version: 1.0 + */ +public class SignException extends SystemException { + + public SignException() { + } + + public SignException(String message) { + super(message); + } + + public SignException(String message, Throwable cause) { + super(message, cause); + } + + public SignException(Throwable cause) { + super(cause); + } + + public SignException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/SystemException.java b/src/main/java/ink/wgink/gateway/exception/SystemException.java new file mode 100644 index 0000000..807a35b --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/SystemException.java @@ -0,0 +1,34 @@ +package ink.wgink.gateway.exception; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: SystemException + * @Description: 系统异常 + * @Author: wanggeng + * @Date: 2021/4/23 3:19 下午 + * @Version: 1.0 + */ +public class SystemException extends RuntimeException { + + public SystemException() { + super(); + } + + public SystemException(String message) { + super(message); + } + + public SystemException(String message, Throwable cause) { + super(message, cause); + } + + public SystemException(Throwable cause) { + super(cause); + } + + protected SystemException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/UpdateException.java b/src/main/java/ink/wgink/gateway/exception/UpdateException.java new file mode 100644 index 0000000..ed381c8 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/UpdateException.java @@ -0,0 +1,32 @@ +package ink.wgink.gateway.exception; + + +/** + * @ClassName: UpdateException + * @Description: 编辑异常 + * @Author: WangGeng + * @Date: 2019/2/26 5:25 PM + * @Version: 1.0 + **/ +public class UpdateException extends SystemException { + + public UpdateException() { + super(); + } + + public UpdateException(String message) { + super(message); + } + + public UpdateException(String message, Throwable cause) { + super(message, cause); + } + + public UpdateException(Throwable cause) { + super(cause); + } + + protected UpdateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/ink/wgink/gateway/exception/handler/ExceptionHandler.java b/src/main/java/ink/wgink/gateway/exception/handler/ExceptionHandler.java new file mode 100644 index 0000000..b4b4aab --- /dev/null +++ b/src/main/java/ink/wgink/gateway/exception/handler/ExceptionHandler.java @@ -0,0 +1,78 @@ +package ink.wgink.gateway.exception.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import ink.wgink.gateway.enums.ErrorResultCodeEnum; +import ink.wgink.gateway.exception.SignException; +import ink.wgink.gateway.exception.SystemException; +import ink.wgink.gateway.pojo.result.ErrorResult; +import lombok.SneakyThrows; +import org.springframework.core.annotation.Order; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebExceptionHandler; +import reactor.core.publisher.Mono; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: ExceptionHandler + * @Description: 异常处理 + * @Author: wanggeng + * @Date: 2021/4/23 3:15 下午 + * @Version: 1.0 + */ +// 至少设置-2,靠前设置,不然不工作,数值越小,越靠前 +@Order(-2) +@Component +public class ExceptionHandler implements WebExceptionHandler { + + @SneakyThrows + @Override + public Mono handle(ServerWebExchange serverWebExchange, Throwable throwable) { + // 设置响应头 + ServerHttpResponse response = serverWebExchange.getResponse(); + response.setStatusCode(HttpStatus.BAD_REQUEST); + response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8); + + ErrorResult errorResult = new ErrorResult(); + errorResult.setCode(getErrorCode(throwable)); + errorResult.setMsg(getErrorMessage(throwable)); + + DataBuffer dataBuffer = response.bufferFactory().wrap(new ObjectMapper().writeValueAsBytes(errorResult)); + return response.writeWith(Mono.just(dataBuffer)); + } + + /** + * 获取异常内容 + * + * @param throwable + * @return + */ + public String getErrorMessage(Throwable throwable) { + if (throwable instanceof SystemException) { + return throwable.getMessage(); + } else { + throwable.printStackTrace(); + return throwable.toString(); + } + } + + /** + * 获取错误编码 + * + * @param throwable + * @return + */ + public Integer getErrorCode(Throwable throwable) { + if (throwable instanceof SignException) { + return ErrorResultCodeEnum.USERNAME_PASSWORD_ERROR.getValue(); + } + return ErrorResultCodeEnum.SYSTEM_ERROR.getValue(); + } + +} diff --git a/src/main/java/ink/wgink/gateway/filter/wg/WebFluxFilter.java b/src/main/java/ink/wgink/gateway/filter/web/WebFluxFilter.java similarity index 78% rename from src/main/java/ink/wgink/gateway/filter/wg/WebFluxFilter.java rename to src/main/java/ink/wgink/gateway/filter/web/WebFluxFilter.java index 064cc2c..fb60c42 100644 --- a/src/main/java/ink/wgink/gateway/filter/wg/WebFluxFilter.java +++ b/src/main/java/ink/wgink/gateway/filter/web/WebFluxFilter.java @@ -1,5 +1,6 @@ -package ink.wgink.gateway.filter.wg; +package ink.wgink.gateway.filter.web; +import ink.wgink.gateway.consts.ISystemConst; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @@ -28,15 +29,11 @@ import java.util.List; @Component public class WebFluxFilter implements WebFilter { - public static final String SESSION_USER = "SESSION_USER"; - public static final String PAGE_LOGIN = "/wg/login.html"; - private List passPathPatterns = Arrays.asList(new PathPattern[]{ - new PathPatternParser().parse("/gw/**"), - new PathPatternParser().parse("/wg/assets/**"), - new PathPatternParser().parse("/wg/api/sign/**"), - new PathPatternParser().parse("/wg/login.html"), - new PathPatternParser().parse(PAGE_LOGIN), + new PathPatternParser().parse(ISystemConst.ROUTE_PREFIX + "/**"), + new PathPatternParser().parse(ISystemConst.ADMIN_ROUTER_PREFIX + "/assets/**"), + new PathPatternParser().parse(ISystemConst.ADMIN_ROUTER_PREFIX + "/api/sign/**"), + new PathPatternParser().parse(ISystemConst.PAGE_LOGIN), }); @Override @@ -50,7 +47,7 @@ public class WebFluxFilter implements WebFilter { } serverWebExchange.getResponse().setStatusCode(HttpStatus.FOUND); HttpHeaders headers = serverWebExchange.getResponse().getHeaders(); - headers.setLocation(URI.create(PAGE_LOGIN)); + headers.setLocation(URI.create(ISystemConst.PAGE_LOGIN)); return serverWebExchange.getResponse().setComplete(); }); } @@ -72,7 +69,7 @@ public class WebFluxFilter implements WebFilter { * @return */ private boolean isLogin(WebSession webSession) { - return webSession.getAttributes().get(SESSION_USER) != null; + return webSession.getAttributes().get(ISystemConst.SESSION_USER) != null; } } diff --git a/src/main/java/ink/wgink/gateway/handler/route/RouteHandler.java b/src/main/java/ink/wgink/gateway/handler/route/RouteHandler.java index 579c78d..619c915 100644 --- a/src/main/java/ink/wgink/gateway/handler/route/RouteHandler.java +++ b/src/main/java/ink/wgink/gateway/handler/route/RouteHandler.java @@ -120,51 +120,6 @@ public class RouteHandler extends BaseHandler implements ApplicationEventPublish return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(routeDao.findAll(example), Route.class); } - public Flux routeDefinitionFlux() { - List routeDefinitionList = new ArrayList<>(); - return routeDao.findAll().flatMap(route -> { - // 定义路由 - RouteDefinition routeDefinition = new RouteDefinition(); - routeDefinition.setId(UUIDUtil.getUUID()); - routeDefinition.setUri(UriComponentsBuilder.fromUriString(route.getUri()).build().toUri()); - // 定义断言 - PredicateDefinition pathPredicateDefinition = new PredicateDefinition(); - // 路由断言 - Map pathPredicateDefinitionMap = new HashMap<>(16); - pathPredicateDefinitionMap.put("pattern", route.getPath()); - pathPredicateDefinition.setName("Path"); - pathPredicateDefinition.setArgs(pathPredicateDefinitionMap); - - List predicateDefinitions = new ArrayList<>(); - predicateDefinitions.add(pathPredicateDefinition); - routeDefinition.setPredicates(predicateDefinitions); - return Flux.just(routeDefinition); - }); - -// routeDao.findAll().map(route -> { -// System.out.println(route); -// // 定义路由 -// RouteDefinition routeDefinition = new RouteDefinition(); -// routeDefinition.setId(UUIDUtil.getUUID()); -// routeDefinition.setUri(UriComponentsBuilder.fromUriString(route.getUri()).build().toUri()); -// // 定义断言 -// PredicateDefinition pathPredicateDefinition = new PredicateDefinition(); -// // 路由断言 -// Map pathPredicateDefinitionMap = new HashMap<>(16); -// pathPredicateDefinitionMap.put("pattern", route.getPath()); -// pathPredicateDefinition.setName("Path"); -// pathPredicateDefinition.setArgs(pathPredicateDefinitionMap); -// -// List predicateDefinitions = new ArrayList<>(); -// predicateDefinitions.add(pathPredicateDefinition); -// routeDefinition.setPredicates(predicateDefinitions); -// // 过滤器 -// routeDefinitionList.add(routeDefinition); -// return route; -// }).blockLast(); -// return routeDefinitionList; - } - /** * 列表 * diff --git a/src/main/java/ink/wgink/gateway/handler/sign/SignHandler.java b/src/main/java/ink/wgink/gateway/handler/sign/SignHandler.java index aacab7d..eae26e8 100644 --- a/src/main/java/ink/wgink/gateway/handler/sign/SignHandler.java +++ b/src/main/java/ink/wgink/gateway/handler/sign/SignHandler.java @@ -1,11 +1,21 @@ package ink.wgink.gateway.handler.sign; +import ink.wgink.gateway.consts.ISystemConst; +import ink.wgink.gateway.exception.SignException; import ink.wgink.gateway.handler.BaseHandler; +import ink.wgink.gateway.pojo.result.SuccessResult; +import ink.wgink.gateway.pojo.sign.In; +import ink.wgink.gateway.pojo.user.User; +import ink.wgink.gateway.util.RequestFieldCheckUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; +import java.net.URI; + /** * When you feel like quitting. Think about why you started * 当你想要放弃的时候,想想当初你为何开始 @@ -19,8 +29,32 @@ import reactor.core.publisher.Mono; @Service public class SignHandler extends BaseHandler { - public Mono login(ServerRequest serverRequest) { - return null; + public Mono in(ServerRequest serverRequest) { + Mono inMono = serverRequest.bodyToMono(In.class); + return inMono.flatMap(in -> { + RequestFieldCheckUtil.check(in); + if (!StringUtils.equals(in.getUsername(), ISystemConst.USER_ADMIN_USERNAME)) { + return Mono.error(new SignException("用户名错误")); + } + if (!StringUtils.equals(in.getPassword(), ISystemConst.USER_ADMIN_PASSWORD)) { + return Mono.error(new SignException("密码错误")); + } + return serverRequest.session().flatMap(webSession -> { + User user = new User(); + user.setUuid("1"); + user.setUsername(ISystemConst.USER_ADMIN_USERNAME); + user.setPassword(ISystemConst.USER_ADMIN_PASSWORD); + webSession.getAttributes().put(ISystemConst.SESSION_USER, user); + return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(Mono.just(new SuccessResult()), SuccessResult.class); + }); + }); + } + + public Mono out(ServerRequest serverRequest) { + return serverRequest.session().flatMap(webSession -> { + webSession.getAttributes().remove(ISystemConst.SESSION_USER); + return ServerResponse.temporaryRedirect(URI.create(ISystemConst.PAGE_LOGIN)).build(); + }); } } diff --git a/src/main/java/ink/wgink/gateway/pojo/ListPage.java b/src/main/java/ink/wgink/gateway/pojo/ListPage.java deleted file mode 100644 index d58128a..0000000 --- a/src/main/java/ink/wgink/gateway/pojo/ListPage.java +++ /dev/null @@ -1,33 +0,0 @@ -package ink.wgink.gateway.pojo; - -/** - * When you feel like quitting. Think about why you started - * 当你想要放弃的时候,想想当初你为何开始 - * - * @ClassName: ListPage - * @Description: - * @Author: wanggeng - * @Date: 2021/4/13 6:19 下午 - * @Version: 1.0 - */ -public class ListPage { - - private Integer page; - private Integer size; - - public Integer getPage() { - return page == null ? 1 : page; - } - - public void setPage(Integer page) { - this.page = page; - } - - public Integer getSize() { - return size == null ? 20 : size; - } - - public void setSize(Integer size) { - this.size = size; - } -} diff --git a/src/main/java/ink/wgink/gateway/pojo/ListSearch.java b/src/main/java/ink/wgink/gateway/pojo/ListSearch.java deleted file mode 100644 index f4d29fd..0000000 --- a/src/main/java/ink/wgink/gateway/pojo/ListSearch.java +++ /dev/null @@ -1,21 +0,0 @@ -package ink.wgink.gateway.pojo; - -import lombok.Data; -import lombok.ToString; - -/** - * When you feel like quitting. Think about why you started - * 当你想要放弃的时候,想想当初你为何开始 - * - * @ClassName: Search - * @Description: 搜索 - * @Author: wanggeng - * @Date: 2021/4/20 12:06 下午 - * @Version: 1.0 - */ -@Data -public class ListSearch { - - private String keywords; - -} diff --git a/src/main/java/ink/wgink/gateway/pojo/result/ErrorResult.java b/src/main/java/ink/wgink/gateway/pojo/result/ErrorResult.java index 83e471a..cf5483c 100644 --- a/src/main/java/ink/wgink/gateway/pojo/result/ErrorResult.java +++ b/src/main/java/ink/wgink/gateway/pojo/result/ErrorResult.java @@ -59,41 +59,4 @@ public class ErrorResult implements Serializable { sb.append('}'); return sb.toString(); } - - public enum ErrorResultCodeEnum { - - /** - * 错误类型 - */ - SYSTEM_ERROR(40001), - ENCODE_ERROR(40002), - DECODE_ERROR(40003), - APP_DEPENDENCY_ERROR(40004), - PROPERTIES_ERROR(40005), - TEXT_ILLEGAL(40101), - PARAMS_ERROR(40102), - QUERY_ERROR(40101), - SAVE_ERROR(40102), - UPDATE_ERROR(40103), - REMOVE_ERROR(40104), - FILE_ERROR(40401), - TEST_ERROR(40201), - LOGIN_OUT(40301), - TOKEN_ERROR(40302), - USERNAME_PASSWORD_ERROR(40303), - USER_EXIST(40304), - PERMISSION_ERROR(40401), - DEVICE_ERROR(40501), - DEVICE_VERSION_ERROR(40502); - - private int value; - - ErrorResultCodeEnum(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - } } diff --git a/src/main/java/ink/wgink/gateway/pojo/result/SuccessResultData.java b/src/main/java/ink/wgink/gateway/pojo/result/SuccessResultData.java deleted file mode 100644 index 997ec52..0000000 --- a/src/main/java/ink/wgink/gateway/pojo/result/SuccessResultData.java +++ /dev/null @@ -1,36 +0,0 @@ -package ink.wgink.gateway.pojo.result; - -/** - * @ClassName: SuccessResultData - * @Description: 返回结果带对象 - * @Author: WangGeng - * @Date: 2019/3/11 9:31 AM - * @Version: 1.0 - **/ -public class SuccessResultData extends SuccessResult { - - private static final long serialVersionUID = 2292105832378967169L; - private T data; - - public SuccessResultData(T data) { - this.data = data; - } - - public T getData() { - return data; - } - - public void setData(T data) { - this.data = data; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("{"); - sb.append("\"data\":") - .append(data); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/src/main/java/ink/wgink/gateway/pojo/result/SuccessResultList.java b/src/main/java/ink/wgink/gateway/pojo/result/SuccessResultList.java deleted file mode 100644 index 9d58f16..0000000 --- a/src/main/java/ink/wgink/gateway/pojo/result/SuccessResultList.java +++ /dev/null @@ -1,61 +0,0 @@ -package ink.wgink.gateway.pojo.result; - -/** - * @ClassName: SuccessResultList - * @Description: 成功列表结果 - * @Author: WangGeng - * @Date: 2019/3/3 12:21 AM - * @Version: 1.0 - **/ -public class SuccessResultList extends SuccessResult { - - private List rows; - private Integer page; - private Long total; - - public SuccessResultList() { - } - - public SuccessResultList(List rows, Integer page, Long total) { - this.rows = rows; - this.page = page; - this.total = total; - } - - public List getRows() { - return rows; - } - - public void setRows(List rows) { - this.rows = rows; - } - - public Integer getPage() { - return page; - } - - public void setPage(Integer page) { - this.page = page; - } - - public Long getTotal() { - return total; - } - - public void setTotal(Long total) { - this.total = total; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("{"); - sb.append("\"rows\":") - .append(rows); - sb.append(",\"page\":") - .append(page); - sb.append(",\"total\":") - .append(total); - sb.append('}'); - return sb.toString(); - } -} diff --git a/src/main/java/ink/wgink/gateway/pojo/result/UploadExcelResultDTO.java b/src/main/java/ink/wgink/gateway/pojo/result/UploadExcelResultDTO.java deleted file mode 100644 index 1695ea2..0000000 --- a/src/main/java/ink/wgink/gateway/pojo/result/UploadExcelResultDTO.java +++ /dev/null @@ -1,61 +0,0 @@ -package ink.wgink.gateway.pojo.result; - -/** - * When you feel like quitting. Think about why you started - * 当你想要放弃的时候,想想当初你为何开始 - * - * @ClassName: UploadExcelResultDTO - * @Description: 上传Excel结果 - * @Author: WangGeng - * @Date: 2020/1/6 10:41 下午 - * @Version: 1.0 - **/ -public class UploadExcelResultDTO { - - private Integer failedCount; - private Long usedTime; - private String errorExcel; - - public UploadExcelResultDTO(Integer failedCount, Long usedTime, String errorExcel) { - this.failedCount = failedCount; - this.usedTime = usedTime; - this.errorExcel = errorExcel; - } - - public Integer getFailedCount() { - return failedCount; - } - - public void setFailedCount(Integer failedCount) { - this.failedCount = failedCount; - } - - public Long getUsedTime() { - return usedTime; - } - - public void setUsedTime(Long usedTime) { - this.usedTime = usedTime; - } - - public String getErrorExcel() { - return errorExcel == null ? "" : errorExcel.trim(); - } - - public void setErrorExcel(String errorExcel) { - this.errorExcel = errorExcel; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("{"); - sb.append("\"failedCount\":") - .append(failedCount); - sb.append(",\"usedTime\":") - .append(usedTime); - sb.append(",\"errorExcel\":") - .append("\"").append(errorExcel).append("\""); - sb.append('}'); - return sb.toString(); - } -} diff --git a/src/main/java/ink/wgink/gateway/pojo/sign/In.java b/src/main/java/ink/wgink/gateway/pojo/sign/In.java new file mode 100644 index 0000000..329431e --- /dev/null +++ b/src/main/java/ink/wgink/gateway/pojo/sign/In.java @@ -0,0 +1,26 @@ +package ink.wgink.gateway.pojo.sign; + +import ink.wgink.gateway.annoation.CheckEmptyAnnotation; +import lombok.Data; +import lombok.ToString; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: In + * @Description: 登录 + * @Author: wanggeng + * @Date: 2021/4/23 3:02 下午 + * @Version: 1.0 + */ +@Data +@ToString +public class In { + + @CheckEmptyAnnotation(name = "用户名") + private String username; + @CheckEmptyAnnotation(name = "密码") + private String password; + +} diff --git a/src/main/java/ink/wgink/gateway/pojo/user/User.java b/src/main/java/ink/wgink/gateway/pojo/user/User.java new file mode 100644 index 0000000..e928804 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/pojo/user/User.java @@ -0,0 +1,29 @@ +package ink.wgink.gateway.pojo.user; + +import ink.wgink.gateway.pojo.BasePOJO; +import lombok.Data; +import lombok.ToString; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: User + * @Description: 用户 + * @Author: wanggeng + * @Date: 2021/4/23 4:28 下午 + * @Version: 1.0 + */ +@Data +@ToString +@Document(collation = "sys_user") +public class User extends BasePOJO implements Serializable { + + private static final long serialVersionUID = 591782822391295803L; + private String username; + private String password; + +} diff --git a/src/main/java/ink/wgink/gateway/router/BaseRouter.java b/src/main/java/ink/wgink/gateway/router/BaseRouter.java new file mode 100644 index 0000000..981521a --- /dev/null +++ b/src/main/java/ink/wgink/gateway/router/BaseRouter.java @@ -0,0 +1,15 @@ +package ink.wgink.gateway.router; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: BaseRouter + * @Description: + * @Author: wanggeng + * @Date: 2021/4/23 4:07 下午 + * @Version: 1.0 + */ +public class BaseRouter { + +} diff --git a/src/main/java/ink/wgink/gateway/router/RouteRouter.java b/src/main/java/ink/wgink/gateway/router/route/RouteRouter.java similarity index 84% rename from src/main/java/ink/wgink/gateway/router/RouteRouter.java rename to src/main/java/ink/wgink/gateway/router/route/RouteRouter.java index fc2675a..156a471 100644 --- a/src/main/java/ink/wgink/gateway/router/RouteRouter.java +++ b/src/main/java/ink/wgink/gateway/router/route/RouteRouter.java @@ -1,6 +1,8 @@ -package ink.wgink.gateway.router; +package ink.wgink.gateway.router.route; +import ink.wgink.gateway.consts.ISystemConst; import ink.wgink.gateway.handler.route.RouteHandler; +import ink.wgink.gateway.router.BaseRouter; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.server.RequestPredicates; @@ -19,7 +21,7 @@ import org.springframework.web.reactive.function.server.ServerResponse; * @Version: 1.0 */ @Component -public class RouteRouter { +public class RouteRouter extends BaseRouter { /** * 路由管理 * @@ -29,7 +31,7 @@ public class RouteRouter { @Bean public RouterFunction routeRouterFunction(RouteHandler routeHandler) { // 嵌套 - return RouterFunctions.nest(RequestPredicates.path("/wg/api/route"), + return RouterFunctions.nest(RequestPredicates.path(ISystemConst.ADMIN_ROUTER_PREFIX + "/api/route"), RouterFunctions .route(RequestPredicates.POST("/save"), routeHandler::save) .andRoute(RequestPredicates.DELETE("/delete/{ids}"), routeHandler::delete) diff --git a/src/main/java/ink/wgink/gateway/router/sign/SignRouter.java b/src/main/java/ink/wgink/gateway/router/sign/SignRouter.java new file mode 100644 index 0000000..41cde43 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/router/sign/SignRouter.java @@ -0,0 +1,36 @@ +package ink.wgink.gateway.router.sign; + +import ink.wgink.gateway.consts.ISystemConst; +import ink.wgink.gateway.handler.BaseHandler; +import ink.wgink.gateway.handler.route.RouteHandler; +import ink.wgink.gateway.handler.sign.SignHandler; +import ink.wgink.gateway.router.BaseRouter; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: SignRouter + * @Description: 登录登出 + * @Author: wanggeng + * @Date: 2021/4/23 4:02 下午 + * @Version: 1.0 + */ +@Component +public class SignRouter extends BaseRouter { + + @Bean + public RouterFunction signRouterFunction(SignHandler signHandler) { + return RouterFunctions.nest(RequestPredicates.path(ISystemConst.ADMIN_ROUTER_PREFIX + "/api/sign"), + RouterFunctions + .route(RequestPredicates.POST("/in"), signHandler::in) + .andRoute(RequestPredicates.GET("/out"), signHandler::out)); + } + +} diff --git a/src/main/java/ink/wgink/gateway/util/RegexUtil.java b/src/main/java/ink/wgink/gateway/util/RegexUtil.java new file mode 100644 index 0000000..765394e --- /dev/null +++ b/src/main/java/ink/wgink/gateway/util/RegexUtil.java @@ -0,0 +1,318 @@ +package ink.wgink.gateway.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: RegexUtil + * @Description: 正则校验工具类 + * @Author: WangGeng + * @Date: 2019/12/4 18:13 + * @Version: 1.0 + **/ +public class RegexUtil { + + /** + * 特殊字符 + */ + public static final String SPECIAL_CHARACTERS = "#?!@$%^&*-_"; + /** + * 密码最小长度 + */ + public static final int PASSWORD_LENGTH_MIN = 6; + /** + * 密码最大长度 + */ + public static final int PASSWORD_LENGTH_MAX = 16; + /** + * 手机 + */ + private static final Pattern PATTERN_PHONE = Pattern.compile("^1\\d{10}$"); + /** + * 邮箱 + */ + private static final Pattern PATTERN_EMAIL = Pattern.compile("^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$"); + /** + * 邮箱 + */ + private static final Pattern PATTERN_URL = Pattern.compile("(^#)|(^http(s*):\\/\\/[^\\s]+)"); + /** + * 日期格式 + */ + private static final Pattern PATTERN_DATE = Pattern.compile("^(\\d{4})[-\\/](\\d{1}|0\\d{1}|1[0-2])([-\\/](\\d{1}|0\\d{1}|[1-2][0-9]|3[0-1]))*$"); + /** + * 时间戳格式 + */ + private static final Pattern PATTERN_DATETIME = Pattern.compile("^(\\d{4})[-\\/](\\d{1}|0\\d{1}|1[0-2])([-\\/](\\d{1}|0\\d{1}|[1-2][0-9]|3[0-1]))*(\\s+)([0-1][0-9]|(2[0-3])):([0-5][0-9])(:([0-5][0-9]))*$"); + /** + * 时间戳 + */ + private static final Pattern PATTERN_YYYY_MM_DD = Pattern.compile("^(\\d{4})(0\\d{1}|1[0-2])(0\\d{1}|[1-2][0-9]|3[0-1])$"); + /** + * 时间戳 + */ + private static final Pattern PATTERN_YYYY_MM_DD_HH_MM_SS = Pattern.compile("^(\\d{4})(0\\d{1}|1[0-2])(0\\d{1}|[1-2][0-9]|3[0-1])([0-1][0-9]|(2[0-3]))([0-5][0-9])([0-5][0-9])$"); + /** + * 时间戳(毫秒) + */ + private static final Pattern PATTERN_YYYY_MM_DD_HH_MM_SS_ZZZ = Pattern.compile("^(\\d{4})(0\\d{1}|1[0-2])(0\\d{1}|[1-2][0-9]|3[0-1])([0-1][0-9]|(2[0-3]))([0-5][0-9])([0-5][0-9])(\\d{3})$"); + /** + * 时间戳 + */ + private static final Pattern PATTERN_HH_MM_SS = Pattern.compile("^([0-1][0-9]|(2[0-3]))([0-5][0-9])([0-5][0-9])$"); + /** + * 时间戳(毫秒) + */ + private static final Pattern PATTERN_HH_MM_SS_ZZZ = Pattern.compile("^([0-1][0-9]|(2[0-3]))([0-5][0-9])([0-5][0-9])(\\d{3})$"); + /** + * 身份证 + */ + private static final Pattern PATTERN_IDENTITY = Pattern.compile("(^\\d{15}$)|(^\\d{17}(x|X|\\d)$)"); + /** + * 用户名 + */ + private static final Pattern PATTERN_USERNAME = Pattern.compile("^[a-zA-Z0-9_\\s]+$"); + /** + * 字母 + */ + private static final Pattern PATTERN_LETTER = Pattern.compile("[a-zA-Z]+"); + /** + * 中文 + */ + private static final Pattern PATTERN_CHINESE = Pattern.compile("[\\u4e00-\\u9fa5]+"); + /** + * 数字 + */ + private static final Pattern PATTERN_NUMBER = Pattern.compile("\\d+"); + /** + * 弱密码 + */ + private static final Pattern PASSWORD_WEEK = Pattern.compile(String.format("(?=.*[A-Za-z0-9%s]).{%d,%d}", SPECIAL_CHARACTERS, PASSWORD_LENGTH_MIN, PASSWORD_LENGTH_MAX)); + /** + * 中密码 + */ + private static final Pattern PASSWORD_MIDDLE = Pattern.compile(String.format("((?=.*[A-Za-z])(?=.*[0-9]))|((?=.*[A-Za-z])(?=.*[%s]))|((?=.*[0-9])(?=.*[%s])).{%d,%d}", SPECIAL_CHARACTERS, SPECIAL_CHARACTERS, PASSWORD_LENGTH_MIN, PASSWORD_LENGTH_MAX)); + /** + * 强密码 + */ + private static final Pattern PASSWORD_STRONG = Pattern.compile(String.format("(?=.*[A-Za-z])(?=.*[0-9])(?=.*[%s]).{%d,%d}", SPECIAL_CHARACTERS, PASSWORD_LENGTH_MIN, PASSWORD_LENGTH_MAX)); + /** + * 路径参数 + */ + private static final Pattern PATH_PARAMS = Pattern.compile("\\{\\w+\\}"); + + /** + * 判断弱密码强度 + * + * @param input + * @return + */ + public static boolean isPasswordWeek(String input) { + return PASSWORD_WEEK.matcher(input).matches(); + } + + /** + * 判断中密码强度 + * + * @param input + * @return + */ + public static boolean isPasswordMiddle(String input) { + return PASSWORD_MIDDLE.matcher(input).matches(); + } + + /** + * 判断强密码强度 + * + * @param input + * @return + */ + public static boolean isPasswordStrong(String input) { + return PASSWORD_STRONG.matcher(input).matches(); + } + + /** + * 判断电话 + * + * @param input + * @return + */ + public static boolean isPhone(String input) { + return PATTERN_PHONE.matcher(input).matches(); + } + + /** + * 判断邮箱 + * + * @param input + * @return + */ + public static boolean isEmail(String input) { + return PATTERN_EMAIL.matcher(input).matches(); + } + + /** + * 判断URL + * + * @param input + * @return + */ + public static boolean isUrl(String input) { + return PATTERN_URL.matcher(input).matches(); + } + + /** + * 判断日期 + * + * @param input + * @return + */ + public static boolean isDate(String input) { + return PATTERN_DATE.matcher(input).matches(); + } + + /** + * 判断时间戳 + * + * @param input + * @return + */ + public static boolean isDatetime(String input) { + return PATTERN_DATETIME.matcher(input).matches(); + } + + /** + * 判断时间时间戳 + * + * @param input + * @return + */ + public static boolean isYyyyMmDd(String input) { + return PATTERN_YYYY_MM_DD.matcher(input).matches(); + } + + /** + * 判断时间时间戳 + * + * @param input + * @return + */ + public static boolean isYyyyMmDdHhMmSs(String input) { + return PATTERN_YYYY_MM_DD_HH_MM_SS.matcher(input).matches(); + } + + /** + * 判断时间时间戳 + * + * @param input + * @return + */ + public static boolean isYyyyMmDdHhMmSsZzz(String input) { + return PATTERN_YYYY_MM_DD_HH_MM_SS_ZZZ.matcher(input).matches(); + } + + /** + * 判断时间时间戳 + * + * @param input + * @return + */ + public static boolean isHhMmSs(String input) { + return PATTERN_HH_MM_SS.matcher(input).matches(); + } + + /** + * 判断时间时间戳 + * + * @param input + * @return + */ + public static boolean isHhMmSsZzz(String input) { + return PATTERN_HH_MM_SS_ZZZ.matcher(input).matches(); + } + + /** + * 判断身份证 + * + * @param input + * @return + */ + public static boolean isIdentity(String input) { + return PATTERN_IDENTITY.matcher(input).matches(); + } + + /** + * 判断用户名 + * + * @param input + * @return + */ + public static boolean isUsername(String input) { + return PATTERN_USERNAME.matcher(input).matches(); + } + + /** + * 判断是字母 + * + * @param input + * @return + */ + public static boolean isLetter(String input) { + return PATTERN_LETTER.matcher(input).matches(); + } + + /** + * 判断是中文 + * + * @param input + * @return + */ + public static boolean isChinese(String input) { + return PATTERN_CHINESE.matcher(input).matches(); + } + + /** + * 判断是数字 + * + * @param input + * @return + */ + public static boolean isNumber(String input) { + return PATTERN_NUMBER.matcher(input).matches(); + } + + /** + * 自定义判断 + * + * @param customPattern + * @param input + * @return + */ + public static boolean isMatch(Pattern customPattern, String input) { + return customPattern.matcher(input).matches(); + } + + /** + * 将路径中的参数替换为指定的字符,返回替换后的结果 + * + * @param path 路径 + * @param replaceStr 替换后的字符 + * @return + */ + public static String replacePathParams(String path, String replaceStr) { + Matcher matcher = PATH_PARAMS.matcher(path); + while (matcher.find()) { + String group = matcher.group(); + path = path.replace(group, replaceStr); + } + return path; + } + + public static void main(String[] args) { + System.out.println(isHhMmSs("1111111")); + } + +} diff --git a/src/main/java/ink/wgink/gateway/util/RequestFieldCheckUtil.java b/src/main/java/ink/wgink/gateway/util/RequestFieldCheckUtil.java new file mode 100644 index 0000000..df7b1e2 --- /dev/null +++ b/src/main/java/ink/wgink/gateway/util/RequestFieldCheckUtil.java @@ -0,0 +1,308 @@ +package ink.wgink.gateway.util; + +import ink.wgink.gateway.annoation.*; +import ink.wgink.gateway.exception.ParamsException; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: ReportBodyFieldCheckUtil + * @Description: 上报内容字段校验 + * @Author: wanggeng + * @Date: 2021/4/23 3:49 下午 + * @Version: 1.0 + */ +public class RequestFieldCheckUtil { + + public static void check(T t) { + Class clazz = t.getClass(); + List fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())); + setSuperClassField(clazz, fields); + Method[] methods = clazz.getMethods(); + try { + for (Field field : fields) { + Method method = getGetMethodByField(methods, field.getName()); + if (method == null) { + continue; + } + Object fieldValue = method.invoke(t); + if (field.isAnnotationPresent(CheckNullAnnotation.class)) { + CheckNullAnnotation checkNullAnnotation = field.getAnnotation(CheckNullAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s不能为空", checkNullAnnotation.name())); + } + checkTypes(checkNullAnnotation.name(), fieldValue.toString(), checkNullAnnotation.types()); + } else if (field.isAnnotationPresent(CheckEmptyAnnotation.class)) { + CheckEmptyAnnotation checkEmptyAnnotation = field.getAnnotation(CheckEmptyAnnotation.class); + if (fieldValue == null || StringUtils.isBlank(fieldValue.toString())) { + throw new ParamsException(String.format("%s不能为空或空串", checkEmptyAnnotation.name())); + } + checkRegular(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.verifyType(), checkEmptyAnnotation.regex()); + checkTypes(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.types()); + } else if (field.isAnnotationPresent(CheckNumberAnnotation.class)) { + CheckNumberAnnotation checkNumberAnnotation = field.getAnnotation(CheckNumberAnnotation.class); + if (fieldValue == null || !NumberUtils.isNumber(fieldValue.toString())) { + throw new ParamsException(String.format("%s必须为数字", checkNumberAnnotation.name())); + } + Double value = Double.parseDouble(fieldValue.toString()); + if (value < checkNumberAnnotation.min()) { + throw new ParamsException(String.format("%s最小值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.min())); + } + if (value > checkNumberAnnotation.max()) { + throw new ParamsException(String.format("%s最大值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.max())); + } + checkTypes(checkNumberAnnotation.name(), fieldValue.toString(), checkNumberAnnotation.types()); + } else if (field.isAnnotationPresent(CheckBooleanAnnotation.class)) { + CheckBooleanAnnotation checkBooleanAnnotation = field.getAnnotation(CheckBooleanAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s必须为布尔", checkBooleanAnnotation.name())); + } + checkTypes(checkBooleanAnnotation.name(), fieldValue.toString(), checkBooleanAnnotation.types()); + } else if (field.isAnnotationPresent(CheckListAnnotation.class)) { + CheckListAnnotation checkListAnnotation = field.getAnnotation(CheckListAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); + } + if (fieldValue instanceof List) { + List fieldValueList = (List) fieldValue; + if (fieldValueList.isEmpty()) { + throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); + } + for (Object obj : fieldValueList) { + checkField(obj); + } + } else if (fieldValue instanceof String[]) { + String[] fieldValueArray = (String[]) fieldValue; + for (Object obj : fieldValueArray) { + checkField(obj); + } + } + } + } + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + throw new ParamsException("系统错误"); + } + } + + /** + * 校验字段 + * + * @param object + * @throws ParamsException + */ + public static void checkField(Object object) throws ParamsException { + Class clazz = object.getClass(); + List fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())); + setSuperClassField(clazz, fields); + Method[] methods = clazz.getMethods(); + try { + for (Field field : fields) { + Method method = getGetMethodByField(methods, field.getName()); + if (method == null) { + continue; + } + Object fieldValue = method.invoke(object); + if (field.isAnnotationPresent(CheckNullAnnotation.class)) { + CheckNullAnnotation checkNullAnnotation = field.getAnnotation(CheckNullAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s不能为空", checkNullAnnotation.name())); + } + checkTypes(checkNullAnnotation.name(), fieldValue.toString(), checkNullAnnotation.types()); + } else if (field.isAnnotationPresent(CheckEmptyAnnotation.class)) { + CheckEmptyAnnotation checkEmptyAnnotation = field.getAnnotation(CheckEmptyAnnotation.class); + if (fieldValue == null || StringUtils.isBlank(fieldValue.toString())) { + throw new ParamsException(String.format("%s不能为空或空串", checkEmptyAnnotation.name())); + } + checkRegular(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.verifyType(), checkEmptyAnnotation.regex()); + checkTypes(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.types()); + } else if (field.isAnnotationPresent(CheckNumberAnnotation.class)) { + CheckNumberAnnotation checkNumberAnnotation = field.getAnnotation(CheckNumberAnnotation.class); + if (fieldValue == null || !NumberUtils.isNumber(fieldValue.toString())) { + throw new ParamsException(String.format("%s必须为数字", checkNumberAnnotation.name())); + } + Double value = Double.parseDouble(fieldValue.toString()); + if (value < checkNumberAnnotation.min()) { + throw new ParamsException(String.format("%s最小值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.min())); + } + if (value > checkNumberAnnotation.max()) { + throw new ParamsException(String.format("%s最大值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.max())); + } + checkTypes(checkNumberAnnotation.name(), fieldValue.toString(), checkNumberAnnotation.types()); + } else if (field.isAnnotationPresent(CheckBooleanAnnotation.class)) { + CheckBooleanAnnotation checkBooleanAnnotation = field.getAnnotation(CheckBooleanAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s必须为布尔", checkBooleanAnnotation.name())); + } + checkTypes(checkBooleanAnnotation.name(), fieldValue.toString(), checkBooleanAnnotation.types()); + } else if (field.isAnnotationPresent(CheckListAnnotation.class)) { + CheckListAnnotation checkListAnnotation = field.getAnnotation(CheckListAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); + } + if (fieldValue instanceof List) { + List fieldValueList = (List) fieldValue; + if (fieldValueList.isEmpty()) { + throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); + } + for (Object obj : fieldValueList) { + checkField(obj); + } + } else if (fieldValue instanceof String[]) { + String[] fieldValueArray = (String[]) fieldValue; + for (Object obj : fieldValueArray) { + checkField(obj); + } + } + } + } + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + throw new ParamsException("系统错误"); + } + } + + /** + * 检查类型 + * + * @param name + * @param value + * @param types + * @throws ParamsException + */ + private static void checkTypes(String name, String value, String[] types) throws ParamsException { + if (types != null && types.length > 0) { + StringBuilder typeSB = new StringBuilder(); + for (String type : types) { + if (StringUtils.equals(value, type)) { + return; + } + if (typeSB.length() > 0) { + typeSB.append(","); + } + typeSB.append("\"").append(type).append("\""); + } + throw new ParamsException(String.format("%s必须是如下类型:[%s]", name, typeSB.toString())); + } + } + + /** + * 检查正则 + * + * @param name + * @param value + * @param verifyType + * @param regex + */ + private static void checkRegular(String name, String value, String verifyType, String regex) { + if (StringUtils.isBlank(verifyType)) { + return; + } + if (StringUtils.equals("username", verifyType)) { + if (!RegexUtil.isUsername(value)) { + throw new ParamsException(String.format("%s格式只能是字母、数字和下划线", name)); + } + return; + } else if (StringUtils.equals("phone", verifyType)) { + if (!RegexUtil.isPhone(value)) { + throw new ParamsException(String.format("%s格式非手机格式", name)); + } + return; + } else if (StringUtils.equals("email", verifyType)) { + if (!RegexUtil.isEmail(value)) { + throw new ParamsException(String.format("%s格式非邮件格式", name)); + } + return; + } else if (StringUtils.equals("url", verifyType)) { + if (!RegexUtil.isUrl(value)) { + throw new ParamsException(String.format("%s格式非url格式", name)); + } + return; + } else if (StringUtils.equals("number", verifyType)) { + if (!NumberUtils.isNumber(value)) { + throw new ParamsException(String.format("%s格式非数字格式", name)); + } + return; + } else if (StringUtils.equals("date", verifyType)) { + if (!RegexUtil.isDate(value)) { + throw new ParamsException(String.format("%s格式非日期格式", name)); + } + return; + } else if (StringUtils.equals("datetime", verifyType)) { + if (!RegexUtil.isDatetime(value)) { + throw new ParamsException(String.format("%s格式非时间戳格式", name)); + } + return; + } else if (StringUtils.equals("identity", verifyType)) { + if (!RegexUtil.isIdentity(value)) { + throw new ParamsException(String.format("%s格式非身份证格式", name)); + } + return; + } else if (StringUtils.equals("letter", verifyType)) { + if (!RegexUtil.isLetter(value)) { + throw new ParamsException(String.format("%s格式非字母格式", name)); + } + return; + } else if (StringUtils.equals("chinese", verifyType)) { + if (!RegexUtil.isLetter(value)) { + throw new ParamsException(String.format("%s格式非中文格式", name)); + } + return; + } else if (StringUtils.equals("custom", verifyType)) { + if (StringUtils.isBlank(regex)) { + return; + } + if (!Pattern.compile(regex).matcher(value).matches()) { + throw new ParamsException(String.format("%s格式不正确", name)); + } + } + } + + /** + * 通过字段获取get方法 + * + * @param methods + * @param fieldName + * @return + */ + public static Method getGetMethodByField(Method[] methods, String fieldName) { + String getMethodName = String.format("get%s", fieldName).toLowerCase(); + for (Method method : methods) { + if (StringUtils.equals(getMethodName, method.getName().toLowerCase())) { + return method; + } + } + return null; + } + + /** + * 设置父类属性列表 + * + * @param clazz + * @param fields + */ + private static void setSuperClassField(Class clazz, List fields) { + Class superClazz = clazz.getSuperclass(); + if (superClazz == null) { + return; + } + Field[] superFields = superClazz.getDeclaredFields(); + if (superFields == null) { + return; + } + fields.addAll(Arrays.asList(superFields)); + setSuperClassField(superClazz, fields); + } + +} diff --git a/src/main/resources/static/wg/assets/images/user-avatar.png b/src/main/resources/static/wg/assets/images/user-avatar.png new file mode 100644 index 0000000..9653241 Binary files /dev/null and b/src/main/resources/static/wg/assets/images/user-avatar.png differ diff --git a/src/main/resources/static/wg/index.html b/src/main/resources/static/wg/index.html index 14da829..a40bcdc 100644 --- a/src/main/resources/static/wg/index.html +++ b/src/main/resources/static/wg/index.html @@ -17,15 +17,13 @@
  • 网关管理
    -
    网关管理
    +
    映射管理
  • - +
    -
    修改信息
    -
    安全管理
    -
    退了
    +
    退出
  • diff --git a/src/main/resources/static/wg/login.html b/src/main/resources/static/wg/login.html index f3f5b83..f4474d6 100644 --- a/src/main/resources/static/wg/login.html +++ b/src/main/resources/static/wg/login.html @@ -9,6 +9,11 @@ +