From aaf62982e277f573a0c7b271aa4e2ba7faee21ce Mon Sep 17 00:00:00 2001 From: xingyu Date: Thu, 12 Jan 2023 21:51:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20captcha=20?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao-spring-boot-starter-captcha/pom.xml | 1 + .../AjCaptchaServiceAutoConfiguration.java | 17 +- .../AjCaptchaStorageAutoConfiguration.java | 5 +- .../captcha/controller/CaptchaController.java | 65 - .../model/common/CaptchaBaseMapEnum.java | 42 +- .../captcha/model/common/CaptchaTypeEnum.java | 44 +- .../com/anji/captcha/model/common/Const.java | 70 +- .../captcha/model/common/RepCodeEnum.java | 45 +- .../captcha/model/common/RequestModel.java | 111 +- .../captcha/model/common/ResponseModel.java | 64 +- .../com/anji/captcha/model/vo/CaptchaVO.java | 173 +- .../com/anji/captcha/model/vo/PointVO.java | 27 +- .../properties/AjCaptchaProperties.java | 201 +- .../captcha/service/CaptchaCacheService.java | 40 +- .../anji/captcha/service/CaptchaService.java | 15 +- .../service/impl/AbstractCaptchaService.java | 58 +- .../impl/BlockPuzzleCaptchaServiceImpl.java | 51 +- .../impl/CaptchaCacheServiceMemImpl.java | 19 +- .../service/impl/CaptchaServiceFactory.java | 14 +- .../impl/ClickWordCaptchaServiceImpl.java | 27 +- .../impl/DefaultCaptchaServiceImpl.java | 14 +- .../service/impl/FrequencyLimitHandler.java | 30 +- .../java/com/anji/captcha/util/AESUtil.java | 33 +- .../com/anji/captcha/util/Base64Utils.java | 53 - .../java/com/anji/captcha/util/CacheUtil.java | 45 +- .../com/anji/captcha/util/FileCopyUtils.java | 11 +- .../com/anji/captcha/util/ImageUtils.java | 21 +- .../java/com/anji/captcha/util/JsonUtil.java | 103 +- .../java/com/anji/captcha/util/MD5Util.java | 11 +- .../com/anji/captcha/util/RandomUtils.java | 21 +- .../com/anji/captcha/util/StreamUtils.java | 17 +- .../com/anji/captcha/util/StringUtils.java | 1742 ----------------- .../admin/captcha/CaptchaController.java | 35 +- 33 files changed, 471 insertions(+), 2754 deletions(-) delete mode 100644 yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/controller/CaptchaController.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/Base64Utils.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/StringUtils.java diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/pom.xml b/yudao-framework/yudao-spring-boot-starter-captcha/pom.xml index 9aaad51f5..5fca12c8d 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-captcha/pom.xml @@ -21,6 +21,7 @@ org.springframework.boot spring-boot-starter + provided diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaServiceAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaServiceAutoConfiguration.java index 57e353e03..1ae6cf2df 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaServiceAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaServiceAutoConfiguration.java @@ -1,13 +1,12 @@ package com.anji.captcha.config; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.Const; import com.anji.captcha.properties.AjCaptchaProperties; import com.anji.captcha.service.CaptchaService; import com.anji.captcha.service.impl.CaptchaServiceFactory; import com.anji.captcha.util.ImageUtils; -import com.anji.captcha.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -21,15 +20,14 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; +@Slf4j @Configuration public class AjCaptchaServiceAutoConfiguration { - private static Logger logger = LoggerFactory.getLogger(AjCaptchaServiceAutoConfiguration.class); - @Bean @ConditionalOnMissingBean public CaptchaService captchaService(AjCaptchaProperties prop) { - logger.info("自定义配置项:{}", prop.toString()); + log.info("自定义配置项:{}", prop.toString()); Properties config = new Properties(); config.put(Const.CAPTCHA_CACHETYPE, prop.getCacheType().name()); config.put(Const.CAPTCHA_WATER_MARK, prop.getWaterMark()); @@ -57,14 +55,13 @@ public class AjCaptchaServiceAutoConfiguration { config.put(Const.CAPTCHA_FONT_STYLE, prop.getFontStyle() + ""); config.put(Const.CAPTCHA_WORD_COUNT, prop.getClickWordCount() + ""); - if ((StringUtils.isNotBlank(prop.getJigsaw()) && prop.getJigsaw().startsWith("classpath:")) - || (StringUtils.isNotBlank(prop.getPicClick()) && prop.getPicClick().startsWith("classpath:"))) { + if ((StrUtil.isNotBlank(prop.getJigsaw()) && prop.getJigsaw().startsWith("classpath:")) + || (StrUtil.isNotBlank(prop.getPicClick()) && prop.getPicClick().startsWith("classpath:"))) { //自定义resources目录下初始化底图 config.put(Const.CAPTCHA_INIT_ORIGINAL, "true"); initializeBaseMap(prop.getJigsaw(), prop.getPicClick()); } - CaptchaService s = CaptchaServiceFactory.getInstance(config); - return s; + return CaptchaServiceFactory.getInstance(config); } private static void initializeBaseMap(String jigsaw, String picClick) { diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaStorageAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaStorageAutoConfiguration.java index f84f6cb08..0eed5316c 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaStorageAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaStorageAutoConfiguration.java @@ -8,14 +8,13 @@ import org.springframework.context.annotation.Configuration; /** * 存储策略自动配置. - * */ @Configuration public class AjCaptchaStorageAutoConfiguration { @Bean(name = "AjCaptchaCacheService") - public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties){ - //缓存类型redis/local/.... + public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties) { + // 缓存类型redis/local/.... return CaptchaServiceFactory.getCache(ajCaptchaProperties.getCacheType().name()); } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/controller/CaptchaController.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/controller/CaptchaController.java deleted file mode 100644 index 468833ecd..000000000 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/controller/CaptchaController.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - *Copyright © 2018 anji-plus - *安吉加加信息技术有限公司 - *http://www.anji-plus.com - *All rights reserved. - */ -package com.anji.captcha.controller; - -import com.anji.captcha.model.common.ResponseModel; -import com.anji.captcha.model.vo.CaptchaVO; -import com.anji.captcha.service.CaptchaService; -import com.anji.captcha.util.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; - - -@RestController -@RequestMapping("/captcha") -public class CaptchaController { - - @Autowired - private CaptchaService captchaService; - - @PostMapping("/get") - public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) { - assert request.getRemoteHost()!=null; - data.setBrowserInfo(getRemoteId(request)); - return captchaService.get(data); - } - - @PostMapping("/check") - public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) { - data.setBrowserInfo(getRemoteId(request)); - return captchaService.check(data); - } - - //@PostMapping("/verify") - public ResponseModel verify(@RequestBody CaptchaVO data, HttpServletRequest request) { - return captchaService.verification(data); - } - - public static final String getRemoteId(HttpServletRequest request) { - String xfwd = request.getHeader("X-Forwarded-For"); - String ip = getRemoteIpFromXfwd(xfwd); - String ua = request.getHeader("user-agent"); - if (StringUtils.isNotBlank(ip)) { - return ip + ua; - } - return request.getRemoteAddr() + ua; - } - - private static String getRemoteIpFromXfwd(String xfwd) { - if (StringUtils.isNotBlank(xfwd)) { - String[] ipList = xfwd.split(","); - return StringUtils.trim(ipList[0]); - } - return null; - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaBaseMapEnum.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaBaseMapEnum.java index 7249ee9db..52d6a18af 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaBaseMapEnum.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaBaseMapEnum.java @@ -1,46 +1,46 @@ package com.anji.captcha.model.common; +import lombok.AllArgsConstructor; +import lombok.Getter; + /** * 底图类型枚举 */ +@Getter +@AllArgsConstructor public enum CaptchaBaseMapEnum { - ORIGINAL("ORIGINAL","滑动拼图底图"), - SLIDING_BLOCK("SLIDING_BLOCK","滑动拼图滑块底图"), - PIC_CLICK("PIC_CLICK","文字点选底图"); + ORIGINAL("ORIGINAL", "滑动拼图底图"), + SLIDING_BLOCK("SLIDING_BLOCK", "滑动拼图滑块底图"), + PIC_CLICK("PIC_CLICK", "文字点选底图"); - private String codeValue; - private String codeDesc; - - private CaptchaBaseMapEnum(String codeValue, String codeDesc) { - this.codeValue = codeValue; - this.codeDesc = codeDesc; - } - - public String getCodeValue(){ return this.codeValue;} - - public String getCodeDesc(){ return this.codeDesc;} + private final String codeValue; + private final String codeDesc; //根据codeValue获取枚举 - public static CaptchaBaseMapEnum parseFromCodeValue(String codeValue){ - for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()){ - if(e.codeValue.equals(codeValue)){ return e;} + public static CaptchaBaseMapEnum parseFromCodeValue(String codeValue) { + for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()) { + if (e.codeValue.equals(codeValue)) { + return e; + } } return null; } //根据codeValue获取描述 - public static String getCodeDescByCodeBalue(String codeValue){ + public static String getCodeDescByCodeBalue(String codeValue) { CaptchaBaseMapEnum enumItem = parseFromCodeValue(codeValue); return enumItem == null ? "" : enumItem.getCodeDesc(); } //验证codeValue是否有效 - public static boolean validateCodeValue(String codeValue){ return parseFromCodeValue(codeValue)!=null;} + public static boolean validateCodeValue(String codeValue) { + return parseFromCodeValue(codeValue) != null; + } //列出所有值字符串 - public static String getString(){ + public static String getString() { StringBuffer buffer = new StringBuffer(); - for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()){ + for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()) { buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); } buffer.deleteCharAt(buffer.lastIndexOf(",")); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaTypeEnum.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaTypeEnum.java index 7e1329a9f..fce123f58 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaTypeEnum.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaTypeEnum.java @@ -1,52 +1,52 @@ package com.anji.captcha.model.common; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor public enum CaptchaTypeEnum { /** * 滑块拼图. */ - BLOCKPUZZLE("blockPuzzle","滑块拼图"), + BLOCKPUZZLE("blockPuzzle", "滑块拼图"), /** * 文字点选. */ - CLICKWORD("clickWord","文字点选"), + CLICKWORD("clickWord", "文字点选"), /** * 默认. */ - DEFAULT("default","默认"); + DEFAULT("default", "默认"); - private String codeValue; - private String codeDesc; - - private CaptchaTypeEnum(String codeValue, String codeDesc) { - this.codeValue = codeValue; - this.codeDesc = codeDesc; - } - - public String getCodeValue(){ return this.codeValue;} - - public String getCodeDesc(){ return this.codeDesc;} + private final String codeValue; + private final String codeDesc; //根据codeValue获取枚举 - public static CaptchaTypeEnum parseFromCodeValue(String codeValue){ - for (CaptchaTypeEnum e : CaptchaTypeEnum.values()){ - if(e.codeValue.equals(codeValue)){ return e;} + public static CaptchaTypeEnum parseFromCodeValue(String codeValue) { + for (CaptchaTypeEnum e : CaptchaTypeEnum.values()) { + if (e.codeValue.equals(codeValue)) { + return e; + } } return null; } //根据codeValue获取描述 - public static String getCodeDescByCodeBalue(String codeValue){ + public static String getCodeDescByCodeBalue(String codeValue) { CaptchaTypeEnum enumItem = parseFromCodeValue(codeValue); return enumItem == null ? "" : enumItem.getCodeDesc(); } //验证codeValue是否有效 - public static boolean validateCodeValue(String codeValue){ return parseFromCodeValue(codeValue)!=null;} + public static boolean validateCodeValue(String codeValue) { + return parseFromCodeValue(codeValue) != null; + } //列出所有值字符串 - public static String getString(){ - StringBuffer buffer = new StringBuffer(); - for (CaptchaTypeEnum e : CaptchaTypeEnum.values()){ + public static String getString() { + StringBuilder buffer = new StringBuilder(); + for (CaptchaTypeEnum e : CaptchaTypeEnum.values()) { buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); } buffer.deleteCharAt(buffer.lastIndexOf(",")); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/Const.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/Const.java index c029d5d1d..782a6e39f 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/Const.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/Const.java @@ -6,7 +6,7 @@ package com.anji.captcha.model.common; public interface Const { /** - *滑块底图路径 + * 滑块底图路径 */ String ORIGINAL_PATH_JIGSAW = "captcha.captchaOriginalPath.jigsaw"; @@ -29,8 +29,8 @@ public interface Const { * 点选文字验证码的文字字体(宋体) */ String CAPTCHA_FONT_TYPE = "captcha.font.type"; - String CAPTCHA_FONT_STYLE = "captcha.font.style"; - String CAPTCHA_FONT_SIZE = "captcha.font.size"; + String CAPTCHA_FONT_STYLE = "captcha.font.style"; + String CAPTCHA_FONT_SIZE = "captcha.font.size"; /** * 验证码类型default两种都实例化。 @@ -72,41 +72,41 @@ public interface Const { */ String CAPTCHA_TIMING_CLEAR_SECOND = "captcha.timing.clear"; - /** - * 历史资源清除开关 0禁用,1 开启 - */ - String HISTORY_DATA_CLEAR_ENABLE = "captcha.history.data.clear.enable"; + /** + * 历史资源清除开关 0禁用,1 开启 + */ + String HISTORY_DATA_CLEAR_ENABLE = "captcha.history.data.clear.enable"; - /** - * 接口限流开关 0禁用 1启用 - */ - String REQ_FREQUENCY_LIMIT_ENABLE = "captcha.req.frequency.limit.enable"; + /** + * 接口限流开关 0禁用 1启用 + */ + String REQ_FREQUENCY_LIMIT_ENABLE = "captcha.req.frequency.limit.enable"; - /** - * get 接口 一分钟请求次数限制 - */ - String REQ_GET_MINUTE_LIMIT = "captcha.req.get.minute.limit"; + /** + * get 接口 一分钟请求次数限制 + */ + String REQ_GET_MINUTE_LIMIT = "captcha.req.get.minute.limit"; - /** - * 验证失败后,get接口锁定时间 - */ - String REQ_GET_LOCK_LIMIT = "captcha.req.get.lock.limit"; - /** - * 验证失败后,get接口锁定时间 - */ - String REQ_GET_LOCK_SECONDS = "captcha.req.get.lock.seconds"; + /** + * 验证失败后,get接口锁定时间 + */ + String REQ_GET_LOCK_LIMIT = "captcha.req.get.lock.limit"; + /** + * 验证失败后,get接口锁定时间 + */ + String REQ_GET_LOCK_SECONDS = "captcha.req.get.lock.seconds"; - /** - * verify 接口 一分钟请求次数限制 - */ - String REQ_VALIDATE_MINUTE_LIMIT = "captcha.req.verify.minute.limit"; - /** - * check接口 一分钟请求次数限制 - */ - String REQ_CHECK_MINUTE_LIMIT = "captcha.req.check.minute.limit"; + /** + * verify 接口 一分钟请求次数限制 + */ + String REQ_VALIDATE_MINUTE_LIMIT = "captcha.req.verify.minute.limit"; + /** + * check接口 一分钟请求次数限制 + */ + String REQ_CHECK_MINUTE_LIMIT = "captcha.req.check.minute.limit"; - /*** - * 点选文字个数 - */ - String CAPTCHA_WORD_COUNT = "captcha.word.count"; + /*** + * 点选文字个数 + */ + String CAPTCHA_WORD_COUNT = "captcha.word.count"; } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RepCodeEnum.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RepCodeEnum.java index c452cc105..6e1917f89 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RepCodeEnum.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RepCodeEnum.java @@ -6,16 +6,23 @@ */ package com.anji.captcha.model.common; +import lombok.AllArgsConstructor; +import lombok.Getter; + import java.text.MessageFormat; /** * 返回应答码 - * @author * + * @author */ +@AllArgsConstructor +@Getter public enum RepCodeEnum { - /** 0001 - 0099 网关应答码 */ + /** + * 0001 - 0099 网关应答码 + */ SUCCESS("0000", "成功"), ERROR("0001", "操作失败"), EXCEPTION("9999", "服务器内部异常"), @@ -33,36 +40,24 @@ public enum RepCodeEnum { API_CAPTCHA_ERROR("6112", "获取验证码失败,请联系管理员"), API_CAPTCHA_BASEMAP_NULL("6113", "底图未初始化成功,请检查路径"), - API_REQ_LIMIT_GET_ERROR("6201", "get接口请求次数超限,请稍后再试!"), + API_REQ_LIMIT_GET_ERROR("6201", "get接口请求次数超限,请稍后再试!"), API_REQ_INVALID("6206", "无效请求,请重新获取验证码"), - API_REQ_LOCK_GET_ERROR("6202", "接口验证失败数过多,请稍后再试"), - API_REQ_LIMIT_CHECK_ERROR("6204", "check接口请求次数超限,请稍后再试!"), - API_REQ_LIMIT_VERIFY_ERROR("6205", "verify请求次数超限!"), - ; - private String code; - private String desc; + API_REQ_LOCK_GET_ERROR("6202", "接口验证失败数过多,请稍后再试"), + API_REQ_LIMIT_CHECK_ERROR("6204", "check接口请求次数超限,请稍后再试!"), + API_REQ_LIMIT_VERIFY_ERROR("6205", "verify请求次数超限!"); + private final String code; + private final String desc; - RepCodeEnum(String code, String desc) { - this.code = code; - this.desc = desc; - } - public String getCode() { - return code; - } - public String getDesc() { - return desc; - } - public String getName(){ - return this.name(); - } - /** 将入参fieldNames与this.desc组合成错误信息 - * {fieldName}不能为空 + /** + * 将入参fieldNames与this.desc组合成错误信息 + * {fieldName}不能为空 + * * @param fieldNames * @return */ public ResponseModel parseError(Object... fieldNames) { - ResponseModel errorMessage=new ResponseModel(); + ResponseModel errorMessage = new ResponseModel(); String newDesc = MessageFormat.format(this.desc, fieldNames); errorMessage.setRepCode(this.code); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RequestModel.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RequestModel.java index 06e33c3d9..87104d341 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RequestModel.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RequestModel.java @@ -6,23 +6,32 @@ */ package com.anji.captcha.model.common; -import com.anji.captcha.util.StringUtils; + +import cn.hutool.core.util.StrUtil; +import lombok.Data; import java.io.Serializable; import java.util.HashMap; import java.util.List; +@Data public class RequestModel implements Serializable { private static final long serialVersionUID = -5800786065305114784L; - /**当前请求接口路径 /business/accessUser/login */ + /** + * 当前请求接口路径 /business/accessUser/login + */ private String servletPath; - /** {"reqData":{"password":"*****","userName":"admin"},"sign":"a304a7f296f565b6d2009797f68180f0","time":"1542456453355","token":""} */ + /** + * {"reqData":{"password":"*****","userName":"admin"},"sign":"a304a7f296f565b6d2009797f68180f0","time":"1542456453355","token":""} + */ private String requestString; - /** {"password":"****","userName":"admin"} */ + /** + * {"password":"****","userName":"admin"} + */ private HashMap reqData; private String token; @@ -46,10 +55,11 @@ public class RequestModel implements Serializable { /** * 校验自身参数合法性 + * * @return */ public boolean isVaildateRequest() { - if (StringUtils.isBlank(sign) || StringUtils.isBlank(time)) { + if (StrUtil.isBlank(sign) || StrUtil.isBlank(time)) { return false; } return true; @@ -63,95 +73,4 @@ public class RequestModel implements Serializable { this.servletPath = servletPath; } - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public Long getUserId() { - return userId; - } - - public void setUserId(Long userId) { - this.userId = userId; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public static long getSerialVersionUID() { - return serialVersionUID; - } - - public List getProjectList() { - return projectList; - } - - public void setProjectList(List projectList) { - this.projectList = projectList; - } - - public List getGroupIdList() { - return groupIdList; - } - - public void setGroupIdList(List groupIdList) { - this.groupIdList = groupIdList; - } - - public String getSign() { - return sign; - } - - public void setSign(String sign) { - this.sign = sign; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getSourceIP() { - return sourceIP; - } - - public void setSourceIP(String sourceIP) { - this.sourceIP = sourceIP; - } - - public String getRequestString() { - return requestString; - } - - public void setRequestString(String requestString) { - this.requestString = requestString; - } - - public HashMap getReqData() { - return reqData; - } - - public void setReqData(HashMap reqData) { - this.reqData = reqData; - } - - public String getTarget() { - return target; - } - - public void setTarget(String target) { - this.target = target; - } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/ResponseModel.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/ResponseModel.java index dbaf4c746..39e02d177 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/ResponseModel.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/ResponseModel.java @@ -6,38 +6,42 @@ */ package com.anji.captcha.model.common; -import com.anji.captcha.util.StringUtils; +import cn.hutool.core.util.StrUtil; +import lombok.Data; import java.io.Serializable; +@Data public class ResponseModel implements Serializable { private static final long serialVersionUID = 8445617032523881407L; - private String repCode; + private String repCode; - private String repMsg; + private String repMsg; - private Object repData; + private Object repData; public ResponseModel() { this.repCode = RepCodeEnum.SUCCESS.getCode(); } public ResponseModel(RepCodeEnum repCodeEnum) { - this.setRepCodeEnum(repCodeEnum); + this.setRepCodeEnum(repCodeEnum); } //成功 - public static ResponseModel success(){ + public static ResponseModel success() { return ResponseModel.successMsg("成功"); } - public static ResponseModel successMsg(String message){ + + public static ResponseModel successMsg(String message) { ResponseModel responseModel = new ResponseModel(); responseModel.setRepMsg(message); return responseModel; } - public static ResponseModel successData(Object data){ + + public static ResponseModel successData(Object data) { ResponseModel responseModel = new ResponseModel(); responseModel.setRepCode(RepCodeEnum.SUCCESS.getCode()); responseModel.setRepData(data); @@ -45,67 +49,45 @@ public class ResponseModel implements Serializable { } //失败 - public static ResponseModel errorMsg(RepCodeEnum message){ + public static ResponseModel errorMsg(RepCodeEnum message) { ResponseModel responseModel = new ResponseModel(); responseModel.setRepCodeEnum(message); return responseModel; } - public static ResponseModel errorMsg(String message){ + + public static ResponseModel errorMsg(String message) { ResponseModel responseModel = new ResponseModel(); responseModel.setRepCode(RepCodeEnum.ERROR.getCode()); responseModel.setRepMsg(message); return responseModel; } - public static ResponseModel errorMsg(RepCodeEnum repCodeEnum, String message){ + + public static ResponseModel errorMsg(RepCodeEnum repCodeEnum, String message) { ResponseModel responseModel = new ResponseModel(); responseModel.setRepCode(repCodeEnum.getCode()); responseModel.setRepMsg(message); return responseModel; } - public static ResponseModel exceptionMsg(String message){ + + public static ResponseModel exceptionMsg(String message) { ResponseModel responseModel = new ResponseModel(); responseModel.setRepCode(RepCodeEnum.EXCEPTION.getCode()); responseModel.setRepMsg(RepCodeEnum.EXCEPTION.getDesc() + ": " + message); return responseModel; } - @Override - public String toString() { - return "ResponseModel{" + "repCode='" + repCode + '\'' + ", repMsg='" - + repMsg + '\'' + ", repData=" + repData + '}'; - } - public boolean isSuccess(){ - return StringUtils.equals(repCode, RepCodeEnum.SUCCESS.getCode()); + public boolean isSuccess() { + return StrUtil.equals(repCode, RepCodeEnum.SUCCESS.getCode()); } public String getRepCode() { return repCode; } - public void setRepCode(String repCode) { - this.repCode = repCode; - } public void setRepCodeEnum(RepCodeEnum repCodeEnum) { - this.repCode=repCodeEnum.getCode(); - this.repMsg=repCodeEnum.getDesc(); + this.repCode = repCodeEnum.getCode(); + this.repMsg = repCodeEnum.getDesc(); } - public String getRepMsg() { - return repMsg; - } - - public void setRepMsg(String repMsg) { - this.repMsg = repMsg; - } - - public Object getRepData() { - return repData; - } - - public void setRepData(Object repData) { - this.repData = repData; - } - - } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/CaptchaVO.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/CaptchaVO.java index 3c6e0c330..9489707aa 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/CaptchaVO.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/CaptchaVO.java @@ -6,10 +6,13 @@ */ package com.anji.captcha.model.vo; +import lombok.Data; + import java.awt.*; import java.io.Serializable; import java.util.List; +@Data public class CaptchaVO implements Serializable { /** @@ -79,173 +82,23 @@ public class CaptchaVO implements Serializable { */ private String captchaVerification; - /*** - * 客户端UI组件id,组件初始化时设置一次,UUID - */ - private String clientUid; - /*** - * 客户端的请求时间,预留字段 - */ - private Long ts; + /*** + * 客户端UI组件id,组件初始化时设置一次,UUID + */ + private String clientUid; + /*** + * 客户端的请求时间,预留字段 + */ + private Long ts; /*** * 客户端ip+userAgent */ private String browserInfo; - public void resetClientFlag(){ + + public void resetClientFlag() { this.browserInfo = null; this.clientUid = null; } - public String getCaptchaId() { - return captchaId; - } - - public void setCaptchaId(String captchaId) { - this.captchaId = captchaId; - } - - public String getProjectCode() { - return projectCode; - } - - public void setProjectCode(String projectCode) { - this.projectCode = projectCode; - } - - public String getCaptchaType() { - return captchaType; - } - - public void setCaptchaType(String captchaType) { - this.captchaType = captchaType; - } - - public String getCaptchaOriginalPath() { - return captchaOriginalPath; - } - - public void setCaptchaOriginalPath(String captchaOriginalPath) { - this.captchaOriginalPath = captchaOriginalPath; - } - - public String getCaptchaFontType() { - return captchaFontType; - } - - public void setCaptchaFontType(String captchaFontType) { - this.captchaFontType = captchaFontType; - } - - public Integer getCaptchaFontSize() { - return captchaFontSize; - } - - public void setCaptchaFontSize(Integer captchaFontSize) { - this.captchaFontSize = captchaFontSize; - } - - public String getOriginalImageBase64() { - return originalImageBase64; - } - - public void setOriginalImageBase64(String originalImageBase64) { - this.originalImageBase64 = originalImageBase64; - } - - public PointVO getPoint() { - return point; - } - - public void setPoint(PointVO point) { - this.point = point; - } - - public String getJigsawImageBase64() { - return jigsawImageBase64; - } - - public void setJigsawImageBase64(String jigsawImageBase64) { - this.jigsawImageBase64 = jigsawImageBase64; - } - - public List getWordList() { - return wordList; - } - - public void setWordList(List wordList) { - this.wordList = wordList; - } - - public List getPointList() { - return pointList; - } - - public void setPointList(List pointList) { - this.pointList = pointList; - } - - public String getPointJson() { - return pointJson; - } - - public void setPointJson(String pointJson) { - this.pointJson = pointJson; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public Boolean getResult() { - return result; - } - - public void setResult(Boolean result) { - this.result = result; - } - - public String getCaptchaVerification() { - return captchaVerification; - } - - public void setCaptchaVerification(String captchaVerification) { - this.captchaVerification = captchaVerification; - } - - public String getSecretKey() { - return secretKey; - } - - public void setSecretKey(String secretKey) { - this.secretKey = secretKey; - } - - public String getClientUid() { - return clientUid; - } - - public void setClientUid(String clientUid) { - this.clientUid = clientUid; - } - - public Long getTs() { - return ts; - } - - public void setTs(Long ts) { - this.ts = ts; - } - - public String getBrowserInfo() { - return browserInfo; - } - - public void setBrowserInfo(String browserInfo) { - this.browserInfo = browserInfo; - } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/PointVO.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/PointVO.java index 5a943bf1c..c2954c8cf 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/PointVO.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/PointVO.java @@ -1,5 +1,7 @@ package com.anji.captcha.model.vo; +import lombok.Data; + import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -9,6 +11,7 @@ import java.util.regex.Pattern; /** * Created by raodeming on 2020/5/16. */ +@Data public class PointVO { private String secretKey; @@ -16,30 +19,6 @@ public class PointVO { public int y; - public String getSecretKey() { - return secretKey; - } - - public void setSecretKey(String secretKey) { - this.secretKey = secretKey; - } - - public int getX() { - return x; - } - - public void setX(int x) { - this.x = x; - } - - public int getY() { - return y; - } - - public void setY(int y) { - this.y = y; - } - public PointVO(int x, int y, String secretKey) { this.secretKey = secretKey; this.x = x; diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/properties/AjCaptchaProperties.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/properties/AjCaptchaProperties.java index fca735943..c6311af74 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/properties/AjCaptchaProperties.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/properties/AjCaptchaProperties.java @@ -1,6 +1,7 @@ package com.anji.captcha.properties; import com.anji.captcha.model.common.CaptchaTypeEnum; +import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import java.awt.*; @@ -8,6 +9,7 @@ import java.awt.*; import static com.anji.captcha.properties.AjCaptchaProperties.PREFIX; import static com.anji.captcha.properties.AjCaptchaProperties.StorageType.local; +@Data @ConfigurationProperties(PREFIX) public class AjCaptchaProperties { public static final String PREFIX = "aj.captcha"; @@ -113,90 +115,10 @@ public class AjCaptchaProperties { */ private int clickWordCount = 4; - public int getFontStyle() { - return fontStyle; - } - - public void setFontStyle(int fontStyle) { - this.fontStyle = fontStyle; - } - - public int getFontSize() { - return fontSize; - } - - public void setFontSize(int fontSize) { - this.fontSize = fontSize; - } - - public int getClickWordCount() { - return clickWordCount; - } - - public void setClickWordCount(int clickWordCount) { - this.clickWordCount = clickWordCount; - } - - public boolean isHistoryDataClearEnable() { - return historyDataClearEnable; - } - - public void setHistoryDataClearEnable(boolean historyDataClearEnable) { - this.historyDataClearEnable = historyDataClearEnable; - } - - public boolean isReqFrequencyLimitEnable() { - return reqFrequencyLimitEnable; - } - public boolean getReqFrequencyLimitEnable() { return reqFrequencyLimitEnable; } - public void setReqFrequencyLimitEnable(boolean reqFrequencyLimitEnable) { - this.reqFrequencyLimitEnable = reqFrequencyLimitEnable; - } - - public int getReqGetLockLimit() { - return reqGetLockLimit; - } - - public void setReqGetLockLimit(int reqGetLockLimit) { - this.reqGetLockLimit = reqGetLockLimit; - } - - public int getReqGetLockSeconds() { - return reqGetLockSeconds; - } - - public void setReqGetLockSeconds(int reqGetLockSeconds) { - this.reqGetLockSeconds = reqGetLockSeconds; - } - - public int getReqGetMinuteLimit() { - return reqGetMinuteLimit; - } - - public void setReqGetMinuteLimit(int reqGetMinuteLimit) { - this.reqGetMinuteLimit = reqGetMinuteLimit; - } - - public int getReqCheckMinuteLimit() { - return reqGetMinuteLimit; - } - - public void setReqCheckMinuteLimit(int reqCheckMinuteLimit) { - this.reqCheckMinuteLimit = reqCheckMinuteLimit; - } - - public int getReqVerifyMinuteLimit() { - return reqVerifyMinuteLimit; - } - - public void setReqVerifyMinuteLimit(int reqVerifyMinuteLimit) { - this.reqVerifyMinuteLimit = reqVerifyMinuteLimit; - } - public enum StorageType { /** * 内存. @@ -216,123 +138,4 @@ public class AjCaptchaProperties { return PREFIX; } - public CaptchaTypeEnum getType() { - return type; - } - - public void setType(CaptchaTypeEnum type) { - this.type = type; - } - - public String getJigsaw() { - return jigsaw; - } - - public void setJigsaw(String jigsaw) { - this.jigsaw = jigsaw; - } - - public String getPicClick() { - return picClick; - } - - public void setPicClick(String picClick) { - this.picClick = picClick; - } - - public String getWaterMark() { - return waterMark; - } - - public void setWaterMark(String waterMark) { - this.waterMark = waterMark; - } - - public String getWaterFont() { - return waterFont; - } - - public void setWaterFont(String waterFont) { - this.waterFont = waterFont; - } - - public String getFontType() { - return fontType; - } - - public void setFontType(String fontType) { - this.fontType = fontType; - } - - public String getSlipOffset() { - return slipOffset; - } - - public void setSlipOffset(String slipOffset) { - this.slipOffset = slipOffset; - } - - public Boolean getAesStatus() { - return aesStatus; - } - - public void setAesStatus(Boolean aesStatus) { - this.aesStatus = aesStatus; - } - - public StorageType getCacheType() { - return cacheType; - } - - public void setCacheType(StorageType cacheType) { - this.cacheType = cacheType; - } - - public String getInterferenceOptions() { - return interferenceOptions; - } - - public void setInterferenceOptions(String interferenceOptions) { - this.interferenceOptions = interferenceOptions; - } - - public String getCacheNumber() { - return cacheNumber; - } - - public void setCacheNumber(String cacheNumber) { - this.cacheNumber = cacheNumber; - } - - public String getTimingClear() { - return timingClear; - } - - public void setTimingClear(String timingClear) { - this.timingClear = timingClear; - } - - @Override - public String toString() { - return "\nAjCaptchaProperties{" + - "type=" + type + - ", jigsaw='" + jigsaw + '\'' + - ", picClick='" + picClick + '\'' + - ", waterMark='" + waterMark + '\'' + - ", waterFont='" + waterFont + '\'' + - ", fontType='" + fontType + '\'' + - ", slipOffset='" + slipOffset + '\'' + - ", aesStatus=" + aesStatus + - ", interferenceOptions='" + interferenceOptions + '\'' + - ", cacheNumber='" + cacheNumber + '\'' + - ", timingClear='" + timingClear + '\'' + - ", cacheType=" + cacheType + - ", reqFrequencyLimitEnable=" + reqFrequencyLimitEnable + - ", reqGetLockLimit=" + reqGetLockLimit + - ", reqGetLockSeconds=" + reqGetLockSeconds + - ", reqGetMinuteLimit=" + reqGetMinuteLimit + - ", reqCheckMinuteLimit=" + reqCheckMinuteLimit + - ", reqVerifyMinuteLimit=" + reqVerifyMinuteLimit + - '}'; - } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaCacheService.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaCacheService.java index fd401d6ea..55c662a8f 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaCacheService.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaCacheService.java @@ -8,34 +8,36 @@ package com.anji.captcha.service; /** * 验证码缓存接口 + * * @author lide1202@hotmail.com * @date 2018-08-21 */ public interface CaptchaCacheService { - void set(String key, String value, long expiresInSeconds); + void set(String key, String value, long expiresInSeconds); - boolean exists(String key); + boolean exists(String key); - void delete(String key); + void delete(String key); - String get(String key); + String get(String key); - /** - * 缓存类型-local/redis/memcache/.. - * 通过java SPI机制,接入方可自定义实现类 - * @return - */ - String type(); + /** + * 缓存类型-local/redis/memcache/.. + * 通过java SPI机制,接入方可自定义实现类 + * + * @return + */ + String type(); - /*** - * - * @param key - * @param val - * @return - */ - default Long increment(String key, long val){ - return 0L; - }; + /*** + * + * @param key + * @param val + * @return + */ + default Long increment(String key, long val) { + return 0L; + } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaService.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaService.java index 723bbb0d1..b9db2fbe2 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaService.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaService.java @@ -13,6 +13,7 @@ import java.util.Properties; /** * 验证码服务接口 + * * @author lide1202@hotmail.com * @date 2020-05-12 */ @@ -24,6 +25,7 @@ public interface CaptchaService { /** * 获取验证码 + * * @param captchaVO * @return */ @@ -31,6 +33,7 @@ public interface CaptchaService { /** * 核对验证码(前端) + * * @param captchaVO * @return */ @@ -38,6 +41,7 @@ public interface CaptchaService { /** * 二次校验验证码(后端) + * * @param captchaVO * @return */ @@ -50,9 +54,10 @@ public interface CaptchaService { */ String captchaType(); - /** - * 历史资源清除(过期的图片文件,生成的临时图片...) - * @param config 配置项 控制资源清理的粒度 - */ - void destroy(Properties config); + /** + * 历史资源清除(过期的图片文件,生成的临时图片...) + * + * @param config 配置项 控制资源清理的粒度 + */ + void destroy(Properties config); } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/AbstractCaptchaService.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/AbstractCaptchaService.java index b33d4ed53..037070f59 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/AbstractCaptchaService.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/AbstractCaptchaService.java @@ -6,6 +6,7 @@ */ package com.anji.captcha.service.impl; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.Const; import com.anji.captcha.model.common.RepCodeEnum; import com.anji.captcha.model.common.ResponseModel; @@ -13,29 +14,28 @@ import com.anji.captcha.model.vo.CaptchaVO; import com.anji.captcha.service.CaptchaCacheService; import com.anji.captcha.service.CaptchaService; import com.anji.captcha.util.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import java.awt.*; import java.io.File; -import java.io.FileOutputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Base64; +import java.util.Objects; import java.util.Properties; /** * Created by raodeming on 2019/12/25. */ +@Slf4j public abstract class AbstractCaptchaService implements CaptchaService { - protected Logger logger = LoggerFactory.getLogger(getClass()); - protected static final String IMAGE_TYPE_PNG = "png"; - protected static int HAN_ZI_SIZE = 25; + protected static int HAN_ZI_SIZE = 25; - protected static int HAN_ZI_SIZE_HALF = HAN_ZI_SIZE / 2; + protected static int HAN_ZI_SIZE_HALF = HAN_ZI_SIZE / 2; //check校验坐标 protected static String REDIS_CAPTCHA_KEY = "RUNNING:CAPTCHA:%s"; @@ -73,7 +73,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { ImageUtils.cacheImage(config.getProperty(Const.ORIGINAL_PATH_JIGSAW), config.getProperty(Const.ORIGINAL_PATH_PIC_CLICK)); } - logger.info("--->>>初始化验证码底图<<<---" + captchaType()); + log.info("--->>>初始化验证码底图<<<---" + captchaType()); waterMark = config.getProperty(Const.CAPTCHA_WATER_MARK, "我的水印"); slipOffset = config.getProperty(Const.CAPTCHA_SLIP_OFFSET, "5"); waterMarkFontStr = config.getProperty(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); @@ -88,13 +88,13 @@ public abstract class AbstractCaptchaService implements CaptchaService { // 通过加载resources下的font字体解决,无需在linux中安装字体 loadWaterMarkFont(); - if (cacheType.equals("local")) { - logger.info("初始化local缓存..."); + if ("local".equals(cacheType)) { + log.info("初始化local缓存..."); CacheUtil.init(Integer.parseInt(config.getProperty(Const.CAPTCHA_CACAHE_MAX_NUMBER, "1000")), Long.parseLong(config.getProperty(Const.CAPTCHA_TIMING_CLEAR_SECOND, "180"))); } - if (config.getProperty(Const.HISTORY_DATA_CLEAR_ENABLE, "0").equals("1")) { - logger.info("历史资源清除开关...开启..." + captchaType()); + if ("1".equals(config.getProperty(Const.HISTORY_DATA_CLEAR_ENABLE, "0"))) { + log.info("历史资源清除开关...开启..." + captchaType()); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { @@ -102,9 +102,9 @@ public abstract class AbstractCaptchaService implements CaptchaService { } })); } - if (config.getProperty(Const.REQ_FREQUENCY_LIMIT_ENABLE, "0").equals("1")) { + if ("1".equals(config.getProperty(Const.REQ_FREQUENCY_LIMIT_ENABLE, "0"))) { if (limitHandler == null) { - logger.info("接口分钟内限流开关...开启..."); + log.info("接口分钟内限流开关...开启..."); limitHandler = new FrequencyLimitHandler.DefaultLimitHandler(config, getCacheService(cacheType)); } } @@ -150,7 +150,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { if (captchaVO == null) { return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); } - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); } if (limitHandler != null) { @@ -163,17 +163,17 @@ public abstract class AbstractCaptchaService implements CaptchaService { return resp == null || resp.isSuccess(); } - protected String getValidateClientId(CaptchaVO req){ - // 以服务端获取的客户端标识 做识别标志 - if(StringUtils.isNotEmpty(req.getBrowserInfo())){ - return MD5Util.md5(req.getBrowserInfo()); - } - // 以客户端Ui组件id做识别标志 - if(StringUtils.isNotEmpty(req.getClientUid())){ - return req.getClientUid(); - } - return null; - } + protected String getValidateClientId(CaptchaVO req) { + // 以服务端获取的客户端标识 做识别标志 + if (StrUtil.isNotEmpty(req.getBrowserInfo())) { + return MD5Util.md5(req.getBrowserInfo()); + } + // 以客户端Ui组件id做识别标志 + if (StrUtil.isNotEmpty(req.getClientUid())) { + return req.getClientUid(); + } + return null; + } protected void afterValidateFail(CaptchaVO data) { if (limitHandler != null) { @@ -197,14 +197,14 @@ public abstract class AbstractCaptchaService implements CaptchaService { if (waterMarkFontStr.toLowerCase().endsWith(".ttf") || waterMarkFontStr.toLowerCase().endsWith(".ttc") || waterMarkFontStr.toLowerCase().endsWith(".otf")) { this.waterMarkFont = Font.createFont(Font.TRUETYPE_FONT, - getClass().getResourceAsStream("/fonts/" + waterMarkFontStr)) + Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + waterMarkFontStr))) .deriveFont(Font.BOLD, HAN_ZI_SIZE / 2); } else { this.waterMarkFont = new Font(waterMarkFontStr, Font.BOLD, HAN_ZI_SIZE / 2); } } catch (Exception e) { - logger.error("load font error:{}", e); + log.error("load font error:{}", e); } } @@ -228,7 +228,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { if (!tempFile.getParentFile().exists()) { tempFile.getParentFile().mkdirs(); } - OutputStream out = new FileOutputStream(tempFile); + OutputStream out = Files.newOutputStream(tempFile.toPath()); out.write(b); out.flush(); out.close(); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/BlockPuzzleCaptchaServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/BlockPuzzleCaptchaServiceImpl.java index 2fd7b0893..6f49a7714 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/BlockPuzzleCaptchaServiceImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/BlockPuzzleCaptchaServiceImpl.java @@ -6,12 +6,14 @@ */ package com.anji.captcha.service.impl; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.CaptchaTypeEnum; import com.anji.captcha.model.common.RepCodeEnum; import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; import com.anji.captcha.model.vo.PointVO; import com.anji.captcha.util.*; +import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; import java.awt.*; @@ -27,6 +29,7 @@ import java.util.Random; *

* Created by raodeming on 2019/12/25. */ +@Slf4j public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { @Override @@ -34,10 +37,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { super.init(config); } - @Override - public void destroy(Properties config) { - logger.info("start-clear-history-data-",captchaType()); - } + @Override + public void destroy(Properties config) { + log.info("start-clear-history-data-", captchaType()); + } @Override public String captchaType() { @@ -46,14 +49,14 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { @Override public ResponseModel get(CaptchaVO captchaVO) { - ResponseModel r = super.get(captchaVO); - if(!validatedReq(r)){ - return r; - } + ResponseModel r = super.get(captchaVO); + if (!validatedReq(r)) { + return r; + } //原生图片 BufferedImage originalImage = ImageUtils.getOriginal(); if (null == originalImage) { - logger.error("滑动底图未初始化成功,请检查路径"); + log.error("滑动底图未初始化成功,请检查路径"); return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); } //设置水印 @@ -68,13 +71,13 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { String jigsawImageBase64 = ImageUtils.getslidingBlock(); BufferedImage jigsawImage = ImageUtils.getBase64StrToImage(jigsawImageBase64); if (null == jigsawImage) { - logger.error("滑动底图未初始化成功,请检查路径"); + log.error("滑动底图未初始化成功,请检查路径"); return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); } CaptchaVO captcha = pictureTemplatesCut(originalImage, jigsawImage, jigsawImageBase64); if (captcha == null - || StringUtils.isBlank(captcha.getJigsawImageBase64()) - || StringUtils.isBlank(captcha.getOriginalImageBase64())) { + || StrUtil.isBlank(captcha.getJigsawImageBase64()) + || StrUtil.isBlank(captcha.getOriginalImageBase64())) { return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); } return ResponseModel.successData(captcha); @@ -82,10 +85,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { @Override public ResponseModel check(CaptchaVO captchaVO) { - ResponseModel r = super.check(captchaVO); - if(!validatedReq(r)){ - return r; - } + ResponseModel r = super.check(captchaVO); + if (!validatedReq(r)) { + return r; + } //取坐标信息 String codeKey = String.format(REDIS_CAPTCHA_KEY, captchaVO.getToken()); if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { @@ -103,7 +106,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { pointJson = decrypt(captchaVO.getPointJson(), point.getSecretKey()); point1 = JsonUtil.parseObject(pointJson, PointVO.class); } catch (Exception e) { - logger.error("验证码坐标解析失败", e); + log.error("验证码坐标解析失败", e); afterValidateFail(captchaVO); return ResponseModel.errorMsg(e.getMessage()); } @@ -119,7 +122,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { try { value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); } catch (Exception e) { - logger.error("AES加密失败", e); + log.error("AES加密失败", e); afterValidateFail(captchaVO); return ResponseModel.errorMsg(e.getMessage()); } @@ -132,10 +135,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { @Override public ResponseModel verification(CaptchaVO captchaVO) { - ResponseModel r = super.verification(captchaVO); - if(!validatedReq(r)){ - return r; - } + ResponseModel r = super.verification(captchaVO); + if (!validatedReq(r)) { + return r; + } try { String codeKey = String.format(REDIS_SECOND_CAPTCHA_KEY, captchaVO.getCaptchaVerification()); if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { @@ -144,7 +147,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { //二次校验取值后,即刻失效 CaptchaServiceFactory.getCache(cacheType).delete(codeKey); } catch (Exception e) { - logger.error("验证码坐标解析失败", e); + log.error("验证码坐标解析失败", e); return ResponseModel.errorMsg(e.getMessage()); } return ResponseModel.success(); @@ -234,7 +237,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { //将坐标信息存入redis中 String codeKey = String.format(REDIS_CAPTCHA_KEY, dataVO.getToken()); CaptchaServiceFactory.getCache(cacheType).set(codeKey, JsonUtil.toJSONString(point), EXPIRESIN_SECONDS); - logger.debug("token:{},point:{}", dataVO.getToken(), JsonUtil.toJSONString(point)); + log.debug("token:{},point:{}", dataVO.getToken(), JsonUtil.toJSONString(point)); return dataVO; } catch (Exception e) { e.printStackTrace(); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaCacheServiceMemImpl.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaCacheServiceMemImpl.java index 264c6c09c..7739b1a4b 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaCacheServiceMemImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaCacheServiceMemImpl.java @@ -3,12 +3,15 @@ package com.anji.captcha.service.impl; import com.anji.captcha.service.CaptchaCacheService; import com.anji.captcha.util.CacheUtil; +import java.util.Objects; + /** * 对于分布式部署的应用,我们建议应用自己实现CaptchaCacheService,比如用Redis,参考service/spring-boot代码示例。 * 如果应用是单点的,也没有使用redis,那默认使用内存。 * 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。 - * @Title: 默认使用内存当缓存 + * * @author lide1202@hotmail.com + * @Title: 默认使用内存当缓存 * @date 2020-05-12 */ public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { @@ -33,14 +36,14 @@ public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { return CacheUtil.get(key); } - @Override - public Long increment(String key, long val) { - Long ret = Long.valueOf(CacheUtil.get(key))+val; - CacheUtil.set(key,ret+"",0); - return ret; - } + @Override + public Long increment(String key, long val) { + Long ret = Long.parseLong(Objects.requireNonNull(CacheUtil.get(key))) + val; + CacheUtil.set(key, ret + "", 0); + return ret; + } - @Override + @Override public String type() { return "local"; } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaServiceFactory.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaServiceFactory.java index 6f3ff70fa..ceb91391a 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaServiceFactory.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/CaptchaServiceFactory.java @@ -3,8 +3,7 @@ package com.anji.captcha.service.impl; import com.anji.captcha.model.common.Const; import com.anji.captcha.service.CaptchaCacheService; import com.anji.captcha.service.CaptchaService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import java.util.HashMap; import java.util.Map; @@ -14,10 +13,9 @@ import java.util.ServiceLoader; /** * Created by raodeming on 2020/5/26. */ +@Slf4j public class CaptchaServiceFactory { - private static Logger logger = LoggerFactory.getLogger(CaptchaServiceFactory.class); - public static CaptchaService getInstance(Properties config) { //先把所有CaptchaService初始化,通过init方法,实例字体等,add by lide1202@hotmail.com /*try{ @@ -41,20 +39,20 @@ public class CaptchaServiceFactory { return cacheService.get(cacheType); } - public volatile static Map instances = new HashMap(); - public volatile static Map cacheService = new HashMap(); + public volatile static Map instances = new HashMap<>(); + public volatile static Map cacheService = new HashMap<>(); static { ServiceLoader cacheServices = ServiceLoader.load(CaptchaCacheService.class); for (CaptchaCacheService item : cacheServices) { cacheService.put(item.type(), item); } - logger.info("supported-captchaCache-service:{}", cacheService.keySet().toString()); + log.info("supported-captchaCache-service:{}", cacheService.keySet().toString()); ServiceLoader services = ServiceLoader.load(CaptchaService.class); for (CaptchaService item : services) { instances.put(item.captchaType(), item); } ; - logger.info("supported-captchaTypes-service:{}", instances.keySet().toString()); + log.info("supported-captchaTypes-service:{}", instances.keySet().toString()); } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/ClickWordCaptchaServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/ClickWordCaptchaServiceImpl.java index f208e0dd5..c5d338ffa 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/ClickWordCaptchaServiceImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/ClickWordCaptchaServiceImpl.java @@ -6,6 +6,7 @@ */ package com.anji.captcha.service.impl; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.CaptchaTypeEnum; import com.anji.captcha.model.common.Const; import com.anji.captcha.model.common.RepCodeEnum; @@ -13,6 +14,7 @@ import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; import com.anji.captcha.model.vo.PointVO; import com.anji.captcha.util.*; +import lombok.extern.slf4j.Slf4j; import java.awt.*; import java.awt.geom.AffineTransform; @@ -25,6 +27,7 @@ import java.util.*; *

* Created by raodeming on 2019/12/25. */ +@Slf4j public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { public static String HAN_ZI = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"; @@ -43,27 +46,27 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { super.init(config); clickWordFontStr = config.getProperty(Const.CAPTCHA_FONT_TYPE, "SourceHanSansCN-Normal.otf"); try { - int size = Integer.valueOf(config.getProperty(Const.CAPTCHA_FONT_SIZE,HAN_ZI_SIZE+"")); + int size = Integer.parseInt(config.getProperty(Const.CAPTCHA_FONT_SIZE,HAN_ZI_SIZE+"")); if (clickWordFontStr.toLowerCase().endsWith(".ttf") || clickWordFontStr.toLowerCase().endsWith(".ttc") || clickWordFontStr.toLowerCase().endsWith(".otf")) { this.clickWordFont = Font.createFont(Font.TRUETYPE_FONT, - getClass().getResourceAsStream("/fonts/" + clickWordFontStr)) + Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + clickWordFontStr))) .deriveFont(Font.BOLD, size); } else { - int style = Integer.valueOf(config.getProperty(Const.CAPTCHA_FONT_STYLE,Font.BOLD+"")); + int style = Integer.parseInt(config.getProperty(Const.CAPTCHA_FONT_STYLE,Font.BOLD+"")); this.clickWordFont = new Font(clickWordFontStr, style, size); } } catch (Exception ex) { - logger.error("load font error:{}", ex); + log.error("load font error:{}", ex); } - this.wordTotalCount = Integer.valueOf(config.getProperty(Const.CAPTCHA_WORD_COUNT,"4")); + this.wordTotalCount = Integer.parseInt(config.getProperty(Const.CAPTCHA_WORD_COUNT,"4")); } @Override public void destroy(Properties config) { - logger.info("start-clear-history-data-", captchaType()); + log.info("start-clear-history-data-", captchaType()); } @Override @@ -74,12 +77,12 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { } BufferedImage bufferedImage = ImageUtils.getPicClick(); if (null == bufferedImage) { - logger.error("滑动底图未初始化成功,请检查路径"); + log.error("滑动底图未初始化成功,请检查路径"); return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); } CaptchaVO imageData = getImageData(bufferedImage); if (imageData == null - || StringUtils.isBlank(imageData.getOriginalImageBase64())) { + || StrUtil.isBlank(imageData.getOriginalImageBase64())) { return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); } return ResponseModel.successData(imageData); @@ -124,7 +127,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { pointJson = decrypt(captchaVO.getPointJson(), point.get(0).getSecretKey()); point1 = JsonUtil.parseArray(pointJson, PointVO.class); } catch (Exception e) { - logger.error("验证码坐标解析失败", e); + log.error("验证码坐标解析失败", e); afterValidateFail(captchaVO); return ResponseModel.errorMsg(e.getMessage()); } @@ -143,7 +146,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { try { value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); } catch (Exception e) { - logger.error("AES加密失败", e); + log.error("AES加密失败", e); afterValidateFail(captchaVO); return ResponseModel.errorMsg(e.getMessage()); } @@ -159,7 +162,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { /*if (captchaVO == null) { return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); } - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); }*/ ResponseModel r = super.verification(captchaVO); @@ -174,7 +177,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { //二次校验取值后,即刻失效 CaptchaServiceFactory.getCache(cacheType).delete(codeKey); } catch (Exception e) { - logger.error("验证码坐标解析失败", e); + log.error("验证码坐标解析失败", e); return ResponseModel.errorMsg(e.getMessage()); } return ResponseModel.success(); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/DefaultCaptchaServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/DefaultCaptchaServiceImpl.java index 18c2180e6..e9843765a 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/DefaultCaptchaServiceImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/DefaultCaptchaServiceImpl.java @@ -6,17 +6,19 @@ */ package com.anji.captcha.service.impl; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.RepCodeEnum; import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; import com.anji.captcha.service.CaptchaService; -import com.anji.captcha.util.StringUtils; +import lombok.extern.slf4j.Slf4j; import java.util.Properties; /** * Created by raodeming on 2019/12/25. */ +@Slf4j public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ @Override @@ -53,7 +55,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ if (captchaVO == null) { return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); } - if (StringUtils.isEmpty(captchaVO.getCaptchaType())) { + if (StrUtil.isEmpty(captchaVO.getCaptchaType())) { return RepCodeEnum.NULL_ERROR.parseError("类型"); } return getService(captchaVO.getCaptchaType()).get(captchaVO); @@ -64,10 +66,10 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ if (captchaVO == null) { return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); } - if (StringUtils.isEmpty(captchaVO.getCaptchaType())) { + if (StrUtil.isEmpty(captchaVO.getCaptchaType())) { return RepCodeEnum.NULL_ERROR.parseError("类型"); } - if (StringUtils.isEmpty(captchaVO.getToken())) { + if (StrUtil.isEmpty(captchaVO.getToken())) { return RepCodeEnum.NULL_ERROR.parseError("token"); } return getService(captchaVO.getCaptchaType()).check(captchaVO); @@ -78,7 +80,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ if (captchaVO == null) { return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); } - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { return RepCodeEnum.NULL_ERROR.parseError("二次校验参数"); } try { @@ -89,7 +91,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ //二次校验取值后,即刻失效 CaptchaServiceFactory.getCache(cacheType).delete(codeKey); } catch (Exception e) { - logger.error("验证码坐标解析失败", e); + log.error("验证码坐标解析失败", e); return ResponseModel.errorMsg(e.getMessage()); } return ResponseModel.success(); diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/FrequencyLimitHandler.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/FrequencyLimitHandler.java index ffbceb5a9..a477db2f9 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/FrequencyLimitHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/FrequencyLimitHandler.java @@ -1,11 +1,11 @@ package com.anji.captcha.service.impl; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.Const; import com.anji.captcha.model.common.RepCodeEnum; import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; import com.anji.captcha.service.CaptchaCacheService; -import com.anji.captcha.util.StringUtils; import java.util.Objects; import java.util.Properties; @@ -66,15 +66,15 @@ public interface FrequencyLimitHandler { } private String getClientCId(CaptchaVO input, String type) { - return String.format(LIMIT_KEY ,type,input.getClientUid()); + return String.format(LIMIT_KEY, type, input.getClientUid()); } @Override public ResponseModel validateGet(CaptchaVO d) { - // 无客户端身份标识,不限制 - if(StringUtils.isEmpty(d.getClientUid())){ - return null; - } + // 无客户端身份标识,不限制 + if (StrUtil.isEmpty(d.getClientUid())) { + return null; + } String getKey = getClientCId(d, "GET"); String lockKey = getClientCId(d, "LOCK"); // 失败次数过多,锁定 @@ -88,7 +88,7 @@ public interface FrequencyLimitHandler { } cacheService.increment(getKey, 1); // 1分钟内请求次数过多 - if (Long.valueOf(getCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_MINUTE_LIMIT, "120"))) { + if (Long.parseLong(getCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_MINUTE_LIMIT, "120"))) { return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_GET_ERROR); } @@ -100,9 +100,9 @@ public interface FrequencyLimitHandler { return null; } // 1分钟内失败5次 - if (Long.valueOf(failCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_LOCK_LIMIT, "5"))) { + if (Long.parseLong(failCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_LOCK_LIMIT, "5"))) { // get接口锁定5分钟 - cacheService.set(lockKey, "1", Long.valueOf(config.getProperty(Const.REQ_GET_LOCK_SECONDS, "300"))); + cacheService.set(lockKey, "1", Long.parseLong(config.getProperty(Const.REQ_GET_LOCK_SECONDS, "300"))); return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LOCK_GET_ERROR); } return null; @@ -110,10 +110,10 @@ public interface FrequencyLimitHandler { @Override public ResponseModel validateCheck(CaptchaVO d) { - // 无客户端身份标识,不限制 - if(StringUtils.isEmpty(d.getClientUid())){ - return null; - } + // 无客户端身份标识,不限制 + if (StrUtil.isEmpty(d.getClientUid())) { + return null; + } /*String getKey = getClientCId(d, "GET"); if(Objects.isNull(cacheService.get(getKey))){ return ResponseModel.errorMsg(RepCodeEnum.API_REQ_INVALID); @@ -125,7 +125,7 @@ public interface FrequencyLimitHandler { v = "1"; } cacheService.increment(key, 1); - if (Long.valueOf(v) > Long.valueOf(config.getProperty(Const.REQ_CHECK_MINUTE_LIMIT, "600"))) { + if (Long.parseLong(v) > Long.parseLong(config.getProperty(Const.REQ_CHECK_MINUTE_LIMIT, "600"))) { return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_CHECK_ERROR); } return null; @@ -144,7 +144,7 @@ public interface FrequencyLimitHandler { v = "1"; } cacheService.increment(key, 1); - if (Long.valueOf(v) > Long.valueOf(config.getProperty(Const.REQ_VALIDATE_MINUTE_LIMIT, "600"))) { + if (Long.parseLong(v) > Long.parseLong(config.getProperty(Const.REQ_VALIDATE_MINUTE_LIMIT, "600"))) { return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_VERIFY_ERROR); } return null; diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/AESUtil.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/AESUtil.java index d8ea95b8d..07cc86f54 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/AESUtil.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/AESUtil.java @@ -7,10 +7,13 @@ package com.anji.captcha.util; +import cn.hutool.core.util.StrUtil; + import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.SecretKeySpec; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -20,6 +23,7 @@ public class AESUtil { /** * 获取随机key + * * @return */ public static String getKey() { @@ -29,39 +33,43 @@ public class AESUtil { /** * 将byte[]转为各种进制的字符串 + * * @param bytes byte[] * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 * @return 转换后的字符串 */ - public static String binary(byte[] bytes, int radix){ + public static String binary(byte[] bytes, int radix) { return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 } /** * base 64 encode + * * @param bytes 待编码的byte[] * @return 编码后的base 64 code */ - public static String base64Encode(byte[] bytes){ + public static String base64Encode(byte[] bytes) { //return Base64.encodeBase64String(bytes); return Base64.getEncoder().encodeToString(bytes); } /** * base 64 decode + * * @param base64Code 待解码的base 64 code * @return 解码后的byte[] * @throws Exception */ - public static byte[] base64Decode(String base64Code) throws Exception{ + public static byte[] base64Decode(String base64Code) throws Exception { Base64.Decoder decoder = Base64.getDecoder(); - return StringUtils.isEmpty(base64Code) ? null : decoder.decode(base64Code); + return StrUtil.isEmpty(base64Code) ? null : decoder.decode(base64Code); } /** * AES加密 - * @param content 待加密的内容 + * + * @param content 待加密的内容 * @param encryptKey 加密密钥 * @return 加密后的byte[] * @throws Exception @@ -72,19 +80,20 @@ public class AESUtil { Cipher cipher = Cipher.getInstance(ALGORITHMSTR); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES")); - return cipher.doFinal(content.getBytes("utf-8")); + return cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)); } /** * AES加密为base 64 code - * @param content 待加密的内容 + * + * @param content 待加密的内容 * @param encryptKey 加密密钥 * @return 加密后的base 64 code * @throws Exception */ public static String aesEncrypt(String content, String encryptKey) throws Exception { - if (StringUtils.isBlank(encryptKey)) { + if (StrUtil.isBlank(encryptKey)) { return content; } return base64Encode(aesEncryptToBytes(content, encryptKey)); @@ -92,8 +101,9 @@ public class AESUtil { /** * AES解密 + * * @param encryptBytes 待解密的byte[] - * @param decryptKey 解密密钥 + * @param decryptKey 解密密钥 * @return 解密后的String * @throws Exception */ @@ -110,16 +120,17 @@ public class AESUtil { /** * 将base 64 code AES解密 + * * @param encryptStr 待解密的base 64 code * @param decryptKey 解密密钥 * @return 解密后的string * @throws Exception */ public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { - if (StringUtils.isBlank(decryptKey)) { + if (StrUtil.isBlank(decryptKey)) { return encryptStr; } - return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); + return StrUtil.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); } /** diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/Base64Utils.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/Base64Utils.java deleted file mode 100644 index 756689ed9..000000000 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/Base64Utils.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// Source code recreated from a .class file by IntelliJ IDEA -// (powered by Fernflower decompiler) -// - -package com.anji.captcha.util; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Base64; - -public abstract class Base64Utils { - private static final Charset DEFAULT_CHARSET; - - public Base64Utils() { - } - - public static byte[] encode(byte[] src) { - return src.length == 0 ? src : Base64.getEncoder().encode(src); - } - - public static byte[] decode(byte[] src) { - return src.length == 0 ? src : Base64.getDecoder().decode(src); - } - - public static byte[] encodeUrlSafe(byte[] src) { - return src.length == 0 ? src : Base64.getUrlEncoder().encode(src); - } - - public static byte[] decodeUrlSafe(byte[] src) { - return src.length == 0 ? src : Base64.getUrlDecoder().decode(src); - } - - public static String encodeToString(byte[] src) { - return src.length == 0 ? "" : new String(encode(src), DEFAULT_CHARSET); - } - - public static byte[] decodeFromString(String src) { - return src.isEmpty() ? new byte[0] : decode(src.getBytes(DEFAULT_CHARSET)); - } - - public static String encodeToUrlSafeString(byte[] src) { - return new String(encodeUrlSafe(src), DEFAULT_CHARSET); - } - - public static byte[] decodeFromUrlSafeString(String src) { - return decodeUrlSafe(src.getBytes(DEFAULT_CHARSET)); - } - - static { - DEFAULT_CHARSET = StandardCharsets.UTF_8; - } -} diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/CacheUtil.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/CacheUtil.java index 5f0fd450c..617993526 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/CacheUtil.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/CacheUtil.java @@ -24,8 +24,9 @@ public final class CacheUtil { /** * 初始化 + * * @param cacheMaxNumber 缓存最大个数 - * @param second 定时任务 秒执行清除过期缓存 + * @param second 定时任务 秒执行清除过期缓存 */ public static void init(int cacheMaxNumber, long second) { CACHE_MAX_NUMBER = cacheMaxNumber; @@ -37,27 +38,25 @@ public final class CacheUtil { refresh(); } }, 0, second * 1000);*/ - scheduledExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - return new Thread(r,"thd-captcha-cache-clean"); - } - },new ThreadPoolExecutor.CallerRunsPolicy()); + ScheduledExecutorService scheduledExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "thd-captcha-cache-clean"); + } + }, new ThreadPoolExecutor.CallerRunsPolicy()); scheduledExecutor.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - refresh(); - } - },10,second,TimeUnit.SECONDS); + @Override + public void run() { + refresh(); + } + }, 10, second, TimeUnit.SECONDS); } } - private static ScheduledExecutorService scheduledExecutor; - /** * 缓存刷新,清除过期数据 */ - public static void refresh(){ + public static void refresh() { logger.debug("local缓存刷新,清除过期数据"); for (String key : CACHE_MAP.keySet()) { exists(key); @@ -65,24 +64,24 @@ public final class CacheUtil { } - public static void set(String key, String value, long expiresInSeconds){ + public static void set(String key, String value, long expiresInSeconds) { //设置阈值,达到即clear缓存 if (CACHE_MAP.size() > CACHE_MAX_NUMBER * 2) { logger.info("CACHE_MAP达到阈值,clear map"); clear(); } CACHE_MAP.put(key, value); - if(expiresInSeconds >0) { - CACHE_MAP.put(key + "_HoldTime", System.currentTimeMillis() + expiresInSeconds * 1000);//缓存失效时间 - } + if (expiresInSeconds > 0) { + CACHE_MAP.put(key + "_HoldTime", System.currentTimeMillis() + expiresInSeconds * 1000);//缓存失效时间 + } } - public static void delete(String key){ + public static void delete(String key) { CACHE_MAP.remove(key); CACHE_MAP.remove(key + "_HoldTime"); } - public static boolean exists(String key){ + public static boolean exists(String key) { Long cacheHoldTime = (Long) CACHE_MAP.get(key + "_HoldTime"); if (cacheHoldTime == null || cacheHoldTime == 0L) { return false; @@ -95,9 +94,9 @@ public final class CacheUtil { } - public static String get(String key){ + public static String get(String key) { if (exists(key)) { - return (String)CACHE_MAP.get(key); + return (String) CACHE_MAP.get(key); } return null; } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/FileCopyUtils.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/FileCopyUtils.java index a3d82db41..057caa921 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/FileCopyUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/FileCopyUtils.java @@ -18,7 +18,7 @@ public abstract class FileCopyUtils { } public static void copy(byte[] in, File out) throws IOException { - copy((InputStream)(new ByteArrayInputStream(in)), (OutputStream)Files.newOutputStream(out.toPath())); + copy((InputStream) (new ByteArrayInputStream(in)), (OutputStream) Files.newOutputStream(out.toPath())); } public static byte[] copyToByteArray(File in) throws IOException { @@ -63,7 +63,7 @@ public abstract class FileCopyUtils { return new byte[0]; } else { ByteArrayOutputStream out = new ByteArrayOutputStream(4096); - copy((InputStream)in, (OutputStream)out); + copy((InputStream) in, (OutputStream) out); return out.toByteArray(); } } @@ -74,13 +74,12 @@ public abstract class FileCopyUtils { char[] buffer = new char[4096]; int bytesRead; - for(boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { + for (boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { out.write(buffer, 0, bytesRead); } out.flush(); - int var5 = byteCount; - return var5; + return byteCount; } finally { try { in.close(); @@ -113,7 +112,7 @@ public abstract class FileCopyUtils { return ""; } else { StringWriter out = new StringWriter(); - copy((Reader)in, (Writer)out); + copy((Reader) in, (Writer) out); return out.toString(); } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/ImageUtils.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/ImageUtils.java index 9d9d88afe..0e822cccd 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/ImageUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/ImageUtils.java @@ -6,9 +6,10 @@ */ package com.anji.captcha.util; +import cn.hutool.core.util.StrUtil; import com.anji.captcha.model.common.CaptchaBaseMapEnum; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.Base64Utils; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; @@ -19,9 +20,8 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - +@Slf4j public class ImageUtils { - private static Logger logger = LoggerFactory.getLogger(ImageUtils.class); private static Map originalCacheMap = new ConcurrentHashMap(); //滑块底图 private static Map slidingBlockCacheMap = new ConcurrentHashMap(); //滑块 private static Map picClickCacheMap = new ConcurrentHashMap(); //点选文字 @@ -29,7 +29,7 @@ public class ImageUtils { public static void cacheImage(String captchaOriginalPathJigsaw, String captchaOriginalPathClick) { //滑动拼图 - if (StringUtils.isBlank(captchaOriginalPathJigsaw)) { + if (StrUtil.isBlank(captchaOriginalPathJigsaw)) { originalCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/original")); slidingBlockCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/slidingBlock")); } else { @@ -37,7 +37,7 @@ public class ImageUtils { slidingBlockCacheMap.putAll(getImagesFile(captchaOriginalPathJigsaw + File.separator + "slidingBlock")); } //点选文字 - if (StringUtils.isBlank(captchaOriginalPathClick)) { + if (StrUtil.isBlank(captchaOriginalPathClick)) { picClickCacheMap.putAll(getResourcesImagesFile("defaultImages/pic-click")); } else { picClickCacheMap.putAll(getImagesFile(captchaOriginalPathClick)); @@ -45,7 +45,7 @@ public class ImageUtils { fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); fileNameMap.put(CaptchaBaseMapEnum.PIC_CLICK.getCodeValue(), picClickCacheMap.keySet().toArray(new String[0])); - logger.info("初始化底图:{}", JsonUtil.toJSONString(fileNameMap)); + log.info("初始化底图:{}", JsonUtil.toJSONString(fileNameMap)); } public static void cacheBootImage(Map originalMap, Map slidingBlockMap, Map picClickMap) { @@ -55,7 +55,7 @@ public class ImageUtils { fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); fileNameMap.put(CaptchaBaseMapEnum.PIC_CLICK.getCodeValue(), picClickCacheMap.keySet().toArray(new String[0])); - logger.info("自定义resource底图:{}", JsonUtil.toJSONString(fileNameMap)); + log.info("自定义resource底图:{}", JsonUtil.toJSONString(fileNameMap)); } @@ -75,8 +75,7 @@ public class ImageUtils { return null; } Integer randomInt = RandomUtils.getRandomInt(0, strings.length); - String s = slidingBlockCacheMap.get(strings[randomInt]); - return s; + return slidingBlockCacheMap.get(strings[randomInt]); } public static BufferedImage getPicClick() { @@ -160,8 +159,6 @@ public class ImageUtils { byte[] bytes = FileCopyUtils.copyToByteArray(fileInputStream); String string = Base64Utils.encodeToString(bytes); imgMap.put(item.getName(), string); - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/JsonUtil.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/JsonUtil.java index 06ff7d2ea..ee2e34894 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/JsonUtil.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/JsonUtil.java @@ -1,8 +1,7 @@ package com.anji.captcha.util; import com.anji.captcha.model.vo.PointVO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; @@ -12,63 +11,63 @@ import java.util.Map; * 替换掉fastjson,自定义实现相关方法 * note: 该实现不具有通用性,仅用于本项目。 * - *@author WongBin - *@date 2021/1/8 + * @author WongBin + * @date 2021/1/8 */ +@Slf4j public class JsonUtil { - private static Logger logger = LoggerFactory.getLogger(JsonUtil.class); - public static List parseArray(String text, Class clazz) { - if (text == null) { - return null; - } else { - String[] arr = text.replaceFirst("\\[","") - .replaceFirst("\\]","").split("\\}"); - List ret = new ArrayList<>(arr.length); - for (String s : arr) { - ret.add(parseObject(s,PointVO.class)); - } - return ret; - } - } + public static List parseArray(String text, Class clazz) { + if (text == null) { + return null; + } else { + String[] arr = text.replaceFirst("\\[", "") + .replaceFirst("\\]", "").split("\\}"); + List ret = new ArrayList<>(arr.length); + for (String s : arr) { + ret.add(parseObject(s, PointVO.class)); + } + return ret; + } + } - public static PointVO parseObject(String text, Class clazz) { - if(text == null) { - return null; - } + public static PointVO parseObject(String text, Class clazz) { + if (text == null) { + return null; + } /*if(!clazz.isAssignableFrom(PointVO.class)) { throw new UnsupportedOperationException("不支持的输入类型:" + clazz.getSimpleName()); }*/ - try { - PointVO ret = clazz.newInstance(); - return ret.parse(text); - }catch (Exception ex){ - logger.error("json解析异常", ex); + try { + PointVO ret = clazz.newInstance(); + return ret.parse(text); + } catch (Exception ex) { + log.error("json解析异常", ex); - } - return null; - } + } + return null; + } - public static String toJSONString(Object object) { - if(object == null) { - return "{}"; - } - if(object instanceof PointVO){ - PointVO t = (PointVO)object; - return t.toJsonString(); - } - if(object instanceof List){ - List list = (List)object; - StringBuilder buf = new StringBuilder("["); - list.stream().forEach(t->{ - buf.append(t.toJsonString()).append(","); - }); - return buf.deleteCharAt(buf.lastIndexOf(",")).append("]").toString(); - } - if(object instanceof Map){ - return ((Map)object).entrySet().toString(); - } - throw new UnsupportedOperationException("不支持的输入类型:" - +object.getClass().getSimpleName()); - } + public static String toJSONString(Object object) { + if (object == null) { + return "{}"; + } + if (object instanceof PointVO) { + PointVO t = (PointVO) object; + return t.toJsonString(); + } + if (object instanceof List) { + List list = (List) object; + StringBuilder buf = new StringBuilder("["); + list.forEach(t -> { + buf.append(t.toJsonString()).append(","); + }); + return buf.deleteCharAt(buf.lastIndexOf(",")).append("]").toString(); + } + if (object instanceof Map) { + return ((Map) object).entrySet().toString(); + } + throw new UnsupportedOperationException("不支持的输入类型:" + + object.getClass().getSimpleName()); + } } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/MD5Util.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/MD5Util.java index be9824ab4..3bb2f6ef6 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/MD5Util.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/MD5Util.java @@ -1,5 +1,6 @@ package com.anji.captcha.util; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; /** @@ -8,17 +9,18 @@ import java.security.MessageDigest; public abstract class MD5Util { /** * 获取指定字符串的md5值 + * * @param dataStr 明文 * @return String */ public static String md5(String dataStr) { try { MessageDigest m = MessageDigest.getInstance("MD5"); - m.update(dataStr.getBytes("UTF8")); + m.update(dataStr.getBytes(StandardCharsets.UTF_8)); byte[] s = m.digest(); StringBuilder result = new StringBuilder(); - for (int i = 0; i < s.length; i++) { - result.append(Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00).substring(6)); + for (byte b : s) { + result.append(Integer.toHexString((0x000000FF & b) | 0xFFFFFF00).substring(6)); } return result.toString(); } catch (Exception e) { @@ -29,10 +31,11 @@ public abstract class MD5Util { /** * 获取指定字符串的md5值, md5(str+salt) + * * @param dataStr 明文 * @return String */ - public static String md5WithSalt(String dataStr,String salt) { + public static String md5WithSalt(String dataStr, String salt) { return md5(dataStr + salt); } diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/RandomUtils.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/RandomUtils.java index 48395d4e8..819cf2f30 100644 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/RandomUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/RandomUtils.java @@ -31,11 +31,10 @@ public class RandomUtils { * @return */ public static String getRandomHan(String hanZi) { - String ch = hanZi.charAt(new Random().nextInt(hanZi.length())) + ""; - return ch; + return hanZi.charAt(new Random().nextInt(hanZi.length())) + ""; } - public static int getRandomInt(int bound){ + public static int getRandomInt(int bound) { return ThreadLocalRandom.current().nextInt(bound); } @@ -68,25 +67,27 @@ public class RandomUtils { /** * 随机范围内数字 + * * @param startNum * @param endNum * @return */ public static Integer getRandomInt(int startNum, int endNum) { - return ThreadLocalRandom.current().nextInt(endNum-startNum) + startNum; + return ThreadLocalRandom.current().nextInt(endNum - startNum) + startNum; } /** * 获取随机字符串 + * * @param length * @return */ - public static String getRandomString(int length){ - String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - Random random=new Random(); - StringBuffer sb=new StringBuffer(); - for(int i=0;i 0L) { + while (bytesToCopy > 0L) { int bytesRead = in.read(buffer); if (bytesRead == -1) { break; } - if ((long)bytesRead <= bytesToCopy) { + if ((long) bytesRead <= bytesToCopy) { out.write(buffer, 0, bytesRead); - bytesToCopy -= (long)bytesRead; + bytesToCopy -= (long) bytesRead; } else { - out.write(buffer, 0, (int)bytesToCopy); + out.write(buffer, 0, (int) bytesToCopy); bytesToCopy = 0L; } } @@ -96,7 +95,7 @@ public abstract class StreamUtils { byte[] buffer = new byte[4096]; int byteCount; int bytesRead; - for(byteCount = 0; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { + for (byteCount = 0; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { } return byteCount; diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/StringUtils.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/StringUtils.java deleted file mode 100644 index e9286532f..000000000 --- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/StringUtils.java +++ /dev/null @@ -1,1742 +0,0 @@ -/* - *Copyright © 2018 anji-plus - *安吉加加信息技术有限公司 - *http://www.anji-plus.com - *All rights reserved. - */ -package com.anji.captcha.util; - -public class StringUtils { - - /** - * The empty String "". - * @since 2.0 - */ - public static final String EMPTY = ""; - - /** - * Represents a failed index search. - * @since 2.1 - */ - public static final int INDEX_NOT_FOUND = -1; - - /** - *

The maximum size to which the padding constant(s) can expand.

- */ - private static final int PAD_LIMIT = 8192; - - /** - *

StringUtils instances should NOT be constructed in - * standard programming. Instead, the class should be used as - * StringUtils.trim(" foo ");.

- * - *

This constructor is public to permit tools that require a JavaBean - * instance to operate.

- */ - public StringUtils() { - super(); - } - - // Empty checks - //----------------------------------------------------------------------- - /** - *

Checks if a String is empty ("") or null.

- * - *
-     * StringUtils.isEmpty(null)      = true
-     * StringUtils.isEmpty("")        = true
-     * StringUtils.isEmpty(" ")       = false
-     * StringUtils.isEmpty("bob")     = false
-     * StringUtils.isEmpty("  bob  ") = false
-     * 
- * - *

NOTE: This method changed in Lang version 2.0. - * It no longer trims the String. - * That functionality is available in isBlank().

- * - * @param str the String to check, may be null - * @return true if the String is empty or null - */ - public static boolean isEmpty(String str) { - return str == null || str.length() == 0; - } - - /** - *

Checks if a String is not empty ("") and not null.

- * - *
-     * StringUtils.isNotEmpty(null)      = false
-     * StringUtils.isNotEmpty("")        = false
-     * StringUtils.isNotEmpty(" ")       = true
-     * StringUtils.isNotEmpty("bob")     = true
-     * StringUtils.isNotEmpty("  bob  ") = true
-     * 
- * - * @param str the String to check, may be null - * @return true if the String is not empty and not null - */ - public static boolean isNotEmpty(String str) { - return !StringUtils.isEmpty(str); - } - - /** - *

Checks if a String is whitespace, empty ("") or null.

- * - *
-     * StringUtils.isBlank(null)      = true
-     * StringUtils.isBlank("null")      = true
-     * StringUtils.isBlank("")        = true
-     * StringUtils.isBlank(" ")       = true
-     * StringUtils.isBlank("bob")     = false
-     * StringUtils.isBlank("  bob  ") = false
-     * 
- * - * @param str the String to check, may be null - * @return true if the String is null, empty or whitespace - * @since 2.0 - */ - public static boolean isBlank(String str) { - int strLen; - if (str == null || (strLen = str.length()) == 0) { - return true; - } - if(equals("null", str.trim().toLowerCase())){ - return true; - } - for (int i = 0; i < strLen; i++) { - if ((Character.isWhitespace(str.charAt(i)) == false)) { - return false; - } - } - return true; - } - - /** - *

Checks if a String is not empty (""), not null and not whitespace only.

- * - *
-     * StringUtils.isNotBlank(null)      = false
-     * StringUtils.isNotBlank("null")    = false
-     * StringUtils.isNotBlank("")        = false
-     * StringUtils.isNotBlank(" ")       = false
-     * StringUtils.isNotBlank("bob")     = true
-     * StringUtils.isNotBlank("  bob  ") = true
-     * 
- * - * @param str the String to check, may be null - * @return true if the String is - * not empty and not null and not whitespace - * @since 2.0 - */ - public static boolean isNotBlank(String str) { - return !StringUtils.isBlank(str); - } - - // Trim - //----------------------------------------------------------------------- - /** - *

Removes control characters (char <= 32) from both - * ends of this String, handling null by returning - * an empty String ("").

- * - *
-     * StringUtils.clean(null)          = ""
-     * StringUtils.clean("")            = ""
-     * StringUtils.clean("abc")         = "abc"
-     * StringUtils.clean("    abc    ") = "abc"
-     * StringUtils.clean("     ")       = ""
-     * 
- * - * @see String#trim() - * @param str the String to clean, may be null - * @return the trimmed text, never null - * @deprecated Use the clearer named {@link #trimToEmpty(String)}. - * Method will be removed in Commons Lang 3.0. - */ - public static String clean(String str) { - return str == null ? EMPTY : str.trim(); - } - - /** - *

Removes control characters (char <= 32) from both - * ends of this String, handling null by returning - * null.

- * - *

The String is trimmed using {@link String#trim()}. - * Trim removes start and end characters <= 32. - * To strip whitespace use {@link #strip(String)}.

- * - *

To trim your choice of characters, use the - * {@link #strip(String, String)} methods.

- * - *
-     * StringUtils.trim(null)          = null
-     * StringUtils.trim("")            = ""
-     * StringUtils.trim("     ")       = ""
-     * StringUtils.trim("abc")         = "abc"
-     * StringUtils.trim("    abc    ") = "abc"
-     * 
- * - * @param str the String to be trimmed, may be null - * @return the trimmed string, null if null String input - */ - public static String trim(String str) { - return str == null ? null : str.trim(); - } - - /** - *

Removes control characters (char <= 32) from both - * ends of this String returning null if the String is - * empty ("") after the trim or if it is null. - * - *

The String is trimmed using {@link String#trim()}. - * Trim removes start and end characters <= 32. - * To strip whitespace use {@link #stripToNull(String)}.

- * - *
-     * StringUtils.trimToNull(null)          = null
-     * StringUtils.trimToNull("")            = null
-     * StringUtils.trimToNull("     ")       = null
-     * StringUtils.trimToNull("abc")         = "abc"
-     * StringUtils.trimToNull("    abc    ") = "abc"
-     * 
- * - * @param str the String to be trimmed, may be null - * @return the trimmed String, - * null if only chars <= 32, empty or null String input - * @since 2.0 - */ - public static String trimToNull(String str) { - String ts = trim(str); - return isEmpty(ts) ? null : ts; - } - - /** - *

Removes control characters (char <= 32) from both - * ends of this String returning an empty String ("") if the String - * is empty ("") after the trim or if it is null. - * - *

The String is trimmed using {@link String#trim()}. - * Trim removes start and end characters <= 32. - * To strip whitespace use {@link #stripToEmpty(String)}.

- * - *
-     * StringUtils.trimToEmpty(null)          = ""
-     * StringUtils.trimToEmpty("")            = ""
-     * StringUtils.trimToEmpty("     ")       = ""
-     * StringUtils.trimToEmpty("abc")         = "abc"
-     * StringUtils.trimToEmpty("    abc    ") = "abc"
-     * 
- * - * @param str the String to be trimmed, may be null - * @return the trimmed String, or an empty String if null input - * @since 2.0 - */ - public static String trimToEmpty(String str) { - return str == null ? EMPTY : str.trim(); - } - - // Stripping - //----------------------------------------------------------------------- - /** - *

Strips whitespace from the start and end of a String.

- * - *

This is similar to {@link #trim(String)} but removes whitespace. - * Whitespace is defined by {@link Character#isWhitespace(char)}.

- * - *

A null input String returns null.

- * - *
-     * StringUtils.strip(null)     = null
-     * StringUtils.strip("")       = ""
-     * StringUtils.strip("   ")    = ""
-     * StringUtils.strip("abc")    = "abc"
-     * StringUtils.strip("  abc")  = "abc"
-     * StringUtils.strip("abc  ")  = "abc"
-     * StringUtils.strip(" abc ")  = "abc"
-     * StringUtils.strip(" ab c ") = "ab c"
-     * 
- * - * @param str the String to remove whitespace from, may be null - * @return the stripped String, null if null String input - */ - public static String strip(String str) { - return strip(str, null); - } - - /** - *

Strips whitespace from the start and end of a String returning - * null if the String is empty ("") after the strip.

- * - *

This is similar to {@link #trimToNull(String)} but removes whitespace. - * Whitespace is defined by {@link Character#isWhitespace(char)}.

- * - *
-     * StringUtils.stripToNull(null)     = null
-     * StringUtils.stripToNull("")       = null
-     * StringUtils.stripToNull("   ")    = null
-     * StringUtils.stripToNull("abc")    = "abc"
-     * StringUtils.stripToNull("  abc")  = "abc"
-     * StringUtils.stripToNull("abc  ")  = "abc"
-     * StringUtils.stripToNull(" abc ")  = "abc"
-     * StringUtils.stripToNull(" ab c ") = "ab c"
-     * 
- * - * @param str the String to be stripped, may be null - * @return the stripped String, - * null if whitespace, empty or null String input - * @since 2.0 - */ - public static String stripToNull(String str) { - if (str == null) { - return null; - } - str = strip(str, null); - return str.length() == 0 ? null : str; - } - - /** - *

Strips whitespace from the start and end of a String returning - * an empty String if null input.

- * - *

This is similar to {@link #trimToEmpty(String)} but removes whitespace. - * Whitespace is defined by {@link Character#isWhitespace(char)}.

- * - *
-     * StringUtils.stripToEmpty(null)     = ""
-     * StringUtils.stripToEmpty("")       = ""
-     * StringUtils.stripToEmpty("   ")    = ""
-     * StringUtils.stripToEmpty("abc")    = "abc"
-     * StringUtils.stripToEmpty("  abc")  = "abc"
-     * StringUtils.stripToEmpty("abc  ")  = "abc"
-     * StringUtils.stripToEmpty(" abc ")  = "abc"
-     * StringUtils.stripToEmpty(" ab c ") = "ab c"
-     * 
- * - * @param str the String to be stripped, may be null - * @return the trimmed String, or an empty String if null input - * @since 2.0 - */ - public static String stripToEmpty(String str) { - return str == null ? EMPTY : strip(str, null); - } - - /** - *

Strips any of a set of characters from the start and end of a String. - * This is similar to {@link String#trim()} but allows the characters - * to be stripped to be controlled.

- * - *

A null input String returns null. - * An empty string ("") input returns the empty string.

- * - *

If the stripChars String is null, whitespace is - * stripped as defined by {@link Character#isWhitespace(char)}. - * Alternatively use {@link #strip(String)}.

- * - *
-     * StringUtils.strip(null, *)          = null
-     * StringUtils.strip("", *)            = ""
-     * StringUtils.strip("abc", null)      = "abc"
-     * StringUtils.strip("  abc", null)    = "abc"
-     * StringUtils.strip("abc  ", null)    = "abc"
-     * StringUtils.strip(" abc ", null)    = "abc"
-     * StringUtils.strip("  abcyx", "xyz") = "  abc"
-     * 
- * - * @param str the String to remove characters from, may be null - * @param stripChars the characters to remove, null treated as whitespace - * @return the stripped String, null if null String input - */ - public static String strip(String str, String stripChars) { - if (isEmpty(str)) { - return str; - } - str = stripStart(str, stripChars); - return stripEnd(str, stripChars); - } - - /** - *

Strips any of a set of characters from the start of a String.

- * - *

A null input String returns null. - * An empty string ("") input returns the empty string.

- * - *

If the stripChars String is null, whitespace is - * stripped as defined by {@link Character#isWhitespace(char)}.

- * - *
-     * StringUtils.stripStart(null, *)          = null
-     * StringUtils.stripStart("", *)            = ""
-     * StringUtils.stripStart("abc", "")        = "abc"
-     * StringUtils.stripStart("abc", null)      = "abc"
-     * StringUtils.stripStart("  abc", null)    = "abc"
-     * StringUtils.stripStart("abc  ", null)    = "abc  "
-     * StringUtils.stripStart(" abc ", null)    = "abc "
-     * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "
-     * 
- * - * @param str the String to remove characters from, may be null - * @param stripChars the characters to remove, null treated as whitespace - * @return the stripped String, null if null String input - */ - public static String stripStart(String str, String stripChars) { - int strLen; - if (str == null || (strLen = str.length()) == 0) { - return str; - } - int start = 0; - if (stripChars == null) { - while ((start != strLen) && Character.isWhitespace(str.charAt(start))) { - start++; - } - } else if (stripChars.length() == 0) { - return str; - } else { - while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND)) { - start++; - } - } - return str.substring(start); - } - - /** - *

Strips any of a set of characters from the end of a String.

- * - *

A null input String returns null. - * An empty string ("") input returns the empty string.

- * - *

If the stripChars String is null, whitespace is - * stripped as defined by {@link Character#isWhitespace(char)}.

- * - *
-     * StringUtils.stripEnd(null, *)          = null
-     * StringUtils.stripEnd("", *)            = ""
-     * StringUtils.stripEnd("abc", "")        = "abc"
-     * StringUtils.stripEnd("abc", null)      = "abc"
-     * StringUtils.stripEnd("  abc", null)    = "  abc"
-     * StringUtils.stripEnd("abc  ", null)    = "abc"
-     * StringUtils.stripEnd(" abc ", null)    = " abc"
-     * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"
-     * StringUtils.stripEnd("120.00", ".0")   = "12"
-     * 
- * - * @param str the String to remove characters from, may be null - * @param stripChars the set of characters to remove, null treated as whitespace - * @return the stripped String, null if null String input - */ - public static String stripEnd(String str, String stripChars) { - int end; - if (str == null || (end = str.length()) == 0) { - return str; - } - - if (stripChars == null) { - while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) { - end--; - } - } else if (stripChars.length() == 0) { - return str; - } else { - while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND)) { - end--; - } - } - return str.substring(0, end); - } - - // StripAll - //----------------------------------------------------------------------- - /** - *

Strips whitespace from the start and end of every String in an array. - * Whitespace is defined by {@link Character#isWhitespace(char)}.

- * - *

A new array is returned each time, except for length zero. - * A null array will return null. - * An empty array will return itself. - * A null array entry will be ignored.

- * - *
-     * StringUtils.stripAll(null)             = null
-     * StringUtils.stripAll([])               = []
-     * StringUtils.stripAll(["abc", "  abc"]) = ["abc", "abc"]
-     * StringUtils.stripAll(["abc  ", null])  = ["abc", null]
-     * 
- * - * @param strs the array to remove whitespace from, may be null - * @return the stripped Strings, null if null array input - */ - public static String[] stripAll(String[] strs) { - return stripAll(strs, null); - } - - /** - *

Strips any of a set of characters from the start and end of every - * String in an array.

- * Whitespace is defined by {@link Character#isWhitespace(char)}.

- * - *

A new array is returned each time, except for length zero. - * A null array will return null. - * An empty array will return itself. - * A null array entry will be ignored. - * A null stripChars will strip whitespace as defined by - * {@link Character#isWhitespace(char)}.

- * - *
-     * StringUtils.stripAll(null, *)                = null
-     * StringUtils.stripAll([], *)                  = []
-     * StringUtils.stripAll(["abc", "  abc"], null) = ["abc", "abc"]
-     * StringUtils.stripAll(["abc  ", null], null)  = ["abc", null]
-     * StringUtils.stripAll(["abc  ", null], "yz")  = ["abc  ", null]
-     * StringUtils.stripAll(["yabcz", null], "yz")  = ["abc", null]
-     * 
- * - * @param strs the array to remove characters from, may be null - * @param stripChars the characters to remove, null treated as whitespace - * @return the stripped Strings, null if null array input - */ - public static String[] stripAll(String[] strs, String stripChars) { - int strsLen; - if (strs == null || (strsLen = strs.length) == 0) { - return strs; - } - String[] newArr = new String[strsLen]; - for (int i = 0; i < strsLen; i++) { - newArr[i] = strip(strs[i], stripChars); - } - return newArr; - } - - // Equals - //----------------------------------------------------------------------- - /** - *

Compares two Strings, returning true if they are equal.

- * - *

nulls are handled without exceptions. Two null - * references are considered to be equal. The comparison is case sensitive.

- * - *
-     * StringUtils.equals(null, null)   = true
-     * StringUtils.equals(null, "abc")  = false
-     * StringUtils.equals("abc", null)  = false
-     * StringUtils.equals("abc", "abc") = true
-     * StringUtils.equals("abc", "ABC") = false
-     * 
- * - * @see String#equals(Object) - * @param str1 the first String, may be null - * @param str2 the second String, may be null - * @return true if the Strings are equal, case sensitive, or - * both null - */ - public static boolean equals(String str1, String str2) { - return str1 == null ? str2 == null : str1.equals(str2); - } - - /** - *

Compares two Strings, returning true if they are equal ignoring - * the case.

- * - *

nulls are handled without exceptions. Two null - * references are considered equal. Comparison is case insensitive.

- * - *
-     * StringUtils.equalsIgnoreCase(null, null)   = true
-     * StringUtils.equalsIgnoreCase(null, "abc")  = false
-     * StringUtils.equalsIgnoreCase("abc", null)  = false
-     * StringUtils.equalsIgnoreCase("abc", "abc") = true
-     * StringUtils.equalsIgnoreCase("abc", "ABC") = true
-     * 
- * - * @see String#equalsIgnoreCase(String) - * @param str1 the first String, may be null - * @param str2 the second String, may be null - * @return true if the Strings are equal, case insensitive, or - * both null - */ - public static boolean equalsIgnoreCase(String str1, String str2) { - return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); - } - - // IndexOf - //----------------------------------------------------------------------- - /** - *

Finds the first index within a String, handling null. - * This method uses {@link String#indexOf(int)}.

- * - *

A null or empty ("") String will return INDEX_NOT_FOUND (-1).

- * - *
-     * StringUtils.indexOf(null, *)         = -1
-     * StringUtils.indexOf("", *)           = -1
-     * StringUtils.indexOf("aabaabaa", 'a') = 0
-     * StringUtils.indexOf("aabaabaa", 'b') = 2
-     * 
- * - * @param str the String to check, may be null - * @param searchChar the character to find - * @return the first index of the search character, - * -1 if no match or null string input - * @since 2.0 - */ - public static int indexOf(String str, char searchChar) { - if (isEmpty(str)) { - return INDEX_NOT_FOUND; - } - return str.indexOf(searchChar); - } - - /** - *

Finds the first index within a String from a start position, - * handling null. - * This method uses {@link String#indexOf(int, int)}.

- * - *

A null or empty ("") String will return (INDEX_NOT_FOUND) -1. - * A negative start position is treated as zero. - * A start position greater than the string length returns -1.

- * - *
-     * StringUtils.indexOf(null, *, *)          = -1
-     * StringUtils.indexOf("", *, *)            = -1
-     * StringUtils.indexOf("aabaabaa", 'b', 0)  = 2
-     * StringUtils.indexOf("aabaabaa", 'b', 3)  = 5
-     * StringUtils.indexOf("aabaabaa", 'b', 9)  = -1
-     * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
-     * 
- * - * @param str the String to check, may be null - * @param searchChar the character to find - * @param startPos the start position, negative treated as zero - * @return the first index of the search character, - * -1 if no match or null string input - * @since 2.0 - */ - public static int indexOf(String str, char searchChar, int startPos) { - if (isEmpty(str)) { - return INDEX_NOT_FOUND; - } - return str.indexOf(searchChar, startPos); - } - - /** - *

Finds the first index within a String, handling null. - * This method uses {@link String#indexOf(String)}.

- * - *

A null String will return -1.

- * - *
-     * StringUtils.indexOf(null, *)          = -1
-     * StringUtils.indexOf(*, null)          = -1
-     * StringUtils.indexOf("", "")           = 0
-     * StringUtils.indexOf("", *)            = -1 (except when * = "")
-     * StringUtils.indexOf("aabaabaa", "a")  = 0
-     * StringUtils.indexOf("aabaabaa", "b")  = 2
-     * StringUtils.indexOf("aabaabaa", "ab") = 1
-     * StringUtils.indexOf("aabaabaa", "")   = 0
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.0 - */ - public static int indexOf(String str, String searchStr) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - return str.indexOf(searchStr); - } - - /** - *

Finds the n-th index within a String, handling null. - * This method uses {@link String#indexOf(String)}.

- * - *

A null String will return -1.

- * - *
-     * StringUtils.ordinalIndexOf(null, *, *)          = -1
-     * StringUtils.ordinalIndexOf(*, null, *)          = -1
-     * StringUtils.ordinalIndexOf("", "", *)           = 0
-     * StringUtils.ordinalIndexOf("aabaabaa", "a", 1)  = 0
-     * StringUtils.ordinalIndexOf("aabaabaa", "a", 2)  = 1
-     * StringUtils.ordinalIndexOf("aabaabaa", "b", 1)  = 2
-     * StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  = 5
-     * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
-     * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
-     * StringUtils.ordinalIndexOf("aabaabaa", "", 1)   = 0
-     * StringUtils.ordinalIndexOf("aabaabaa", "", 2)   = 0
-     * 
- * - *

Note that 'head(String str, int n)' may be implemented as:

- * - *
-     *   str.substring(0, lastOrdinalIndexOf(str, "\n", n))
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param ordinal the n-th searchStr to find - * @return the n-th index of the search String, - * -1 (INDEX_NOT_FOUND) if no match or null string input - * @since 2.1 - */ - public static int ordinalIndexOf(String str, String searchStr, int ordinal) { - return ordinalIndexOf(str, searchStr, ordinal, false); - } - - /** - *

Finds the n-th index within a String, handling null. - * This method uses {@link String#indexOf(String)}.

- * - *

A null String will return -1.

- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param ordinal the n-th searchStr to find - * @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf() - * @return the n-th index of the search String, - * -1 (INDEX_NOT_FOUND) if no match or null string input - */ - // Shared code between ordinalIndexOf(String,String,int) and lastOrdinalIndexOf(String,String,int) - private static int ordinalIndexOf(String str, String searchStr, int ordinal, boolean lastIndex) { - if (str == null || searchStr == null || ordinal <= 0) { - return INDEX_NOT_FOUND; - } - if (searchStr.length() == 0) { - return lastIndex ? str.length() : 0; - } - int found = 0; - int index = lastIndex ? str.length() : INDEX_NOT_FOUND; - do { - if(lastIndex) { - index = str.lastIndexOf(searchStr, index - 1); - } else { - index = str.indexOf(searchStr, index + 1); - } - if (index < 0) { - return index; - } - found++; - } while (found < ordinal); - return index; - } - - /** - *

Finds the first index within a String, handling null. - * This method uses {@link String#indexOf(String, int)}.

- * - *

A null String will return -1. - * A negative start position is treated as zero. - * An empty ("") search String always matches. - * A start position greater than the string length only matches - * an empty search String.

- * - *
-     * StringUtils.indexOf(null, *, *)          = -1
-     * StringUtils.indexOf(*, null, *)          = -1
-     * StringUtils.indexOf("", "", 0)           = 0
-     * StringUtils.indexOf("", *, 0)            = -1 (except when * = "")
-     * StringUtils.indexOf("aabaabaa", "a", 0)  = 0
-     * StringUtils.indexOf("aabaabaa", "b", 0)  = 2
-     * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
-     * StringUtils.indexOf("aabaabaa", "b", 3)  = 5
-     * StringUtils.indexOf("aabaabaa", "b", 9)  = -1
-     * StringUtils.indexOf("aabaabaa", "b", -1) = 2
-     * StringUtils.indexOf("aabaabaa", "", 2)   = 2
-     * StringUtils.indexOf("abc", "", 9)        = 3
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param startPos the start position, negative treated as zero - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.0 - */ - public static int indexOf(String str, String searchStr, int startPos) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence - if (searchStr.length() == 0 && startPos >= str.length()) { - return str.length(); - } - return str.indexOf(searchStr, startPos); - } - - /** - *

Case in-sensitive find of the first index within a String.

- * - *

A null String will return -1. - * A negative start position is treated as zero. - * An empty ("") search String always matches. - * A start position greater than the string length only matches - * an empty search String.

- * - *
-     * StringUtils.indexOfIgnoreCase(null, *)          = -1
-     * StringUtils.indexOfIgnoreCase(*, null)          = -1
-     * StringUtils.indexOfIgnoreCase("", "")           = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "a")  = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "b")  = 2
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.5 - */ - public static int indexOfIgnoreCase(String str, String searchStr) { - return indexOfIgnoreCase(str, searchStr, 0); - } - - /** - *

Case in-sensitive find of the first index within a String - * from the specified position.

- * - *

A null String will return -1. - * A negative start position is treated as zero. - * An empty ("") search String always matches. - * A start position greater than the string length only matches - * an empty search String.

- * - *
-     * StringUtils.indexOfIgnoreCase(null, *, *)          = -1
-     * StringUtils.indexOfIgnoreCase(*, null, *)          = -1
-     * StringUtils.indexOfIgnoreCase("", "", 0)           = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
-     * StringUtils.indexOfIgnoreCase("abc", "", 9)        = 3
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param startPos the start position, negative treated as zero - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.5 - */ - public static int indexOfIgnoreCase(String str, String searchStr, int startPos) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - if (startPos < 0) { - startPos = 0; - } - int endLimit = (str.length() - searchStr.length()) + 1; - if (startPos > endLimit) { - return INDEX_NOT_FOUND; - } - if (searchStr.length() == 0) { - return startPos; - } - for (int i = startPos; i < endLimit; i++) { - if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) { - return i; - } - } - return INDEX_NOT_FOUND; - } - - // LastIndexOf - //----------------------------------------------------------------------- - /** - *

Finds the last index within a String, handling null. - * This method uses {@link String#lastIndexOf(int)}.

- * - *

A null or empty ("") String will return -1.

- * - *
-     * StringUtils.lastIndexOf(null, *)         = -1
-     * StringUtils.lastIndexOf("", *)           = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
-     * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
-     * 
- * - * @param str the String to check, may be null - * @param searchChar the character to find - * @return the last index of the search character, - * -1 if no match or null string input - * @since 2.0 - */ - public static int lastIndexOf(String str, char searchChar) { - if (isEmpty(str)) { - return INDEX_NOT_FOUND; - } - return str.lastIndexOf(searchChar); - } - - /** - *

Finds the last index within a String from a start position, - * handling null. - * This method uses {@link String#lastIndexOf(int, int)}.

- * - *

A null or empty ("") String will return -1. - * A negative start position returns -1. - * A start position greater than the string length searches the whole string.

- * - *
-     * StringUtils.lastIndexOf(null, *, *)          = -1
-     * StringUtils.lastIndexOf("", *,  *)           = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 8)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 4)  = 2
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 0)  = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 9)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'a', 0)  = 0
-     * 
- * - * @param str the String to check, may be null - * @param searchChar the character to find - * @param startPos the start position - * @return the last index of the search character, - * -1 if no match or null string input - * @since 2.0 - */ - public static int lastIndexOf(String str, char searchChar, int startPos) { - if (isEmpty(str)) { - return INDEX_NOT_FOUND; - } - return str.lastIndexOf(searchChar, startPos); - } - - /** - *

Finds the last index within a String, handling null. - * This method uses {@link String#lastIndexOf(String)}.

- * - *

A null String will return -1.

- * - *
-     * StringUtils.lastIndexOf(null, *)          = -1
-     * StringUtils.lastIndexOf(*, null)          = -1
-     * StringUtils.lastIndexOf("", "")           = 0
-     * StringUtils.lastIndexOf("aabaabaa", "a")  = 7
-     * StringUtils.lastIndexOf("aabaabaa", "b")  = 5
-     * StringUtils.lastIndexOf("aabaabaa", "ab") = 4
-     * StringUtils.lastIndexOf("aabaabaa", "")   = 8
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @return the last index of the search String, - * -1 if no match or null string input - * @since 2.0 - */ - public static int lastIndexOf(String str, String searchStr) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - return str.lastIndexOf(searchStr); - } - - /** - *

Finds the n-th last index within a String, handling null. - * This method uses {@link String#lastIndexOf(String)}.

- * - *

A null String will return -1.

- * - *
-     * StringUtils.lastOrdinalIndexOf(null, *, *)          = -1
-     * StringUtils.lastOrdinalIndexOf(*, null, *)          = -1
-     * StringUtils.lastOrdinalIndexOf("", "", *)           = 0
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1)  = 7
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2)  = 6
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1)  = 5
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2)  = 2
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1)   = 8
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2)   = 8
-     * 
- * - *

Note that 'tail(String str, int n)' may be implemented as:

- * - *
-     *   str.substring(lastOrdinalIndexOf(str, "\n", n) + 1)
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param ordinal the n-th last searchStr to find - * @return the n-th last index of the search String, - * -1 (INDEX_NOT_FOUND) if no match or null string input - * @since 2.5 - */ - public static int lastOrdinalIndexOf(String str, String searchStr, int ordinal) { - return ordinalIndexOf(str, searchStr, ordinal, true); - } - - /** - *

Finds the first index within a String, handling null. - * This method uses {@link String#lastIndexOf(String, int)}.

- * - *

A null String will return -1. - * A negative start position returns -1. - * An empty ("") search String always matches unless the start position is negative. - * A start position greater than the string length searches the whole string.

- * - *
-     * StringUtils.lastIndexOf(null, *, *)          = -1
-     * StringUtils.lastIndexOf(*, null, *)          = -1
-     * StringUtils.lastIndexOf("aabaabaa", "a", 8)  = 7
-     * StringUtils.lastIndexOf("aabaabaa", "b", 8)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
-     * StringUtils.lastIndexOf("aabaabaa", "b", 9)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
-     * StringUtils.lastIndexOf("aabaabaa", "a", 0)  = 0
-     * StringUtils.lastIndexOf("aabaabaa", "b", 0)  = -1
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param startPos the start position, negative treated as zero - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.0 - */ - public static int lastIndexOf(String str, String searchStr, int startPos) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - return str.lastIndexOf(searchStr, startPos); - } - - /** - *

Case in-sensitive find of the last index within a String.

- * - *

A null String will return -1. - * A negative start position returns -1. - * An empty ("") search String always matches unless the start position is negative. - * A start position greater than the string length searches the whole string.

- * - *
-     * StringUtils.lastIndexOfIgnoreCase(null, *)          = -1
-     * StringUtils.lastIndexOfIgnoreCase(*, null)          = -1
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A")  = 7
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B")  = 5
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.5 - */ - public static int lastIndexOfIgnoreCase(String str, String searchStr) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - return lastIndexOfIgnoreCase(str, searchStr, str.length()); - } - - /** - *

Case in-sensitive find of the last index within a String - * from the specified position.

- * - *

A null String will return -1. - * A negative start position returns -1. - * An empty ("") search String always matches unless the start position is negative. - * A start position greater than the string length searches the whole string.

- * - *
-     * StringUtils.lastIndexOfIgnoreCase(null, *, *)          = -1
-     * StringUtils.lastIndexOfIgnoreCase(*, null, *)          = -1
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8)  = 7
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8)  = 5
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9)  = 5
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0)  = -1
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @param startPos the start position - * @return the first index of the search String, - * -1 if no match or null string input - * @since 2.5 - */ - public static int lastIndexOfIgnoreCase(String str, String searchStr, int startPos) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - if (startPos > (str.length() - searchStr.length())) { - startPos = str.length() - searchStr.length(); - } - if (startPos < 0) { - return INDEX_NOT_FOUND; - } - if (searchStr.length() == 0) { - return startPos; - } - - for (int i = startPos; i >= 0; i--) { - if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) { - return i; - } - } - return INDEX_NOT_FOUND; - } - - // Contains - //----------------------------------------------------------------------- - /** - *

Checks if String contains a search character, handling null. - * This method uses {@link String#indexOf(int)}.

- * - *

A null or empty ("") String will return false.

- * - *
-     * StringUtils.contains(null, *)    = false
-     * StringUtils.contains("", *)      = false
-     * StringUtils.contains("abc", 'a') = true
-     * StringUtils.contains("abc", 'z') = false
-     * 
- * - * @param str the String to check, may be null - * @param searchChar the character to find - * @return true if the String contains the search character, - * false if not or null string input - * @since 2.0 - */ - public static boolean contains(String str, char searchChar) { - if (isEmpty(str)) { - return false; - } - return str.indexOf(searchChar) >= 0; - } - - /** - *

Checks if String contains a search String, handling null. - * This method uses {@link String#indexOf(String)}.

- * - *

A null String will return false.

- * - *
-     * StringUtils.contains(null, *)     = false
-     * StringUtils.contains(*, null)     = false
-     * StringUtils.contains("", "")      = true
-     * StringUtils.contains("abc", "")   = true
-     * StringUtils.contains("abc", "a")  = true
-     * StringUtils.contains("abc", "z")  = false
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @return true if the String contains the search String, - * false if not or null string input - * @since 2.0 - */ - public static boolean contains(String str, String searchStr) { - if (str == null || searchStr == null) { - return false; - } - return str.indexOf(searchStr) >= 0; - } - - /** - *

Checks if String contains a search String irrespective of case, - * handling null. Case-insensitivity is defined as by - * {@link String#equalsIgnoreCase(String)}. - * - *

A null String will return false.

- * - *
-     * StringUtils.contains(null, *) = false
-     * StringUtils.contains(*, null) = false
-     * StringUtils.contains("", "") = true
-     * StringUtils.contains("abc", "") = true
-     * StringUtils.contains("abc", "a") = true
-     * StringUtils.contains("abc", "z") = false
-     * StringUtils.contains("abc", "A") = true
-     * StringUtils.contains("abc", "Z") = false
-     * 
- * - * @param str the String to check, may be null - * @param searchStr the String to find, may be null - * @return true if the String contains the search String irrespective of - * case or false if not or null string input - */ - public static boolean containsIgnoreCase(String str, String searchStr) { - if (str == null || searchStr == null) { - return false; - } - int len = searchStr.length(); - int max = str.length() - len; - for (int i = 0; i <= max; i++) { - if (str.regionMatches(true, i, searchStr, 0, len)) { - return true; - } - } - return false; - } - - - // IndexOfAny strings - //----------------------------------------------------------------------- - /** - *

Find the first index of any of a set of potential substrings.

- * - *

A null String will return -1. - * A null or zero length search array will return -1. - * A null search array entry will be ignored, but a search - * array containing "" will return 0 if str is not - * null. This method uses {@link String#indexOf(String)}.

- * - *
-     * StringUtils.indexOfAny(null, *)                     = -1
-     * StringUtils.indexOfAny(*, null)                     = -1
-     * StringUtils.indexOfAny(*, [])                       = -1
-     * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
-     * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
-     * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
-     * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
-     * StringUtils.indexOfAny("zzabyycdxx", [""])          = 0
-     * StringUtils.indexOfAny("", [""])                    = 0
-     * StringUtils.indexOfAny("", ["a"])                   = -1
-     * 
- * - * @param str the String to check, may be null - * @param searchStrs the Strings to search for, may be null - * @return the first index of any of the searchStrs in str, -1 if no match - */ - public static int indexOfAny(String str, String[] searchStrs) { - if ((str == null) || (searchStrs == null)) { - return INDEX_NOT_FOUND; - } - int sz = searchStrs.length; - - // String's can't have a MAX_VALUEth index. - int ret = Integer.MAX_VALUE; - - int tmp = 0; - for (int i = 0; i < sz; i++) { - String search = searchStrs[i]; - if (search == null) { - continue; - } - tmp = str.indexOf(search); - if (tmp == INDEX_NOT_FOUND) { - continue; - } - - if (tmp < ret) { - ret = tmp; - } - } - - return (ret == Integer.MAX_VALUE) ? INDEX_NOT_FOUND : ret; - } - - /** - *

Find the latest index of any of a set of potential substrings.

- * - *

A null String will return -1. - * A null search array will return -1. - * A null or zero length search array entry will be ignored, - * but a search array containing "" will return the length of str - * if str is not null. This method uses {@link String#indexOf(String)}

- * - *
-     * StringUtils.lastIndexOfAny(null, *)                   = -1
-     * StringUtils.lastIndexOfAny(*, null)                   = -1
-     * StringUtils.lastIndexOfAny(*, [])                     = -1
-     * StringUtils.lastIndexOfAny(*, [null])                 = -1
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
-     * 
- * - * @param str the String to check, may be null - * @param searchStrs the Strings to search for, may be null - * @return the last index of any of the Strings, -1 if no match - */ - public static int lastIndexOfAny(String str, String[] searchStrs) { - if ((str == null) || (searchStrs == null)) { - return INDEX_NOT_FOUND; - } - int sz = searchStrs.length; - int ret = INDEX_NOT_FOUND; - int tmp = 0; - for (int i = 0; i < sz; i++) { - String search = searchStrs[i]; - if (search == null) { - continue; - } - tmp = str.lastIndexOf(search); - if (tmp > ret) { - ret = tmp; - } - } - return ret; - } - - // Substring - //----------------------------------------------------------------------- - /** - *

Gets a substring from the specified String avoiding exceptions.

- * - *

A negative start position can be used to start n - * characters from the end of the String.

- * - *

A null String will return null. - * An empty ("") String will return "".

- * - *
-     * StringUtils.substring(null, *)   = null
-     * StringUtils.substring("", *)     = ""
-     * StringUtils.substring("abc", 0)  = "abc"
-     * StringUtils.substring("abc", 2)  = "c"
-     * StringUtils.substring("abc", 4)  = ""
-     * StringUtils.substring("abc", -2) = "bc"
-     * StringUtils.substring("abc", -4) = "abc"
-     * 
- * - * @param str the String to get the substring from, may be null - * @param start the position to start from, negative means - * count back from the end of the String by this many characters - * @return substring from start position, null if null String input - */ - public static String substring(String str, int start) { - if (str == null) { - return null; - } - - // handle negatives, which means last n characters - if (start < 0) { - start = str.length() + start; // remember start is negative - } - - if (start < 0) { - start = 0; - } - if (start > str.length()) { - return EMPTY; - } - - return str.substring(start); - } - - /** - *

Gets a substring from the specified String avoiding exceptions.

- * - *

A negative start position can be used to start/end n - * characters from the end of the String.

- * - *

The returned substring starts with the character in the start - * position and ends before the end position. All position counting is - * zero-based -- i.e., to start at the beginning of the string use - * start = 0. Negative start and end positions can be used to - * specify offsets relative to the end of the String.

- * - *

If start is not strictly to the left of end, "" - * is returned.

- * - *
-     * StringUtils.substring(null, *, *)    = null
-     * StringUtils.substring("", * ,  *)    = "";
-     * StringUtils.substring("abc", 0, 2)   = "ab"
-     * StringUtils.substring("abc", 2, 0)   = ""
-     * StringUtils.substring("abc", 2, 4)   = "c"
-     * StringUtils.substring("abc", 4, 6)   = ""
-     * StringUtils.substring("abc", 2, 2)   = ""
-     * StringUtils.substring("abc", -2, -1) = "b"
-     * StringUtils.substring("abc", -4, 2)  = "ab"
-     * 
- * - * @param str the String to get the substring from, may be null - * @param start the position to start from, negative means - * count back from the end of the String by this many characters - * @param end the position to end at (exclusive), negative means - * count back from the end of the String by this many characters - * @return substring from start position to end positon, - * null if null String input - */ - public static String substring(String str, int start, int end) { - if (str == null) { - return null; - } - - // handle negatives - if (end < 0) { - end = str.length() + end; // remember end is negative - } - if (start < 0) { - start = str.length() + start; // remember start is negative - } - - // check length next - if (end > str.length()) { - end = str.length(); - } - - // if start is greater than end, return "" - if (start > end) { - return EMPTY; - } - - if (start < 0) { - start = 0; - } - if (end < 0) { - end = 0; - } - - return str.substring(start, end); - } - - // Left/Right/Mid - //----------------------------------------------------------------------- - /** - *

Gets the leftmost len characters of a String.

- * - *

If len characters are not available, or the - * String is null, the String will be returned without - * an exception. An empty String is returned if len is negative.

- * - *
-     * StringUtils.left(null, *)    = null
-     * StringUtils.left(*, -ve)     = ""
-     * StringUtils.left("", *)      = ""
-     * StringUtils.left("abc", 0)   = ""
-     * StringUtils.left("abc", 2)   = "ab"
-     * StringUtils.left("abc", 4)   = "abc"
-     * 
- * - * @param str the String to get the leftmost characters from, may be null - * @param len the length of the required String - * @return the leftmost characters, null if null String input - */ - public static String left(String str, int len) { - if (str == null) { - return null; - } - if (len < 0) { - return EMPTY; - } - if (str.length() <= len) { - return str; - } - return str.substring(0, len); - } - - /** - *

Gets the rightmost len characters of a String.

- * - *

If len characters are not available, or the String - * is null, the String will be returned without an - * an exception. An empty String is returned if len is negative.

- * - *
-     * StringUtils.right(null, *)    = null
-     * StringUtils.right(*, -ve)     = ""
-     * StringUtils.right("", *)      = ""
-     * StringUtils.right("abc", 0)   = ""
-     * StringUtils.right("abc", 2)   = "bc"
-     * StringUtils.right("abc", 4)   = "abc"
-     * 
- * - * @param str the String to get the rightmost characters from, may be null - * @param len the length of the required String - * @return the rightmost characters, null if null String input - */ - public static String right(String str, int len) { - if (str == null) { - return null; - } - if (len < 0) { - return EMPTY; - } - if (str.length() <= len) { - return str; - } - return str.substring(str.length() - len); - } - - /** - *

Gets len characters from the middle of a String.

- * - *

If len characters are not available, the remainder - * of the String will be returned without an exception. If the - * String is null, null will be returned. - * An empty String is returned if len is negative or exceeds the - * length of str.

- * - *
-     * StringUtils.mid(null, *, *)    = null
-     * StringUtils.mid(*, *, -ve)     = ""
-     * StringUtils.mid("", 0, *)      = ""
-     * StringUtils.mid("abc", 0, 2)   = "ab"
-     * StringUtils.mid("abc", 0, 4)   = "abc"
-     * StringUtils.mid("abc", 2, 4)   = "c"
-     * StringUtils.mid("abc", 4, 2)   = ""
-     * StringUtils.mid("abc", -2, 2)  = "ab"
-     * 
- * - * @param str the String to get the characters from, may be null - * @param pos the position to start from, negative treated as zero - * @param len the length of the required String - * @return the middle characters, null if null String input - */ - public static String mid(String str, int pos, int len) { - if (str == null) { - return null; - } - if (len < 0 || pos > str.length()) { - return EMPTY; - } - if (pos < 0) { - pos = 0; - } - if (str.length() <= (pos + len)) { - return str.substring(pos); - } - return str.substring(pos, pos + len); - } - - // SubStringAfter/SubStringBefore - //----------------------------------------------------------------------- - /** - *

Gets the substring before the first occurrence of a separator. - * The separator is not returned.

- * - *

A null string input will return null. - * An empty ("") string input will return the empty string. - * A null separator will return the input string.

- * - *

If nothing is found, the string input is returned.

- * - *
-     * StringUtils.substringBefore(null, *)      = null
-     * StringUtils.substringBefore("", *)        = ""
-     * StringUtils.substringBefore("abc", "a")   = ""
-     * StringUtils.substringBefore("abcba", "b") = "a"
-     * StringUtils.substringBefore("abc", "c")   = "ab"
-     * StringUtils.substringBefore("abc", "d")   = "abc"
-     * StringUtils.substringBefore("abc", "")    = ""
-     * StringUtils.substringBefore("abc", null)  = "abc"
-     * 
- * - * @param str the String to get a substring from, may be null - * @param separator the String to search for, may be null - * @return the substring before the first occurrence of the separator, - * null if null String input - * @since 2.0 - */ - public static String substringBefore(String str, String separator) { - if (isEmpty(str) || separator == null) { - return str; - } - if (separator.length() == 0) { - return EMPTY; - } - int pos = str.indexOf(separator); - if (pos == INDEX_NOT_FOUND) { - return str; - } - return str.substring(0, pos); - } - - /** - *

Gets the substring after the first occurrence of a separator. - * The separator is not returned.

- * - *

A null string input will return null. - * An empty ("") string input will return the empty string. - * A null separator will return the empty string if the - * input string is not null.

- * - *

If nothing is found, the empty string is returned.

- * - *
-     * StringUtils.substringAfter(null, *)      = null
-     * StringUtils.substringAfter("", *)        = ""
-     * StringUtils.substringAfter(*, null)      = ""
-     * StringUtils.substringAfter("abc", "a")   = "bc"
-     * StringUtils.substringAfter("abcba", "b") = "cba"
-     * StringUtils.substringAfter("abc", "c")   = ""
-     * StringUtils.substringAfter("abc", "d")   = ""
-     * StringUtils.substringAfter("abc", "")    = "abc"
-     * 
- * - * @param str the String to get a substring from, may be null - * @param separator the String to search for, may be null - * @return the substring after the first occurrence of the separator, - * null if null String input - * @since 2.0 - */ - public static String substringAfter(String str, String separator) { - if (isEmpty(str)) { - return str; - } - if (separator == null) { - return EMPTY; - } - int pos = str.indexOf(separator); - if (pos == INDEX_NOT_FOUND) { - return EMPTY; - } - return str.substring(pos + separator.length()); - } - - /** - *

Gets the substring before the last occurrence of a separator. - * The separator is not returned.

- * - *

A null string input will return null. - * An empty ("") string input will return the empty string. - * An empty or null separator will return the input string.

- * - *

If nothing is found, the string input is returned.

- * - *
-     * StringUtils.substringBeforeLast(null, *)      = null
-     * StringUtils.substringBeforeLast("", *)        = ""
-     * StringUtils.substringBeforeLast("abcba", "b") = "abc"
-     * StringUtils.substringBeforeLast("abc", "c")   = "ab"
-     * StringUtils.substringBeforeLast("a", "a")     = ""
-     * StringUtils.substringBeforeLast("a", "z")     = "a"
-     * StringUtils.substringBeforeLast("a", null)    = "a"
-     * StringUtils.substringBeforeLast("a", "")      = "a"
-     * 
- * - * @param str the String to get a substring from, may be null - * @param separator the String to search for, may be null - * @return the substring before the last occurrence of the separator, - * null if null String input - * @since 2.0 - */ - public static String substringBeforeLast(String str, String separator) { - if (isEmpty(str) || isEmpty(separator)) { - return str; - } - int pos = str.lastIndexOf(separator); - if (pos == INDEX_NOT_FOUND) { - return str; - } - return str.substring(0, pos); - } - - /** - *

Gets the substring after the last occurrence of a separator. - * The separator is not returned.

- * - *

A null string input will return null. - * An empty ("") string input will return the empty string. - * An empty or null separator will return the empty string if - * the input string is not null.

- * - *

If nothing is found, the empty string is returned.

- * - *
-     * StringUtils.substringAfterLast(null, *)      = null
-     * StringUtils.substringAfterLast("", *)        = ""
-     * StringUtils.substringAfterLast(*, "")        = ""
-     * StringUtils.substringAfterLast(*, null)      = ""
-     * StringUtils.substringAfterLast("abc", "a")   = "bc"
-     * StringUtils.substringAfterLast("abcba", "b") = "a"
-     * StringUtils.substringAfterLast("abc", "c")   = ""
-     * StringUtils.substringAfterLast("a", "a")     = ""
-     * StringUtils.substringAfterLast("a", "z")     = ""
-     * 
- * - * @param str the String to get a substring from, may be null - * @param separator the String to search for, may be null - * @return the substring after the last occurrence of the separator, - * null if null String input - * @since 2.0 - */ - public static String substringAfterLast(String str, String separator) { - if (isEmpty(str)) { - return str; - } - if (isEmpty(separator)) { - return EMPTY; - } - int pos = str.lastIndexOf(separator); - if (pos == INDEX_NOT_FOUND || pos == (str.length() - separator.length())) { - return EMPTY; - } - return str.substring(pos + separator.length()); - } - - // Substring between - //----------------------------------------------------------------------- - /** - *

Gets the String that is nested in between two instances of the - * same String.

- * - *

A null input String returns null. - * A null tag returns null.

- * - *
-     * StringUtils.substringBetween(null, *)            = null
-     * StringUtils.substringBetween("", "")             = ""
-     * StringUtils.substringBetween("", "tag")          = null
-     * StringUtils.substringBetween("tagabctag", null)  = null
-     * StringUtils.substringBetween("tagabctag", "")    = ""
-     * StringUtils.substringBetween("tagabctag", "tag") = "abc"
-     * 
- * - * @param str the String containing the substring, may be null - * @param tag the String before and after the substring, may be null - * @return the substring, null if no match - * @since 2.0 - */ - public static String substringBetween(String str, String tag) { - return substringBetween(str, tag, tag); - } - - /** - *

Gets the String that is nested in between two Strings. - * Only the first match is returned.

- * - *

A null input String returns null. - * A null open/close returns null (no match). - * An empty ("") open and close returns an empty string.

- * - *
-     * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
-     * StringUtils.substringBetween(null, *, *)          = null
-     * StringUtils.substringBetween(*, null, *)          = null
-     * StringUtils.substringBetween(*, *, null)          = null
-     * StringUtils.substringBetween("", "", "")          = ""
-     * StringUtils.substringBetween("", "", "]")         = null
-     * StringUtils.substringBetween("", "[", "]")        = null
-     * StringUtils.substringBetween("yabcz", "", "")     = ""
-     * StringUtils.substringBetween("yabcz", "y", "z")   = "abc"
-     * StringUtils.substringBetween("yabczyabcz", "y", "z")   = "abc"
-     * 
- * - * @param str the String containing the substring, may be null - * @param open the String before the substring, may be null - * @param close the String after the substring, may be null - * @return the substring, null if no match - * @since 2.0 - */ - public static String substringBetween(String str, String open, String close) { - if (str == null || open == null || close == null) { - return null; - } - int start = str.indexOf(open); - if (start != INDEX_NOT_FOUND) { - int end = str.indexOf(close, start + open.length()); - if (end != INDEX_NOT_FOUND) { - return str.substring(start + open.length(), end); - } - } - return null; - } - -} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java index fbdd665e8..c10e602a7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.captcha; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -10,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; import javax.annotation.security.PermitAll; import javax.servlet.http.HttpServletRequest; @@ -24,24 +27,46 @@ import javax.servlet.http.HttpServletRequest; @Api(tags = "管理后台 - 验证码") @RestController("adminCaptchaController") @RequestMapping("/system/captcha") -public class CaptchaController extends com.anji.captcha.controller.CaptchaController { +public class CaptchaController { + + @Resource + private CaptchaService captchaService; @PostMapping({"/get"}) @ApiOperation("获得验证码") @PermitAll @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 - @Override public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) { - return super.get(data, request); + assert request.getRemoteHost() != null; + data.setBrowserInfo(getRemoteId(request)); + return captchaService.get(data); } @PostMapping("/check") @ApiOperation("校验验证码") @PermitAll @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 - @Override public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) { - return super.check(data, request); + data.setBrowserInfo(getRemoteId(request)); + return captchaService.check(data); + } + + public static String getRemoteId(HttpServletRequest request) { + String xfwd = request.getHeader("X-Forwarded-For"); + String ip = getRemoteIpFromXfwd(xfwd); + String ua = request.getHeader("user-agent"); + if (StrUtil.isNotBlank(ip)) { + return ip + ua; + } + return request.getRemoteAddr() + ua; + } + + private static String getRemoteIpFromXfwd(String xfwd) { + if (StrUtil.isNotBlank(xfwd)) { + String[] ipList = xfwd.split(","); + return StrUtil.trim(ipList[0]); + } + return null; } }