Commit aaf62982e277f573a0c7b271aa4e2ba7faee21ce
1 parent
865f1010
feat: 优化 captcha 代码
Showing
33 changed files
with
476 additions
and
2759 deletions
yudao-framework/yudao-spring-boot-starter-captcha/pom.xml
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaServiceAutoConfiguration.java
| 1 | 1 | package com.anji.captcha.config; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 3 | 4 | import com.anji.captcha.model.common.Const; |
| 4 | 5 | import com.anji.captcha.properties.AjCaptchaProperties; |
| 5 | 6 | import com.anji.captcha.service.CaptchaService; |
| 6 | 7 | import com.anji.captcha.service.impl.CaptchaServiceFactory; |
| 7 | 8 | import com.anji.captcha.util.ImageUtils; |
| 8 | -import com.anji.captcha.util.StringUtils; | |
| 9 | -import org.slf4j.Logger; | |
| 10 | -import org.slf4j.LoggerFactory; | |
| 9 | +import lombok.extern.slf4j.Slf4j; | |
| 11 | 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
| 12 | 11 | import org.springframework.context.annotation.Bean; |
| 13 | 12 | import org.springframework.context.annotation.Configuration; |
| ... | ... | @@ -21,15 +20,14 @@ import java.util.HashMap; |
| 21 | 20 | import java.util.Map; |
| 22 | 21 | import java.util.Properties; |
| 23 | 22 | |
| 23 | +@Slf4j | |
| 24 | 24 | @Configuration |
| 25 | 25 | public class AjCaptchaServiceAutoConfiguration { |
| 26 | 26 | |
| 27 | - private static Logger logger = LoggerFactory.getLogger(AjCaptchaServiceAutoConfiguration.class); | |
| 28 | - | |
| 29 | 27 | @Bean |
| 30 | 28 | @ConditionalOnMissingBean |
| 31 | 29 | public CaptchaService captchaService(AjCaptchaProperties prop) { |
| 32 | - logger.info("自定义配置项:{}", prop.toString()); | |
| 30 | + log.info("自定义配置项:{}", prop.toString()); | |
| 33 | 31 | Properties config = new Properties(); |
| 34 | 32 | config.put(Const.CAPTCHA_CACHETYPE, prop.getCacheType().name()); |
| 35 | 33 | config.put(Const.CAPTCHA_WATER_MARK, prop.getWaterMark()); |
| ... | ... | @@ -57,14 +55,13 @@ public class AjCaptchaServiceAutoConfiguration { |
| 57 | 55 | config.put(Const.CAPTCHA_FONT_STYLE, prop.getFontStyle() + ""); |
| 58 | 56 | config.put(Const.CAPTCHA_WORD_COUNT, prop.getClickWordCount() + ""); |
| 59 | 57 | |
| 60 | - if ((StringUtils.isNotBlank(prop.getJigsaw()) && prop.getJigsaw().startsWith("classpath:")) | |
| 61 | - || (StringUtils.isNotBlank(prop.getPicClick()) && prop.getPicClick().startsWith("classpath:"))) { | |
| 58 | + if ((StrUtil.isNotBlank(prop.getJigsaw()) && prop.getJigsaw().startsWith("classpath:")) | |
| 59 | + || (StrUtil.isNotBlank(prop.getPicClick()) && prop.getPicClick().startsWith("classpath:"))) { | |
| 62 | 60 | //自定义resources目录下初始化底图 |
| 63 | 61 | config.put(Const.CAPTCHA_INIT_ORIGINAL, "true"); |
| 64 | 62 | initializeBaseMap(prop.getJigsaw(), prop.getPicClick()); |
| 65 | 63 | } |
| 66 | - CaptchaService s = CaptchaServiceFactory.getInstance(config); | |
| 67 | - return s; | |
| 64 | + return CaptchaServiceFactory.getInstance(config); | |
| 68 | 65 | } |
| 69 | 66 | |
| 70 | 67 | private static void initializeBaseMap(String jigsaw, String picClick) { | ... | ... |
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; |
| 8 | 8 | |
| 9 | 9 | /** |
| 10 | 10 | * 存储策略自动配置. |
| 11 | - * | |
| 12 | 11 | */ |
| 13 | 12 | @Configuration |
| 14 | 13 | public class AjCaptchaStorageAutoConfiguration { |
| 15 | 14 | |
| 16 | 15 | @Bean(name = "AjCaptchaCacheService") |
| 17 | - public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties){ | |
| 18 | - //缓存类型redis/local/.... | |
| 16 | + public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties) { | |
| 17 | + // 缓存类型redis/local/.... | |
| 19 | 18 | return CaptchaServiceFactory.getCache(ajCaptchaProperties.getCacheType().name()); |
| 20 | 19 | } |
| 21 | 20 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/controller/CaptchaController.java deleted
| 1 | -/* | |
| 2 | - *Copyright © 2018 anji-plus | |
| 3 | - *安吉加加信息技术有限公司 | |
| 4 | - *http://www.anji-plus.com | |
| 5 | - *All rights reserved. | |
| 6 | - */ | |
| 7 | -package com.anji.captcha.controller; | |
| 8 | - | |
| 9 | -import com.anji.captcha.model.common.ResponseModel; | |
| 10 | -import com.anji.captcha.model.vo.CaptchaVO; | |
| 11 | -import com.anji.captcha.service.CaptchaService; | |
| 12 | -import com.anji.captcha.util.StringUtils; | |
| 13 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 14 | -import org.springframework.web.bind.annotation.PostMapping; | |
| 15 | -import org.springframework.web.bind.annotation.RequestBody; | |
| 16 | -import org.springframework.web.bind.annotation.RequestMapping; | |
| 17 | -import org.springframework.web.bind.annotation.RestController; | |
| 18 | - | |
| 19 | -import javax.servlet.http.HttpServletRequest; | |
| 20 | - | |
| 21 | - | |
| 22 | -@RestController | |
| 23 | -@RequestMapping("/captcha") | |
| 24 | -public class CaptchaController { | |
| 25 | - | |
| 26 | - @Autowired | |
| 27 | - private CaptchaService captchaService; | |
| 28 | - | |
| 29 | - @PostMapping("/get") | |
| 30 | - public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) { | |
| 31 | - assert request.getRemoteHost()!=null; | |
| 32 | - data.setBrowserInfo(getRemoteId(request)); | |
| 33 | - return captchaService.get(data); | |
| 34 | - } | |
| 35 | - | |
| 36 | - @PostMapping("/check") | |
| 37 | - public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) { | |
| 38 | - data.setBrowserInfo(getRemoteId(request)); | |
| 39 | - return captchaService.check(data); | |
| 40 | - } | |
| 41 | - | |
| 42 | - //@PostMapping("/verify") | |
| 43 | - public ResponseModel verify(@RequestBody CaptchaVO data, HttpServletRequest request) { | |
| 44 | - return captchaService.verification(data); | |
| 45 | - } | |
| 46 | - | |
| 47 | - public static final String getRemoteId(HttpServletRequest request) { | |
| 48 | - String xfwd = request.getHeader("X-Forwarded-For"); | |
| 49 | - String ip = getRemoteIpFromXfwd(xfwd); | |
| 50 | - String ua = request.getHeader("user-agent"); | |
| 51 | - if (StringUtils.isNotBlank(ip)) { | |
| 52 | - return ip + ua; | |
| 53 | - } | |
| 54 | - return request.getRemoteAddr() + ua; | |
| 55 | - } | |
| 56 | - | |
| 57 | - private static String getRemoteIpFromXfwd(String xfwd) { | |
| 58 | - if (StringUtils.isNotBlank(xfwd)) { | |
| 59 | - String[] ipList = xfwd.split(","); | |
| 60 | - return StringUtils.trim(ipList[0]); | |
| 61 | - } | |
| 62 | - return null; | |
| 63 | - } | |
| 64 | - | |
| 65 | -} |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaBaseMapEnum.java
| 1 | 1 | package com.anji.captcha.model.common; |
| 2 | 2 | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 3 | 6 | /** |
| 4 | 7 | * 底图类型枚举 |
| 5 | 8 | */ |
| 9 | +@Getter | |
| 10 | +@AllArgsConstructor | |
| 6 | 11 | public enum CaptchaBaseMapEnum { |
| 7 | - ORIGINAL("ORIGINAL","滑动拼图底图"), | |
| 8 | - SLIDING_BLOCK("SLIDING_BLOCK","滑动拼图滑块底图"), | |
| 9 | - PIC_CLICK("PIC_CLICK","文字点选底图"); | |
| 10 | - | |
| 11 | - private String codeValue; | |
| 12 | - private String codeDesc; | |
| 13 | - | |
| 14 | - private CaptchaBaseMapEnum(String codeValue, String codeDesc) { | |
| 15 | - this.codeValue = codeValue; | |
| 16 | - this.codeDesc = codeDesc; | |
| 17 | - } | |
| 18 | - | |
| 19 | - public String getCodeValue(){ return this.codeValue;} | |
| 12 | + ORIGINAL("ORIGINAL", "滑动拼图底图"), | |
| 13 | + SLIDING_BLOCK("SLIDING_BLOCK", "滑动拼图滑块底图"), | |
| 14 | + PIC_CLICK("PIC_CLICK", "文字点选底图"); | |
| 20 | 15 | |
| 21 | - public String getCodeDesc(){ return this.codeDesc;} | |
| 16 | + private final String codeValue; | |
| 17 | + private final String codeDesc; | |
| 22 | 18 | |
| 23 | 19 | //根据codeValue获取枚举 |
| 24 | - public static CaptchaBaseMapEnum parseFromCodeValue(String codeValue){ | |
| 25 | - for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()){ | |
| 26 | - if(e.codeValue.equals(codeValue)){ return e;} | |
| 20 | + public static CaptchaBaseMapEnum parseFromCodeValue(String codeValue) { | |
| 21 | + for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()) { | |
| 22 | + if (e.codeValue.equals(codeValue)) { | |
| 23 | + return e; | |
| 24 | + } | |
| 27 | 25 | } |
| 28 | 26 | return null; |
| 29 | 27 | } |
| 30 | 28 | |
| 31 | 29 | //根据codeValue获取描述 |
| 32 | - public static String getCodeDescByCodeBalue(String codeValue){ | |
| 30 | + public static String getCodeDescByCodeBalue(String codeValue) { | |
| 33 | 31 | CaptchaBaseMapEnum enumItem = parseFromCodeValue(codeValue); |
| 34 | 32 | return enumItem == null ? "" : enumItem.getCodeDesc(); |
| 35 | 33 | } |
| 36 | 34 | |
| 37 | 35 | //验证codeValue是否有效 |
| 38 | - public static boolean validateCodeValue(String codeValue){ return parseFromCodeValue(codeValue)!=null;} | |
| 36 | + public static boolean validateCodeValue(String codeValue) { | |
| 37 | + return parseFromCodeValue(codeValue) != null; | |
| 38 | + } | |
| 39 | 39 | |
| 40 | 40 | //列出所有值字符串 |
| 41 | - public static String getString(){ | |
| 41 | + public static String getString() { | |
| 42 | 42 | StringBuffer buffer = new StringBuffer(); |
| 43 | - for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()){ | |
| 43 | + for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()) { | |
| 44 | 44 | buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); |
| 45 | 45 | } |
| 46 | 46 | buffer.deleteCharAt(buffer.lastIndexOf(",")); | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaTypeEnum.java
| 1 | 1 | package com.anji.captcha.model.common; |
| 2 | 2 | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +@Getter | |
| 7 | +@AllArgsConstructor | |
| 3 | 8 | public enum CaptchaTypeEnum { |
| 4 | 9 | /** |
| 5 | 10 | * 滑块拼图. |
| 6 | 11 | */ |
| 7 | - BLOCKPUZZLE("blockPuzzle","滑块拼图"), | |
| 12 | + BLOCKPUZZLE("blockPuzzle", "滑块拼图"), | |
| 8 | 13 | /** |
| 9 | 14 | * 文字点选. |
| 10 | 15 | */ |
| 11 | - CLICKWORD("clickWord","文字点选"), | |
| 16 | + CLICKWORD("clickWord", "文字点选"), | |
| 12 | 17 | /** |
| 13 | 18 | * 默认. |
| 14 | 19 | */ |
| 15 | - DEFAULT("default","默认"); | |
| 16 | - | |
| 17 | - private String codeValue; | |
| 18 | - private String codeDesc; | |
| 19 | - | |
| 20 | - private CaptchaTypeEnum(String codeValue, String codeDesc) { | |
| 21 | - this.codeValue = codeValue; | |
| 22 | - this.codeDesc = codeDesc; | |
| 23 | - } | |
| 24 | - | |
| 25 | - public String getCodeValue(){ return this.codeValue;} | |
| 20 | + DEFAULT("default", "默认"); | |
| 26 | 21 | |
| 27 | - public String getCodeDesc(){ return this.codeDesc;} | |
| 22 | + private final String codeValue; | |
| 23 | + private final String codeDesc; | |
| 28 | 24 | |
| 29 | 25 | //根据codeValue获取枚举 |
| 30 | - public static CaptchaTypeEnum parseFromCodeValue(String codeValue){ | |
| 31 | - for (CaptchaTypeEnum e : CaptchaTypeEnum.values()){ | |
| 32 | - if(e.codeValue.equals(codeValue)){ return e;} | |
| 26 | + public static CaptchaTypeEnum parseFromCodeValue(String codeValue) { | |
| 27 | + for (CaptchaTypeEnum e : CaptchaTypeEnum.values()) { | |
| 28 | + if (e.codeValue.equals(codeValue)) { | |
| 29 | + return e; | |
| 30 | + } | |
| 33 | 31 | } |
| 34 | 32 | return null; |
| 35 | 33 | } |
| 36 | 34 | |
| 37 | 35 | //根据codeValue获取描述 |
| 38 | - public static String getCodeDescByCodeBalue(String codeValue){ | |
| 36 | + public static String getCodeDescByCodeBalue(String codeValue) { | |
| 39 | 37 | CaptchaTypeEnum enumItem = parseFromCodeValue(codeValue); |
| 40 | 38 | return enumItem == null ? "" : enumItem.getCodeDesc(); |
| 41 | 39 | } |
| 42 | 40 | |
| 43 | 41 | //验证codeValue是否有效 |
| 44 | - public static boolean validateCodeValue(String codeValue){ return parseFromCodeValue(codeValue)!=null;} | |
| 42 | + public static boolean validateCodeValue(String codeValue) { | |
| 43 | + return parseFromCodeValue(codeValue) != null; | |
| 44 | + } | |
| 45 | 45 | |
| 46 | 46 | //列出所有值字符串 |
| 47 | - public static String getString(){ | |
| 48 | - StringBuffer buffer = new StringBuffer(); | |
| 49 | - for (CaptchaTypeEnum e : CaptchaTypeEnum.values()){ | |
| 47 | + public static String getString() { | |
| 48 | + StringBuilder buffer = new StringBuilder(); | |
| 49 | + for (CaptchaTypeEnum e : CaptchaTypeEnum.values()) { | |
| 50 | 50 | buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); |
| 51 | 51 | } |
| 52 | 52 | buffer.deleteCharAt(buffer.lastIndexOf(",")); | ... | ... |
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; |
| 6 | 6 | public interface Const { |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | - *滑块底图路径 | |
| 9 | + * 滑块底图路径 | |
| 10 | 10 | */ |
| 11 | 11 | String ORIGINAL_PATH_JIGSAW = "captcha.captchaOriginalPath.jigsaw"; |
| 12 | 12 | |
| ... | ... | @@ -29,8 +29,8 @@ public interface Const { |
| 29 | 29 | * 点选文字验证码的文字字体(宋体) |
| 30 | 30 | */ |
| 31 | 31 | String CAPTCHA_FONT_TYPE = "captcha.font.type"; |
| 32 | - String CAPTCHA_FONT_STYLE = "captcha.font.style"; | |
| 33 | - String CAPTCHA_FONT_SIZE = "captcha.font.size"; | |
| 32 | + String CAPTCHA_FONT_STYLE = "captcha.font.style"; | |
| 33 | + String CAPTCHA_FONT_SIZE = "captcha.font.size"; | |
| 34 | 34 | |
| 35 | 35 | /** |
| 36 | 36 | * 验证码类型default两种都实例化。 |
| ... | ... | @@ -72,41 +72,41 @@ public interface Const { |
| 72 | 72 | */ |
| 73 | 73 | String CAPTCHA_TIMING_CLEAR_SECOND = "captcha.timing.clear"; |
| 74 | 74 | |
| 75 | - /** | |
| 76 | - * 历史资源清除开关 0禁用,1 开启 | |
| 77 | - */ | |
| 78 | - String HISTORY_DATA_CLEAR_ENABLE = "captcha.history.data.clear.enable"; | |
| 79 | - | |
| 80 | - /** | |
| 81 | - * 接口限流开关 0禁用 1启用 | |
| 82 | - */ | |
| 83 | - String REQ_FREQUENCY_LIMIT_ENABLE = "captcha.req.frequency.limit.enable"; | |
| 84 | - | |
| 85 | - /** | |
| 86 | - * get 接口 一分钟请求次数限制 | |
| 87 | - */ | |
| 88 | - String REQ_GET_MINUTE_LIMIT = "captcha.req.get.minute.limit"; | |
| 89 | - | |
| 90 | - /** | |
| 91 | - * 验证失败后,get接口锁定时间 | |
| 92 | - */ | |
| 93 | - String REQ_GET_LOCK_LIMIT = "captcha.req.get.lock.limit"; | |
| 94 | - /** | |
| 95 | - * 验证失败后,get接口锁定时间 | |
| 96 | - */ | |
| 97 | - String REQ_GET_LOCK_SECONDS = "captcha.req.get.lock.seconds"; | |
| 98 | - | |
| 99 | - /** | |
| 100 | - * verify 接口 一分钟请求次数限制 | |
| 101 | - */ | |
| 102 | - String REQ_VALIDATE_MINUTE_LIMIT = "captcha.req.verify.minute.limit"; | |
| 103 | - /** | |
| 104 | - * check接口 一分钟请求次数限制 | |
| 105 | - */ | |
| 106 | - String REQ_CHECK_MINUTE_LIMIT = "captcha.req.check.minute.limit"; | |
| 107 | - | |
| 108 | - /*** | |
| 109 | - * 点选文字个数 | |
| 110 | - */ | |
| 111 | - String CAPTCHA_WORD_COUNT = "captcha.word.count"; | |
| 75 | + /** | |
| 76 | + * 历史资源清除开关 0禁用,1 开启 | |
| 77 | + */ | |
| 78 | + String HISTORY_DATA_CLEAR_ENABLE = "captcha.history.data.clear.enable"; | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * 接口限流开关 0禁用 1启用 | |
| 82 | + */ | |
| 83 | + String REQ_FREQUENCY_LIMIT_ENABLE = "captcha.req.frequency.limit.enable"; | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * get 接口 一分钟请求次数限制 | |
| 87 | + */ | |
| 88 | + String REQ_GET_MINUTE_LIMIT = "captcha.req.get.minute.limit"; | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * 验证失败后,get接口锁定时间 | |
| 92 | + */ | |
| 93 | + String REQ_GET_LOCK_LIMIT = "captcha.req.get.lock.limit"; | |
| 94 | + /** | |
| 95 | + * 验证失败后,get接口锁定时间 | |
| 96 | + */ | |
| 97 | + String REQ_GET_LOCK_SECONDS = "captcha.req.get.lock.seconds"; | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * verify 接口 一分钟请求次数限制 | |
| 101 | + */ | |
| 102 | + String REQ_VALIDATE_MINUTE_LIMIT = "captcha.req.verify.minute.limit"; | |
| 103 | + /** | |
| 104 | + * check接口 一分钟请求次数限制 | |
| 105 | + */ | |
| 106 | + String REQ_CHECK_MINUTE_LIMIT = "captcha.req.check.minute.limit"; | |
| 107 | + | |
| 108 | + /*** | |
| 109 | + * 点选文字个数 | |
| 110 | + */ | |
| 111 | + String CAPTCHA_WORD_COUNT = "captcha.word.count"; | |
| 112 | 112 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RepCodeEnum.java
| ... | ... | @@ -6,16 +6,23 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.model.common; |
| 8 | 8 | |
| 9 | +import lombok.AllArgsConstructor; | |
| 10 | +import lombok.Getter; | |
| 11 | + | |
| 9 | 12 | import java.text.MessageFormat; |
| 10 | 13 | |
| 11 | 14 | /** |
| 12 | 15 | * 返回应答码 |
| 13 | - * @author | |
| 14 | 16 | * |
| 17 | + * @author | |
| 15 | 18 | */ |
| 19 | +@AllArgsConstructor | |
| 20 | +@Getter | |
| 16 | 21 | public enum RepCodeEnum { |
| 17 | 22 | |
| 18 | - /** 0001 - 0099 网关应答码 */ | |
| 23 | + /** | |
| 24 | + * 0001 - 0099 网关应答码 | |
| 25 | + */ | |
| 19 | 26 | SUCCESS("0000", "成功"), |
| 20 | 27 | ERROR("0001", "操作失败"), |
| 21 | 28 | EXCEPTION("9999", "服务器内部异常"), |
| ... | ... | @@ -33,36 +40,24 @@ public enum RepCodeEnum { |
| 33 | 40 | API_CAPTCHA_ERROR("6112", "获取验证码失败,请联系管理员"), |
| 34 | 41 | API_CAPTCHA_BASEMAP_NULL("6113", "底图未初始化成功,请检查路径"), |
| 35 | 42 | |
| 36 | - API_REQ_LIMIT_GET_ERROR("6201", "get接口请求次数超限,请稍后再试!"), | |
| 43 | + API_REQ_LIMIT_GET_ERROR("6201", "get接口请求次数超限,请稍后再试!"), | |
| 37 | 44 | API_REQ_INVALID("6206", "无效请求,请重新获取验证码"), |
| 38 | - API_REQ_LOCK_GET_ERROR("6202", "接口验证失败数过多,请稍后再试"), | |
| 39 | - API_REQ_LIMIT_CHECK_ERROR("6204", "check接口请求次数超限,请稍后再试!"), | |
| 40 | - API_REQ_LIMIT_VERIFY_ERROR("6205", "verify请求次数超限!"), | |
| 41 | - ; | |
| 42 | - private String code; | |
| 43 | - private String desc; | |
| 45 | + API_REQ_LOCK_GET_ERROR("6202", "接口验证失败数过多,请稍后再试"), | |
| 46 | + API_REQ_LIMIT_CHECK_ERROR("6204", "check接口请求次数超限,请稍后再试!"), | |
| 47 | + API_REQ_LIMIT_VERIFY_ERROR("6205", "verify请求次数超限!"); | |
| 48 | + private final String code; | |
| 49 | + private final String desc; | |
| 44 | 50 | |
| 45 | - RepCodeEnum(String code, String desc) { | |
| 46 | - this.code = code; | |
| 47 | - this.desc = desc; | |
| 48 | - } | |
| 49 | - public String getCode() { | |
| 50 | - return code; | |
| 51 | - } | |
| 52 | - public String getDesc() { | |
| 53 | - return desc; | |
| 54 | - } | |
| 55 | - public String getName(){ | |
| 56 | - return this.name(); | |
| 57 | - } | |
| 58 | 51 | |
| 59 | - /** 将入参fieldNames与this.desc组合成错误信息 | |
| 60 | - * {fieldName}不能为空 | |
| 52 | + /** | |
| 53 | + * 将入参fieldNames与this.desc组合成错误信息 | |
| 54 | + * {fieldName}不能为空 | |
| 55 | + * | |
| 61 | 56 | * @param fieldNames |
| 62 | 57 | * @return |
| 63 | 58 | */ |
| 64 | 59 | public ResponseModel parseError(Object... fieldNames) { |
| 65 | - ResponseModel errorMessage=new ResponseModel(); | |
| 60 | + ResponseModel errorMessage = new ResponseModel(); | |
| 66 | 61 | String newDesc = MessageFormat.format(this.desc, fieldNames); |
| 67 | 62 | |
| 68 | 63 | errorMessage.setRepCode(this.code); | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/RequestModel.java
| ... | ... | @@ -6,23 +6,32 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.model.common; |
| 8 | 8 | |
| 9 | -import com.anji.captcha.util.StringUtils; | |
| 9 | + | |
| 10 | +import cn.hutool.core.util.StrUtil; | |
| 11 | +import lombok.Data; | |
| 10 | 12 | |
| 11 | 13 | import java.io.Serializable; |
| 12 | 14 | import java.util.HashMap; |
| 13 | 15 | import java.util.List; |
| 14 | 16 | |
| 17 | +@Data | |
| 15 | 18 | public class RequestModel implements Serializable { |
| 16 | 19 | |
| 17 | 20 | private static final long serialVersionUID = -5800786065305114784L; |
| 18 | 21 | |
| 19 | - /**当前请求接口路径 /business/accessUser/login */ | |
| 22 | + /** | |
| 23 | + * 当前请求接口路径 /business/accessUser/login | |
| 24 | + */ | |
| 20 | 25 | private String servletPath; |
| 21 | 26 | |
| 22 | - /** {"reqData":{"password":"*****","userName":"admin"},"sign":"a304a7f296f565b6d2009797f68180f0","time":"1542456453355","token":""} */ | |
| 27 | + /** | |
| 28 | + * {"reqData":{"password":"*****","userName":"admin"},"sign":"a304a7f296f565b6d2009797f68180f0","time":"1542456453355","token":""} | |
| 29 | + */ | |
| 23 | 30 | private String requestString; |
| 24 | 31 | |
| 25 | - /** {"password":"****","userName":"admin"} */ | |
| 32 | + /** | |
| 33 | + * {"password":"****","userName":"admin"} | |
| 34 | + */ | |
| 26 | 35 | private HashMap reqData; |
| 27 | 36 | |
| 28 | 37 | private String token; |
| ... | ... | @@ -46,10 +55,11 @@ public class RequestModel implements Serializable { |
| 46 | 55 | |
| 47 | 56 | /** |
| 48 | 57 | * 校验自身参数合法性 |
| 58 | + * | |
| 49 | 59 | * @return |
| 50 | 60 | */ |
| 51 | 61 | public boolean isVaildateRequest() { |
| 52 | - if (StringUtils.isBlank(sign) || StringUtils.isBlank(time)) { | |
| 62 | + if (StrUtil.isBlank(sign) || StrUtil.isBlank(time)) { | |
| 53 | 63 | return false; |
| 54 | 64 | } |
| 55 | 65 | return true; |
| ... | ... | @@ -63,95 +73,4 @@ public class RequestModel implements Serializable { |
| 63 | 73 | this.servletPath = servletPath; |
| 64 | 74 | } |
| 65 | 75 | |
| 66 | - public String getToken() { | |
| 67 | - return token; | |
| 68 | - } | |
| 69 | - | |
| 70 | - public void setToken(String token) { | |
| 71 | - this.token = token; | |
| 72 | - } | |
| 73 | - | |
| 74 | - public Long getUserId() { | |
| 75 | - return userId; | |
| 76 | - } | |
| 77 | - | |
| 78 | - public void setUserId(Long userId) { | |
| 79 | - this.userId = userId; | |
| 80 | - } | |
| 81 | - | |
| 82 | - public String getUserName() { | |
| 83 | - return userName; | |
| 84 | - } | |
| 85 | - | |
| 86 | - public void setUserName(String userName) { | |
| 87 | - this.userName = userName; | |
| 88 | - } | |
| 89 | - | |
| 90 | - public static long getSerialVersionUID() { | |
| 91 | - return serialVersionUID; | |
| 92 | - } | |
| 93 | - | |
| 94 | - public List<Long> getProjectList() { | |
| 95 | - return projectList; | |
| 96 | - } | |
| 97 | - | |
| 98 | - public void setProjectList(List<Long> projectList) { | |
| 99 | - this.projectList = projectList; | |
| 100 | - } | |
| 101 | - | |
| 102 | - public List<Long> getGroupIdList() { | |
| 103 | - return groupIdList; | |
| 104 | - } | |
| 105 | - | |
| 106 | - public void setGroupIdList(List<Long> groupIdList) { | |
| 107 | - this.groupIdList = groupIdList; | |
| 108 | - } | |
| 109 | - | |
| 110 | - public String getSign() { | |
| 111 | - return sign; | |
| 112 | - } | |
| 113 | - | |
| 114 | - public void setSign(String sign) { | |
| 115 | - this.sign = sign; | |
| 116 | - } | |
| 117 | - | |
| 118 | - public String getTime() { | |
| 119 | - return time; | |
| 120 | - } | |
| 121 | - | |
| 122 | - public void setTime(String time) { | |
| 123 | - this.time = time; | |
| 124 | - } | |
| 125 | - | |
| 126 | - public String getSourceIP() { | |
| 127 | - return sourceIP; | |
| 128 | - } | |
| 129 | - | |
| 130 | - public void setSourceIP(String sourceIP) { | |
| 131 | - this.sourceIP = sourceIP; | |
| 132 | - } | |
| 133 | - | |
| 134 | - public String getRequestString() { | |
| 135 | - return requestString; | |
| 136 | - } | |
| 137 | - | |
| 138 | - public void setRequestString(String requestString) { | |
| 139 | - this.requestString = requestString; | |
| 140 | - } | |
| 141 | - | |
| 142 | - public HashMap getReqData() { | |
| 143 | - return reqData; | |
| 144 | - } | |
| 145 | - | |
| 146 | - public void setReqData(HashMap reqData) { | |
| 147 | - this.reqData = reqData; | |
| 148 | - } | |
| 149 | - | |
| 150 | - public String getTarget() { | |
| 151 | - return target; | |
| 152 | - } | |
| 153 | - | |
| 154 | - public void setTarget(String target) { | |
| 155 | - this.target = target; | |
| 156 | - } | |
| 157 | 76 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/ResponseModel.java
| ... | ... | @@ -6,38 +6,42 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.model.common; |
| 8 | 8 | |
| 9 | -import com.anji.captcha.util.StringUtils; | |
| 9 | +import cn.hutool.core.util.StrUtil; | |
| 10 | +import lombok.Data; | |
| 10 | 11 | |
| 11 | 12 | import java.io.Serializable; |
| 12 | 13 | |
| 14 | +@Data | |
| 13 | 15 | public class ResponseModel implements Serializable { |
| 14 | 16 | |
| 15 | 17 | private static final long serialVersionUID = 8445617032523881407L; |
| 16 | 18 | |
| 17 | - private String repCode; | |
| 19 | + private String repCode; | |
| 18 | 20 | |
| 19 | - private String repMsg; | |
| 21 | + private String repMsg; | |
| 20 | 22 | |
| 21 | - private Object repData; | |
| 23 | + private Object repData; | |
| 22 | 24 | |
| 23 | 25 | public ResponseModel() { |
| 24 | 26 | this.repCode = RepCodeEnum.SUCCESS.getCode(); |
| 25 | 27 | } |
| 26 | 28 | |
| 27 | 29 | public ResponseModel(RepCodeEnum repCodeEnum) { |
| 28 | - this.setRepCodeEnum(repCodeEnum); | |
| 30 | + this.setRepCodeEnum(repCodeEnum); | |
| 29 | 31 | } |
| 30 | 32 | |
| 31 | 33 | //成功 |
| 32 | - public static ResponseModel success(){ | |
| 34 | + public static ResponseModel success() { | |
| 33 | 35 | return ResponseModel.successMsg("成功"); |
| 34 | 36 | } |
| 35 | - public static ResponseModel successMsg(String message){ | |
| 37 | + | |
| 38 | + public static ResponseModel successMsg(String message) { | |
| 36 | 39 | ResponseModel responseModel = new ResponseModel(); |
| 37 | 40 | responseModel.setRepMsg(message); |
| 38 | 41 | return responseModel; |
| 39 | 42 | } |
| 40 | - public static ResponseModel successData(Object data){ | |
| 43 | + | |
| 44 | + public static ResponseModel successData(Object data) { | |
| 41 | 45 | ResponseModel responseModel = new ResponseModel(); |
| 42 | 46 | responseModel.setRepCode(RepCodeEnum.SUCCESS.getCode()); |
| 43 | 47 | responseModel.setRepData(data); |
| ... | ... | @@ -45,67 +49,45 @@ public class ResponseModel implements Serializable { |
| 45 | 49 | } |
| 46 | 50 | |
| 47 | 51 | //失败 |
| 48 | - public static ResponseModel errorMsg(RepCodeEnum message){ | |
| 52 | + public static ResponseModel errorMsg(RepCodeEnum message) { | |
| 49 | 53 | ResponseModel responseModel = new ResponseModel(); |
| 50 | 54 | responseModel.setRepCodeEnum(message); |
| 51 | 55 | return responseModel; |
| 52 | 56 | } |
| 53 | - public static ResponseModel errorMsg(String message){ | |
| 57 | + | |
| 58 | + public static ResponseModel errorMsg(String message) { | |
| 54 | 59 | ResponseModel responseModel = new ResponseModel(); |
| 55 | 60 | responseModel.setRepCode(RepCodeEnum.ERROR.getCode()); |
| 56 | 61 | responseModel.setRepMsg(message); |
| 57 | 62 | return responseModel; |
| 58 | 63 | } |
| 59 | - public static ResponseModel errorMsg(RepCodeEnum repCodeEnum, String message){ | |
| 64 | + | |
| 65 | + public static ResponseModel errorMsg(RepCodeEnum repCodeEnum, String message) { | |
| 60 | 66 | ResponseModel responseModel = new ResponseModel(); |
| 61 | 67 | responseModel.setRepCode(repCodeEnum.getCode()); |
| 62 | 68 | responseModel.setRepMsg(message); |
| 63 | 69 | return responseModel; |
| 64 | 70 | } |
| 65 | - public static ResponseModel exceptionMsg(String message){ | |
| 71 | + | |
| 72 | + public static ResponseModel exceptionMsg(String message) { | |
| 66 | 73 | ResponseModel responseModel = new ResponseModel(); |
| 67 | 74 | responseModel.setRepCode(RepCodeEnum.EXCEPTION.getCode()); |
| 68 | 75 | responseModel.setRepMsg(RepCodeEnum.EXCEPTION.getDesc() + ": " + message); |
| 69 | 76 | return responseModel; |
| 70 | 77 | } |
| 71 | 78 | |
| 72 | - @Override | |
| 73 | - public String toString() { | |
| 74 | - return "ResponseModel{" + "repCode='" + repCode + '\'' + ", repMsg='" | |
| 75 | - + repMsg + '\'' + ", repData=" + repData + '}'; | |
| 76 | - } | |
| 77 | 79 | |
| 78 | - public boolean isSuccess(){ | |
| 79 | - return StringUtils.equals(repCode, RepCodeEnum.SUCCESS.getCode()); | |
| 80 | + public boolean isSuccess() { | |
| 81 | + return StrUtil.equals(repCode, RepCodeEnum.SUCCESS.getCode()); | |
| 80 | 82 | } |
| 81 | 83 | |
| 82 | 84 | public String getRepCode() { |
| 83 | 85 | return repCode; |
| 84 | 86 | } |
| 85 | 87 | |
| 86 | - public void setRepCode(String repCode) { | |
| 87 | - this.repCode = repCode; | |
| 88 | - } | |
| 89 | 88 | public void setRepCodeEnum(RepCodeEnum repCodeEnum) { |
| 90 | - this.repCode=repCodeEnum.getCode(); | |
| 91 | - this.repMsg=repCodeEnum.getDesc(); | |
| 92 | - } | |
| 93 | - | |
| 94 | - public String getRepMsg() { | |
| 95 | - return repMsg; | |
| 89 | + this.repCode = repCodeEnum.getCode(); | |
| 90 | + this.repMsg = repCodeEnum.getDesc(); | |
| 96 | 91 | } |
| 97 | 92 | |
| 98 | - public void setRepMsg(String repMsg) { | |
| 99 | - this.repMsg = repMsg; | |
| 100 | - } | |
| 101 | - | |
| 102 | - public Object getRepData() { | |
| 103 | - return repData; | |
| 104 | - } | |
| 105 | - | |
| 106 | - public void setRepData(Object repData) { | |
| 107 | - this.repData = repData; | |
| 108 | - } | |
| 109 | - | |
| 110 | - | |
| 111 | 93 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/CaptchaVO.java
| ... | ... | @@ -6,10 +6,13 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.model.vo; |
| 8 | 8 | |
| 9 | +import lombok.Data; | |
| 10 | + | |
| 9 | 11 | import java.awt.*; |
| 10 | 12 | import java.io.Serializable; |
| 11 | 13 | import java.util.List; |
| 12 | 14 | |
| 15 | +@Data | |
| 13 | 16 | public class CaptchaVO implements Serializable { |
| 14 | 17 | |
| 15 | 18 | /** |
| ... | ... | @@ -79,173 +82,23 @@ public class CaptchaVO implements Serializable { |
| 79 | 82 | */ |
| 80 | 83 | private String captchaVerification; |
| 81 | 84 | |
| 82 | - /*** | |
| 83 | - * 客户端UI组件id,组件初始化时设置一次,UUID | |
| 84 | - */ | |
| 85 | - private String clientUid; | |
| 86 | - /*** | |
| 87 | - * 客户端的请求时间,预留字段 | |
| 88 | - */ | |
| 89 | - private Long ts; | |
| 85 | + /*** | |
| 86 | + * 客户端UI组件id,组件初始化时设置一次,UUID | |
| 87 | + */ | |
| 88 | + private String clientUid; | |
| 89 | + /*** | |
| 90 | + * 客户端的请求时间,预留字段 | |
| 91 | + */ | |
| 92 | + private Long ts; | |
| 90 | 93 | |
| 91 | 94 | /*** |
| 92 | 95 | * 客户端ip+userAgent |
| 93 | 96 | */ |
| 94 | 97 | private String browserInfo; |
| 95 | - public void resetClientFlag(){ | |
| 98 | + | |
| 99 | + public void resetClientFlag() { | |
| 96 | 100 | this.browserInfo = null; |
| 97 | 101 | this.clientUid = null; |
| 98 | 102 | } |
| 99 | 103 | |
| 100 | - public String getCaptchaId() { | |
| 101 | - return captchaId; | |
| 102 | - } | |
| 103 | - | |
| 104 | - public void setCaptchaId(String captchaId) { | |
| 105 | - this.captchaId = captchaId; | |
| 106 | - } | |
| 107 | - | |
| 108 | - public String getProjectCode() { | |
| 109 | - return projectCode; | |
| 110 | - } | |
| 111 | - | |
| 112 | - public void setProjectCode(String projectCode) { | |
| 113 | - this.projectCode = projectCode; | |
| 114 | - } | |
| 115 | - | |
| 116 | - public String getCaptchaType() { | |
| 117 | - return captchaType; | |
| 118 | - } | |
| 119 | - | |
| 120 | - public void setCaptchaType(String captchaType) { | |
| 121 | - this.captchaType = captchaType; | |
| 122 | - } | |
| 123 | - | |
| 124 | - public String getCaptchaOriginalPath() { | |
| 125 | - return captchaOriginalPath; | |
| 126 | - } | |
| 127 | - | |
| 128 | - public void setCaptchaOriginalPath(String captchaOriginalPath) { | |
| 129 | - this.captchaOriginalPath = captchaOriginalPath; | |
| 130 | - } | |
| 131 | - | |
| 132 | - public String getCaptchaFontType() { | |
| 133 | - return captchaFontType; | |
| 134 | - } | |
| 135 | - | |
| 136 | - public void setCaptchaFontType(String captchaFontType) { | |
| 137 | - this.captchaFontType = captchaFontType; | |
| 138 | - } | |
| 139 | - | |
| 140 | - public Integer getCaptchaFontSize() { | |
| 141 | - return captchaFontSize; | |
| 142 | - } | |
| 143 | - | |
| 144 | - public void setCaptchaFontSize(Integer captchaFontSize) { | |
| 145 | - this.captchaFontSize = captchaFontSize; | |
| 146 | - } | |
| 147 | - | |
| 148 | - public String getOriginalImageBase64() { | |
| 149 | - return originalImageBase64; | |
| 150 | - } | |
| 151 | - | |
| 152 | - public void setOriginalImageBase64(String originalImageBase64) { | |
| 153 | - this.originalImageBase64 = originalImageBase64; | |
| 154 | - } | |
| 155 | - | |
| 156 | - public PointVO getPoint() { | |
| 157 | - return point; | |
| 158 | - } | |
| 159 | - | |
| 160 | - public void setPoint(PointVO point) { | |
| 161 | - this.point = point; | |
| 162 | - } | |
| 163 | - | |
| 164 | - public String getJigsawImageBase64() { | |
| 165 | - return jigsawImageBase64; | |
| 166 | - } | |
| 167 | - | |
| 168 | - public void setJigsawImageBase64(String jigsawImageBase64) { | |
| 169 | - this.jigsawImageBase64 = jigsawImageBase64; | |
| 170 | - } | |
| 171 | - | |
| 172 | - public List<String> getWordList() { | |
| 173 | - return wordList; | |
| 174 | - } | |
| 175 | - | |
| 176 | - public void setWordList(List<String> wordList) { | |
| 177 | - this.wordList = wordList; | |
| 178 | - } | |
| 179 | - | |
| 180 | - public List<Point> getPointList() { | |
| 181 | - return pointList; | |
| 182 | - } | |
| 183 | - | |
| 184 | - public void setPointList(List<Point> pointList) { | |
| 185 | - this.pointList = pointList; | |
| 186 | - } | |
| 187 | - | |
| 188 | - public String getPointJson() { | |
| 189 | - return pointJson; | |
| 190 | - } | |
| 191 | - | |
| 192 | - public void setPointJson(String pointJson) { | |
| 193 | - this.pointJson = pointJson; | |
| 194 | - } | |
| 195 | - | |
| 196 | - public String getToken() { | |
| 197 | - return token; | |
| 198 | - } | |
| 199 | - | |
| 200 | - public void setToken(String token) { | |
| 201 | - this.token = token; | |
| 202 | - } | |
| 203 | - | |
| 204 | - public Boolean getResult() { | |
| 205 | - return result; | |
| 206 | - } | |
| 207 | - | |
| 208 | - public void setResult(Boolean result) { | |
| 209 | - this.result = result; | |
| 210 | - } | |
| 211 | - | |
| 212 | - public String getCaptchaVerification() { | |
| 213 | - return captchaVerification; | |
| 214 | - } | |
| 215 | - | |
| 216 | - public void setCaptchaVerification(String captchaVerification) { | |
| 217 | - this.captchaVerification = captchaVerification; | |
| 218 | - } | |
| 219 | - | |
| 220 | - public String getSecretKey() { | |
| 221 | - return secretKey; | |
| 222 | - } | |
| 223 | - | |
| 224 | - public void setSecretKey(String secretKey) { | |
| 225 | - this.secretKey = secretKey; | |
| 226 | - } | |
| 227 | - | |
| 228 | - public String getClientUid() { | |
| 229 | - return clientUid; | |
| 230 | - } | |
| 231 | - | |
| 232 | - public void setClientUid(String clientUid) { | |
| 233 | - this.clientUid = clientUid; | |
| 234 | - } | |
| 235 | - | |
| 236 | - public Long getTs() { | |
| 237 | - return ts; | |
| 238 | - } | |
| 239 | - | |
| 240 | - public void setTs(Long ts) { | |
| 241 | - this.ts = ts; | |
| 242 | - } | |
| 243 | - | |
| 244 | - public String getBrowserInfo() { | |
| 245 | - return browserInfo; | |
| 246 | - } | |
| 247 | - | |
| 248 | - public void setBrowserInfo(String browserInfo) { | |
| 249 | - this.browserInfo = browserInfo; | |
| 250 | - } | |
| 251 | 104 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/vo/PointVO.java
| 1 | 1 | package com.anji.captcha.model.vo; |
| 2 | 2 | |
| 3 | +import lombok.Data; | |
| 4 | + | |
| 3 | 5 | import java.util.Arrays; |
| 4 | 6 | import java.util.HashMap; |
| 5 | 7 | import java.util.Map; |
| ... | ... | @@ -9,6 +11,7 @@ import java.util.regex.Pattern; |
| 9 | 11 | /** |
| 10 | 12 | * Created by raodeming on 2020/5/16. |
| 11 | 13 | */ |
| 14 | +@Data | |
| 12 | 15 | public class PointVO { |
| 13 | 16 | private String secretKey; |
| 14 | 17 | |
| ... | ... | @@ -16,30 +19,6 @@ public class PointVO { |
| 16 | 19 | |
| 17 | 20 | public int y; |
| 18 | 21 | |
| 19 | - public String getSecretKey() { | |
| 20 | - return secretKey; | |
| 21 | - } | |
| 22 | - | |
| 23 | - public void setSecretKey(String secretKey) { | |
| 24 | - this.secretKey = secretKey; | |
| 25 | - } | |
| 26 | - | |
| 27 | - public int getX() { | |
| 28 | - return x; | |
| 29 | - } | |
| 30 | - | |
| 31 | - public void setX(int x) { | |
| 32 | - this.x = x; | |
| 33 | - } | |
| 34 | - | |
| 35 | - public int getY() { | |
| 36 | - return y; | |
| 37 | - } | |
| 38 | - | |
| 39 | - public void setY(int y) { | |
| 40 | - this.y = y; | |
| 41 | - } | |
| 42 | - | |
| 43 | 22 | public PointVO(int x, int y, String secretKey) { |
| 44 | 23 | this.secretKey = secretKey; |
| 45 | 24 | this.x = x; | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/properties/AjCaptchaProperties.java
| 1 | 1 | package com.anji.captcha.properties; |
| 2 | 2 | |
| 3 | 3 | import com.anji.captcha.model.common.CaptchaTypeEnum; |
| 4 | +import lombok.Data; | |
| 4 | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; |
| 5 | 6 | |
| 6 | 7 | import java.awt.*; |
| ... | ... | @@ -8,6 +9,7 @@ import java.awt.*; |
| 8 | 9 | import static com.anji.captcha.properties.AjCaptchaProperties.PREFIX; |
| 9 | 10 | import static com.anji.captcha.properties.AjCaptchaProperties.StorageType.local; |
| 10 | 11 | |
| 12 | +@Data | |
| 11 | 13 | @ConfigurationProperties(PREFIX) |
| 12 | 14 | public class AjCaptchaProperties { |
| 13 | 15 | public static final String PREFIX = "aj.captcha"; |
| ... | ... | @@ -113,90 +115,10 @@ public class AjCaptchaProperties { |
| 113 | 115 | */ |
| 114 | 116 | private int clickWordCount = 4; |
| 115 | 117 | |
| 116 | - public int getFontStyle() { | |
| 117 | - return fontStyle; | |
| 118 | - } | |
| 119 | - | |
| 120 | - public void setFontStyle(int fontStyle) { | |
| 121 | - this.fontStyle = fontStyle; | |
| 122 | - } | |
| 123 | - | |
| 124 | - public int getFontSize() { | |
| 125 | - return fontSize; | |
| 126 | - } | |
| 127 | - | |
| 128 | - public void setFontSize(int fontSize) { | |
| 129 | - this.fontSize = fontSize; | |
| 130 | - } | |
| 131 | - | |
| 132 | - public int getClickWordCount() { | |
| 133 | - return clickWordCount; | |
| 134 | - } | |
| 135 | - | |
| 136 | - public void setClickWordCount(int clickWordCount) { | |
| 137 | - this.clickWordCount = clickWordCount; | |
| 138 | - } | |
| 139 | - | |
| 140 | - public boolean isHistoryDataClearEnable() { | |
| 141 | - return historyDataClearEnable; | |
| 142 | - } | |
| 143 | - | |
| 144 | - public void setHistoryDataClearEnable(boolean historyDataClearEnable) { | |
| 145 | - this.historyDataClearEnable = historyDataClearEnable; | |
| 146 | - } | |
| 147 | - | |
| 148 | - public boolean isReqFrequencyLimitEnable() { | |
| 149 | - return reqFrequencyLimitEnable; | |
| 150 | - } | |
| 151 | - | |
| 152 | 118 | public boolean getReqFrequencyLimitEnable() { |
| 153 | 119 | return reqFrequencyLimitEnable; |
| 154 | 120 | } |
| 155 | 121 | |
| 156 | - public void setReqFrequencyLimitEnable(boolean reqFrequencyLimitEnable) { | |
| 157 | - this.reqFrequencyLimitEnable = reqFrequencyLimitEnable; | |
| 158 | - } | |
| 159 | - | |
| 160 | - public int getReqGetLockLimit() { | |
| 161 | - return reqGetLockLimit; | |
| 162 | - } | |
| 163 | - | |
| 164 | - public void setReqGetLockLimit(int reqGetLockLimit) { | |
| 165 | - this.reqGetLockLimit = reqGetLockLimit; | |
| 166 | - } | |
| 167 | - | |
| 168 | - public int getReqGetLockSeconds() { | |
| 169 | - return reqGetLockSeconds; | |
| 170 | - } | |
| 171 | - | |
| 172 | - public void setReqGetLockSeconds(int reqGetLockSeconds) { | |
| 173 | - this.reqGetLockSeconds = reqGetLockSeconds; | |
| 174 | - } | |
| 175 | - | |
| 176 | - public int getReqGetMinuteLimit() { | |
| 177 | - return reqGetMinuteLimit; | |
| 178 | - } | |
| 179 | - | |
| 180 | - public void setReqGetMinuteLimit(int reqGetMinuteLimit) { | |
| 181 | - this.reqGetMinuteLimit = reqGetMinuteLimit; | |
| 182 | - } | |
| 183 | - | |
| 184 | - public int getReqCheckMinuteLimit() { | |
| 185 | - return reqGetMinuteLimit; | |
| 186 | - } | |
| 187 | - | |
| 188 | - public void setReqCheckMinuteLimit(int reqCheckMinuteLimit) { | |
| 189 | - this.reqCheckMinuteLimit = reqCheckMinuteLimit; | |
| 190 | - } | |
| 191 | - | |
| 192 | - public int getReqVerifyMinuteLimit() { | |
| 193 | - return reqVerifyMinuteLimit; | |
| 194 | - } | |
| 195 | - | |
| 196 | - public void setReqVerifyMinuteLimit(int reqVerifyMinuteLimit) { | |
| 197 | - this.reqVerifyMinuteLimit = reqVerifyMinuteLimit; | |
| 198 | - } | |
| 199 | - | |
| 200 | 122 | public enum StorageType { |
| 201 | 123 | /** |
| 202 | 124 | * 内存. |
| ... | ... | @@ -216,123 +138,4 @@ public class AjCaptchaProperties { |
| 216 | 138 | return PREFIX; |
| 217 | 139 | } |
| 218 | 140 | |
| 219 | - public CaptchaTypeEnum getType() { | |
| 220 | - return type; | |
| 221 | - } | |
| 222 | - | |
| 223 | - public void setType(CaptchaTypeEnum type) { | |
| 224 | - this.type = type; | |
| 225 | - } | |
| 226 | - | |
| 227 | - public String getJigsaw() { | |
| 228 | - return jigsaw; | |
| 229 | - } | |
| 230 | - | |
| 231 | - public void setJigsaw(String jigsaw) { | |
| 232 | - this.jigsaw = jigsaw; | |
| 233 | - } | |
| 234 | - | |
| 235 | - public String getPicClick() { | |
| 236 | - return picClick; | |
| 237 | - } | |
| 238 | - | |
| 239 | - public void setPicClick(String picClick) { | |
| 240 | - this.picClick = picClick; | |
| 241 | - } | |
| 242 | - | |
| 243 | - public String getWaterMark() { | |
| 244 | - return waterMark; | |
| 245 | - } | |
| 246 | - | |
| 247 | - public void setWaterMark(String waterMark) { | |
| 248 | - this.waterMark = waterMark; | |
| 249 | - } | |
| 250 | - | |
| 251 | - public String getWaterFont() { | |
| 252 | - return waterFont; | |
| 253 | - } | |
| 254 | - | |
| 255 | - public void setWaterFont(String waterFont) { | |
| 256 | - this.waterFont = waterFont; | |
| 257 | - } | |
| 258 | - | |
| 259 | - public String getFontType() { | |
| 260 | - return fontType; | |
| 261 | - } | |
| 262 | - | |
| 263 | - public void setFontType(String fontType) { | |
| 264 | - this.fontType = fontType; | |
| 265 | - } | |
| 266 | - | |
| 267 | - public String getSlipOffset() { | |
| 268 | - return slipOffset; | |
| 269 | - } | |
| 270 | - | |
| 271 | - public void setSlipOffset(String slipOffset) { | |
| 272 | - this.slipOffset = slipOffset; | |
| 273 | - } | |
| 274 | - | |
| 275 | - public Boolean getAesStatus() { | |
| 276 | - return aesStatus; | |
| 277 | - } | |
| 278 | - | |
| 279 | - public void setAesStatus(Boolean aesStatus) { | |
| 280 | - this.aesStatus = aesStatus; | |
| 281 | - } | |
| 282 | - | |
| 283 | - public StorageType getCacheType() { | |
| 284 | - return cacheType; | |
| 285 | - } | |
| 286 | - | |
| 287 | - public void setCacheType(StorageType cacheType) { | |
| 288 | - this.cacheType = cacheType; | |
| 289 | - } | |
| 290 | - | |
| 291 | - public String getInterferenceOptions() { | |
| 292 | - return interferenceOptions; | |
| 293 | - } | |
| 294 | - | |
| 295 | - public void setInterferenceOptions(String interferenceOptions) { | |
| 296 | - this.interferenceOptions = interferenceOptions; | |
| 297 | - } | |
| 298 | - | |
| 299 | - public String getCacheNumber() { | |
| 300 | - return cacheNumber; | |
| 301 | - } | |
| 302 | - | |
| 303 | - public void setCacheNumber(String cacheNumber) { | |
| 304 | - this.cacheNumber = cacheNumber; | |
| 305 | - } | |
| 306 | - | |
| 307 | - public String getTimingClear() { | |
| 308 | - return timingClear; | |
| 309 | - } | |
| 310 | - | |
| 311 | - public void setTimingClear(String timingClear) { | |
| 312 | - this.timingClear = timingClear; | |
| 313 | - } | |
| 314 | - | |
| 315 | - @Override | |
| 316 | - public String toString() { | |
| 317 | - return "\nAjCaptchaProperties{" + | |
| 318 | - "type=" + type + | |
| 319 | - ", jigsaw='" + jigsaw + '\'' + | |
| 320 | - ", picClick='" + picClick + '\'' + | |
| 321 | - ", waterMark='" + waterMark + '\'' + | |
| 322 | - ", waterFont='" + waterFont + '\'' + | |
| 323 | - ", fontType='" + fontType + '\'' + | |
| 324 | - ", slipOffset='" + slipOffset + '\'' + | |
| 325 | - ", aesStatus=" + aesStatus + | |
| 326 | - ", interferenceOptions='" + interferenceOptions + '\'' + | |
| 327 | - ", cacheNumber='" + cacheNumber + '\'' + | |
| 328 | - ", timingClear='" + timingClear + '\'' + | |
| 329 | - ", cacheType=" + cacheType + | |
| 330 | - ", reqFrequencyLimitEnable=" + reqFrequencyLimitEnable + | |
| 331 | - ", reqGetLockLimit=" + reqGetLockLimit + | |
| 332 | - ", reqGetLockSeconds=" + reqGetLockSeconds + | |
| 333 | - ", reqGetMinuteLimit=" + reqGetMinuteLimit + | |
| 334 | - ", reqCheckMinuteLimit=" + reqCheckMinuteLimit + | |
| 335 | - ", reqVerifyMinuteLimit=" + reqVerifyMinuteLimit + | |
| 336 | - '}'; | |
| 337 | - } | |
| 338 | 141 | } | ... | ... |
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; |
| 8 | 8 | |
| 9 | 9 | /** |
| 10 | 10 | * 验证码缓存接口 |
| 11 | + * | |
| 11 | 12 | * @author lide1202@hotmail.com |
| 12 | 13 | * @date 2018-08-21 |
| 13 | 14 | */ |
| 14 | 15 | public interface CaptchaCacheService { |
| 15 | 16 | |
| 16 | - void set(String key, String value, long expiresInSeconds); | |
| 17 | + void set(String key, String value, long expiresInSeconds); | |
| 17 | 18 | |
| 18 | - boolean exists(String key); | |
| 19 | + boolean exists(String key); | |
| 19 | 20 | |
| 20 | - void delete(String key); | |
| 21 | + void delete(String key); | |
| 21 | 22 | |
| 22 | - String get(String key); | |
| 23 | + String get(String key); | |
| 23 | 24 | |
| 24 | - /** | |
| 25 | - * 缓存类型-local/redis/memcache/.. | |
| 26 | - * 通过java SPI机制,接入方可自定义实现类 | |
| 27 | - * @return | |
| 28 | - */ | |
| 29 | - String type(); | |
| 25 | + /** | |
| 26 | + * 缓存类型-local/redis/memcache/.. | |
| 27 | + * 通过java SPI机制,接入方可自定义实现类 | |
| 28 | + * | |
| 29 | + * @return | |
| 30 | + */ | |
| 31 | + String type(); | |
| 30 | 32 | |
| 31 | - /*** | |
| 32 | - * | |
| 33 | - * @param key | |
| 34 | - * @param val | |
| 35 | - * @return | |
| 36 | - */ | |
| 37 | - default Long increment(String key, long val){ | |
| 38 | - return 0L; | |
| 39 | - }; | |
| 33 | + /*** | |
| 34 | + * | |
| 35 | + * @param key | |
| 36 | + * @param val | |
| 37 | + * @return | |
| 38 | + */ | |
| 39 | + default Long increment(String key, long val) { | |
| 40 | + return 0L; | |
| 41 | + } | |
| 40 | 42 | |
| 41 | 43 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/CaptchaService.java
| ... | ... | @@ -13,6 +13,7 @@ import java.util.Properties; |
| 13 | 13 | |
| 14 | 14 | /** |
| 15 | 15 | * 验证码服务接口 |
| 16 | + * | |
| 16 | 17 | * @author lide1202@hotmail.com |
| 17 | 18 | * @date 2020-05-12 |
| 18 | 19 | */ |
| ... | ... | @@ -24,6 +25,7 @@ public interface CaptchaService { |
| 24 | 25 | |
| 25 | 26 | /** |
| 26 | 27 | * 获取验证码 |
| 28 | + * | |
| 27 | 29 | * @param captchaVO |
| 28 | 30 | * @return |
| 29 | 31 | */ |
| ... | ... | @@ -31,6 +33,7 @@ public interface CaptchaService { |
| 31 | 33 | |
| 32 | 34 | /** |
| 33 | 35 | * 核对验证码(前端) |
| 36 | + * | |
| 34 | 37 | * @param captchaVO |
| 35 | 38 | * @return |
| 36 | 39 | */ |
| ... | ... | @@ -38,6 +41,7 @@ public interface CaptchaService { |
| 38 | 41 | |
| 39 | 42 | /** |
| 40 | 43 | * 二次校验验证码(后端) |
| 44 | + * | |
| 41 | 45 | * @param captchaVO |
| 42 | 46 | * @return |
| 43 | 47 | */ |
| ... | ... | @@ -50,9 +54,10 @@ public interface CaptchaService { |
| 50 | 54 | */ |
| 51 | 55 | String captchaType(); |
| 52 | 56 | |
| 53 | - /** | |
| 54 | - * 历史资源清除(过期的图片文件,生成的临时图片...) | |
| 55 | - * @param config 配置项 控制资源清理的粒度 | |
| 56 | - */ | |
| 57 | - void destroy(Properties config); | |
| 57 | + /** | |
| 58 | + * 历史资源清除(过期的图片文件,生成的临时图片...) | |
| 59 | + * | |
| 60 | + * @param config 配置项 控制资源清理的粒度 | |
| 61 | + */ | |
| 62 | + void destroy(Properties config); | |
| 58 | 63 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/AbstractCaptchaService.java
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | |
| 9 | +import cn.hutool.core.util.StrUtil; | |
| 9 | 10 | import com.anji.captcha.model.common.Const; |
| 10 | 11 | import com.anji.captcha.model.common.RepCodeEnum; |
| 11 | 12 | import com.anji.captcha.model.common.ResponseModel; |
| ... | ... | @@ -13,29 +14,28 @@ import com.anji.captcha.model.vo.CaptchaVO; |
| 13 | 14 | import com.anji.captcha.service.CaptchaCacheService; |
| 14 | 15 | import com.anji.captcha.service.CaptchaService; |
| 15 | 16 | import com.anji.captcha.util.*; |
| 16 | -import org.slf4j.Logger; | |
| 17 | -import org.slf4j.LoggerFactory; | |
| 17 | +import lombok.extern.slf4j.Slf4j; | |
| 18 | 18 | |
| 19 | 19 | import java.awt.*; |
| 20 | 20 | import java.io.File; |
| 21 | -import java.io.FileOutputStream; | |
| 22 | 21 | import java.io.OutputStream; |
| 23 | 22 | import java.nio.charset.StandardCharsets; |
| 23 | +import java.nio.file.Files; | |
| 24 | 24 | import java.util.Base64; |
| 25 | +import java.util.Objects; | |
| 25 | 26 | import java.util.Properties; |
| 26 | 27 | |
| 27 | 28 | /** |
| 28 | 29 | * Created by raodeming on 2019/12/25. |
| 29 | 30 | */ |
| 31 | +@Slf4j | |
| 30 | 32 | public abstract class AbstractCaptchaService implements CaptchaService { |
| 31 | 33 | |
| 32 | - protected Logger logger = LoggerFactory.getLogger(getClass()); | |
| 33 | - | |
| 34 | 34 | protected static final String IMAGE_TYPE_PNG = "png"; |
| 35 | 35 | |
| 36 | - protected static int HAN_ZI_SIZE = 25; | |
| 36 | + protected static int HAN_ZI_SIZE = 25; | |
| 37 | 37 | |
| 38 | - protected static int HAN_ZI_SIZE_HALF = HAN_ZI_SIZE / 2; | |
| 38 | + protected static int HAN_ZI_SIZE_HALF = HAN_ZI_SIZE / 2; | |
| 39 | 39 | //check校验坐标 |
| 40 | 40 | protected static String REDIS_CAPTCHA_KEY = "RUNNING:CAPTCHA:%s"; |
| 41 | 41 | |
| ... | ... | @@ -73,7 +73,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 73 | 73 | ImageUtils.cacheImage(config.getProperty(Const.ORIGINAL_PATH_JIGSAW), |
| 74 | 74 | config.getProperty(Const.ORIGINAL_PATH_PIC_CLICK)); |
| 75 | 75 | } |
| 76 | - logger.info("--->>>初始化验证码底图<<<---" + captchaType()); | |
| 76 | + log.info("--->>>初始化验证码底图<<<---" + captchaType()); | |
| 77 | 77 | waterMark = config.getProperty(Const.CAPTCHA_WATER_MARK, "我的水印"); |
| 78 | 78 | slipOffset = config.getProperty(Const.CAPTCHA_SLIP_OFFSET, "5"); |
| 79 | 79 | waterMarkFontStr = config.getProperty(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); |
| ... | ... | @@ -88,13 +88,13 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 88 | 88 | // 通过加载resources下的font字体解决,无需在linux中安装字体 |
| 89 | 89 | loadWaterMarkFont(); |
| 90 | 90 | |
| 91 | - if (cacheType.equals("local")) { | |
| 92 | - logger.info("初始化local缓存..."); | |
| 91 | + if ("local".equals(cacheType)) { | |
| 92 | + log.info("初始化local缓存..."); | |
| 93 | 93 | CacheUtil.init(Integer.parseInt(config.getProperty(Const.CAPTCHA_CACAHE_MAX_NUMBER, "1000")), |
| 94 | 94 | Long.parseLong(config.getProperty(Const.CAPTCHA_TIMING_CLEAR_SECOND, "180"))); |
| 95 | 95 | } |
| 96 | - if (config.getProperty(Const.HISTORY_DATA_CLEAR_ENABLE, "0").equals("1")) { | |
| 97 | - logger.info("历史资源清除开关...开启..." + captchaType()); | |
| 96 | + if ("1".equals(config.getProperty(Const.HISTORY_DATA_CLEAR_ENABLE, "0"))) { | |
| 97 | + log.info("历史资源清除开关...开启..." + captchaType()); | |
| 98 | 98 | Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { |
| 99 | 99 | @Override |
| 100 | 100 | public void run() { |
| ... | ... | @@ -102,9 +102,9 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 102 | 102 | } |
| 103 | 103 | })); |
| 104 | 104 | } |
| 105 | - if (config.getProperty(Const.REQ_FREQUENCY_LIMIT_ENABLE, "0").equals("1")) { | |
| 105 | + if ("1".equals(config.getProperty(Const.REQ_FREQUENCY_LIMIT_ENABLE, "0"))) { | |
| 106 | 106 | if (limitHandler == null) { |
| 107 | - logger.info("接口分钟内限流开关...开启..."); | |
| 107 | + log.info("接口分钟内限流开关...开启..."); | |
| 108 | 108 | limitHandler = new FrequencyLimitHandler.DefaultLimitHandler(config, getCacheService(cacheType)); |
| 109 | 109 | } |
| 110 | 110 | } |
| ... | ... | @@ -150,7 +150,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 150 | 150 | if (captchaVO == null) { |
| 151 | 151 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 152 | 152 | } |
| 153 | - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { | |
| 153 | + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { | |
| 154 | 154 | return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); |
| 155 | 155 | } |
| 156 | 156 | if (limitHandler != null) { |
| ... | ... | @@ -163,17 +163,17 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 163 | 163 | return resp == null || resp.isSuccess(); |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | - protected String getValidateClientId(CaptchaVO req){ | |
| 167 | - // 以服务端获取的客户端标识 做识别标志 | |
| 168 | - if(StringUtils.isNotEmpty(req.getBrowserInfo())){ | |
| 169 | - return MD5Util.md5(req.getBrowserInfo()); | |
| 170 | - } | |
| 171 | - // 以客户端Ui组件id做识别标志 | |
| 172 | - if(StringUtils.isNotEmpty(req.getClientUid())){ | |
| 173 | - return req.getClientUid(); | |
| 174 | - } | |
| 175 | - return null; | |
| 176 | - } | |
| 166 | + protected String getValidateClientId(CaptchaVO req) { | |
| 167 | + // 以服务端获取的客户端标识 做识别标志 | |
| 168 | + if (StrUtil.isNotEmpty(req.getBrowserInfo())) { | |
| 169 | + return MD5Util.md5(req.getBrowserInfo()); | |
| 170 | + } | |
| 171 | + // 以客户端Ui组件id做识别标志 | |
| 172 | + if (StrUtil.isNotEmpty(req.getClientUid())) { | |
| 173 | + return req.getClientUid(); | |
| 174 | + } | |
| 175 | + return null; | |
| 176 | + } | |
| 177 | 177 | |
| 178 | 178 | protected void afterValidateFail(CaptchaVO data) { |
| 179 | 179 | if (limitHandler != null) { |
| ... | ... | @@ -197,14 +197,14 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 197 | 197 | if (waterMarkFontStr.toLowerCase().endsWith(".ttf") || waterMarkFontStr.toLowerCase().endsWith(".ttc") |
| 198 | 198 | || waterMarkFontStr.toLowerCase().endsWith(".otf")) { |
| 199 | 199 | this.waterMarkFont = Font.createFont(Font.TRUETYPE_FONT, |
| 200 | - getClass().getResourceAsStream("/fonts/" + waterMarkFontStr)) | |
| 200 | + Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + waterMarkFontStr))) | |
| 201 | 201 | .deriveFont(Font.BOLD, HAN_ZI_SIZE / 2); |
| 202 | 202 | } else { |
| 203 | 203 | this.waterMarkFont = new Font(waterMarkFontStr, Font.BOLD, HAN_ZI_SIZE / 2); |
| 204 | 204 | } |
| 205 | 205 | |
| 206 | 206 | } catch (Exception e) { |
| 207 | - logger.error("load font error:{}", e); | |
| 207 | + log.error("load font error:{}", e); | |
| 208 | 208 | } |
| 209 | 209 | } |
| 210 | 210 | |
| ... | ... | @@ -228,7 +228,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { |
| 228 | 228 | if (!tempFile.getParentFile().exists()) { |
| 229 | 229 | tempFile.getParentFile().mkdirs(); |
| 230 | 230 | } |
| 231 | - OutputStream out = new FileOutputStream(tempFile); | |
| 231 | + OutputStream out = Files.newOutputStream(tempFile.toPath()); | |
| 232 | 232 | out.write(b); |
| 233 | 233 | out.flush(); |
| 234 | 234 | out.close(); | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/BlockPuzzleCaptchaServiceImpl.java
| ... | ... | @@ -6,12 +6,14 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | |
| 9 | +import cn.hutool.core.util.StrUtil; | |
| 9 | 10 | import com.anji.captcha.model.common.CaptchaTypeEnum; |
| 10 | 11 | import com.anji.captcha.model.common.RepCodeEnum; |
| 11 | 12 | import com.anji.captcha.model.common.ResponseModel; |
| 12 | 13 | import com.anji.captcha.model.vo.CaptchaVO; |
| 13 | 14 | import com.anji.captcha.model.vo.PointVO; |
| 14 | 15 | import com.anji.captcha.util.*; |
| 16 | +import lombok.extern.slf4j.Slf4j; | |
| 15 | 17 | |
| 16 | 18 | import javax.imageio.ImageIO; |
| 17 | 19 | import java.awt.*; |
| ... | ... | @@ -27,6 +29,7 @@ import java.util.Random; |
| 27 | 29 | * <p> |
| 28 | 30 | * Created by raodeming on 2019/12/25. |
| 29 | 31 | */ |
| 32 | +@Slf4j | |
| 30 | 33 | public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 31 | 34 | |
| 32 | 35 | @Override |
| ... | ... | @@ -34,10 +37,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 34 | 37 | super.init(config); |
| 35 | 38 | } |
| 36 | 39 | |
| 37 | - @Override | |
| 38 | - public void destroy(Properties config) { | |
| 39 | - logger.info("start-clear-history-data-",captchaType()); | |
| 40 | - } | |
| 40 | + @Override | |
| 41 | + public void destroy(Properties config) { | |
| 42 | + log.info("start-clear-history-data-", captchaType()); | |
| 43 | + } | |
| 41 | 44 | |
| 42 | 45 | @Override |
| 43 | 46 | public String captchaType() { |
| ... | ... | @@ -46,14 +49,14 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 46 | 49 | |
| 47 | 50 | @Override |
| 48 | 51 | public ResponseModel get(CaptchaVO captchaVO) { |
| 49 | - ResponseModel r = super.get(captchaVO); | |
| 50 | - if(!validatedReq(r)){ | |
| 51 | - return r; | |
| 52 | - } | |
| 52 | + ResponseModel r = super.get(captchaVO); | |
| 53 | + if (!validatedReq(r)) { | |
| 54 | + return r; | |
| 55 | + } | |
| 53 | 56 | //原生图片 |
| 54 | 57 | BufferedImage originalImage = ImageUtils.getOriginal(); |
| 55 | 58 | if (null == originalImage) { |
| 56 | - logger.error("滑动底图未初始化成功,请检查路径"); | |
| 59 | + log.error("滑动底图未初始化成功,请检查路径"); | |
| 57 | 60 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); |
| 58 | 61 | } |
| 59 | 62 | //设置水印 |
| ... | ... | @@ -68,13 +71,13 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 68 | 71 | String jigsawImageBase64 = ImageUtils.getslidingBlock(); |
| 69 | 72 | BufferedImage jigsawImage = ImageUtils.getBase64StrToImage(jigsawImageBase64); |
| 70 | 73 | if (null == jigsawImage) { |
| 71 | - logger.error("滑动底图未初始化成功,请检查路径"); | |
| 74 | + log.error("滑动底图未初始化成功,请检查路径"); | |
| 72 | 75 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); |
| 73 | 76 | } |
| 74 | 77 | CaptchaVO captcha = pictureTemplatesCut(originalImage, jigsawImage, jigsawImageBase64); |
| 75 | 78 | if (captcha == null |
| 76 | - || StringUtils.isBlank(captcha.getJigsawImageBase64()) | |
| 77 | - || StringUtils.isBlank(captcha.getOriginalImageBase64())) { | |
| 79 | + || StrUtil.isBlank(captcha.getJigsawImageBase64()) | |
| 80 | + || StrUtil.isBlank(captcha.getOriginalImageBase64())) { | |
| 78 | 81 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); |
| 79 | 82 | } |
| 80 | 83 | return ResponseModel.successData(captcha); |
| ... | ... | @@ -82,10 +85,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 82 | 85 | |
| 83 | 86 | @Override |
| 84 | 87 | public ResponseModel check(CaptchaVO captchaVO) { |
| 85 | - ResponseModel r = super.check(captchaVO); | |
| 86 | - if(!validatedReq(r)){ | |
| 87 | - return r; | |
| 88 | - } | |
| 88 | + ResponseModel r = super.check(captchaVO); | |
| 89 | + if (!validatedReq(r)) { | |
| 90 | + return r; | |
| 91 | + } | |
| 89 | 92 | //取坐标信息 |
| 90 | 93 | String codeKey = String.format(REDIS_CAPTCHA_KEY, captchaVO.getToken()); |
| 91 | 94 | if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { |
| ... | ... | @@ -103,7 +106,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 103 | 106 | pointJson = decrypt(captchaVO.getPointJson(), point.getSecretKey()); |
| 104 | 107 | point1 = JsonUtil.parseObject(pointJson, PointVO.class); |
| 105 | 108 | } catch (Exception e) { |
| 106 | - logger.error("验证码坐标解析失败", e); | |
| 109 | + log.error("验证码坐标解析失败", e); | |
| 107 | 110 | afterValidateFail(captchaVO); |
| 108 | 111 | return ResponseModel.errorMsg(e.getMessage()); |
| 109 | 112 | } |
| ... | ... | @@ -119,7 +122,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 119 | 122 | try { |
| 120 | 123 | value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); |
| 121 | 124 | } catch (Exception e) { |
| 122 | - logger.error("AES加密失败", e); | |
| 125 | + log.error("AES加密失败", e); | |
| 123 | 126 | afterValidateFail(captchaVO); |
| 124 | 127 | return ResponseModel.errorMsg(e.getMessage()); |
| 125 | 128 | } |
| ... | ... | @@ -132,10 +135,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 132 | 135 | |
| 133 | 136 | @Override |
| 134 | 137 | public ResponseModel verification(CaptchaVO captchaVO) { |
| 135 | - ResponseModel r = super.verification(captchaVO); | |
| 136 | - if(!validatedReq(r)){ | |
| 137 | - return r; | |
| 138 | - } | |
| 138 | + ResponseModel r = super.verification(captchaVO); | |
| 139 | + if (!validatedReq(r)) { | |
| 140 | + return r; | |
| 141 | + } | |
| 139 | 142 | try { |
| 140 | 143 | String codeKey = String.format(REDIS_SECOND_CAPTCHA_KEY, captchaVO.getCaptchaVerification()); |
| 141 | 144 | if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { |
| ... | ... | @@ -144,7 +147,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 144 | 147 | //二次校验取值后,即刻失效 |
| 145 | 148 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); |
| 146 | 149 | } catch (Exception e) { |
| 147 | - logger.error("验证码坐标解析失败", e); | |
| 150 | + log.error("验证码坐标解析失败", e); | |
| 148 | 151 | return ResponseModel.errorMsg(e.getMessage()); |
| 149 | 152 | } |
| 150 | 153 | return ResponseModel.success(); |
| ... | ... | @@ -234,7 +237,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 234 | 237 | //将坐标信息存入redis中 |
| 235 | 238 | String codeKey = String.format(REDIS_CAPTCHA_KEY, dataVO.getToken()); |
| 236 | 239 | CaptchaServiceFactory.getCache(cacheType).set(codeKey, JsonUtil.toJSONString(point), EXPIRESIN_SECONDS); |
| 237 | - logger.debug("token:{},point:{}", dataVO.getToken(), JsonUtil.toJSONString(point)); | |
| 240 | + log.debug("token:{},point:{}", dataVO.getToken(), JsonUtil.toJSONString(point)); | |
| 238 | 241 | return dataVO; |
| 239 | 242 | } catch (Exception e) { |
| 240 | 243 | e.printStackTrace(); | ... | ... |
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; |
| 3 | 3 | import com.anji.captcha.service.CaptchaCacheService; |
| 4 | 4 | import com.anji.captcha.util.CacheUtil; |
| 5 | 5 | |
| 6 | +import java.util.Objects; | |
| 7 | + | |
| 6 | 8 | /** |
| 7 | 9 | * 对于分布式部署的应用,我们建议应用自己实现CaptchaCacheService,比如用Redis,参考service/spring-boot代码示例。 |
| 8 | 10 | * 如果应用是单点的,也没有使用redis,那默认使用内存。 |
| 9 | 11 | * 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。 |
| 10 | - * @Title: 默认使用内存当缓存 | |
| 12 | + * | |
| 11 | 13 | * @author lide1202@hotmail.com |
| 14 | + * @Title: 默认使用内存当缓存 | |
| 12 | 15 | * @date 2020-05-12 |
| 13 | 16 | */ |
| 14 | 17 | public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { |
| ... | ... | @@ -33,14 +36,14 @@ public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { |
| 33 | 36 | return CacheUtil.get(key); |
| 34 | 37 | } |
| 35 | 38 | |
| 36 | - @Override | |
| 37 | - public Long increment(String key, long val) { | |
| 38 | - Long ret = Long.valueOf(CacheUtil.get(key))+val; | |
| 39 | - CacheUtil.set(key,ret+"",0); | |
| 40 | - return ret; | |
| 41 | - } | |
| 39 | + @Override | |
| 40 | + public Long increment(String key, long val) { | |
| 41 | + Long ret = Long.parseLong(Objects.requireNonNull(CacheUtil.get(key))) + val; | |
| 42 | + CacheUtil.set(key, ret + "", 0); | |
| 43 | + return ret; | |
| 44 | + } | |
| 42 | 45 | |
| 43 | - @Override | |
| 46 | + @Override | |
| 44 | 47 | public String type() { |
| 45 | 48 | return "local"; |
| 46 | 49 | } | ... | ... |
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; |
| 3 | 3 | import com.anji.captcha.model.common.Const; |
| 4 | 4 | import com.anji.captcha.service.CaptchaCacheService; |
| 5 | 5 | import com.anji.captcha.service.CaptchaService; |
| 6 | -import org.slf4j.Logger; | |
| 7 | -import org.slf4j.LoggerFactory; | |
| 6 | +import lombok.extern.slf4j.Slf4j; | |
| 8 | 7 | |
| 9 | 8 | import java.util.HashMap; |
| 10 | 9 | import java.util.Map; |
| ... | ... | @@ -14,10 +13,9 @@ import java.util.ServiceLoader; |
| 14 | 13 | /** |
| 15 | 14 | * Created by raodeming on 2020/5/26. |
| 16 | 15 | */ |
| 16 | +@Slf4j | |
| 17 | 17 | public class CaptchaServiceFactory { |
| 18 | 18 | |
| 19 | - private static Logger logger = LoggerFactory.getLogger(CaptchaServiceFactory.class); | |
| 20 | - | |
| 21 | 19 | public static CaptchaService getInstance(Properties config) { |
| 22 | 20 | //先把所有CaptchaService初始化,通过init方法,实例字体等,add by lide1202@hotmail.com |
| 23 | 21 | /*try{ |
| ... | ... | @@ -41,20 +39,20 @@ public class CaptchaServiceFactory { |
| 41 | 39 | return cacheService.get(cacheType); |
| 42 | 40 | } |
| 43 | 41 | |
| 44 | - public volatile static Map<String, CaptchaService> instances = new HashMap(); | |
| 45 | - public volatile static Map<String, CaptchaCacheService> cacheService = new HashMap(); | |
| 42 | + public volatile static Map<String, CaptchaService> instances = new HashMap<>(); | |
| 43 | + public volatile static Map<String, CaptchaCacheService> cacheService = new HashMap<>(); | |
| 46 | 44 | |
| 47 | 45 | static { |
| 48 | 46 | ServiceLoader<CaptchaCacheService> cacheServices = ServiceLoader.load(CaptchaCacheService.class); |
| 49 | 47 | for (CaptchaCacheService item : cacheServices) { |
| 50 | 48 | cacheService.put(item.type(), item); |
| 51 | 49 | } |
| 52 | - logger.info("supported-captchaCache-service:{}", cacheService.keySet().toString()); | |
| 50 | + log.info("supported-captchaCache-service:{}", cacheService.keySet().toString()); | |
| 53 | 51 | ServiceLoader<CaptchaService> services = ServiceLoader.load(CaptchaService.class); |
| 54 | 52 | for (CaptchaService item : services) { |
| 55 | 53 | instances.put(item.captchaType(), item); |
| 56 | 54 | } |
| 57 | 55 | ; |
| 58 | - logger.info("supported-captchaTypes-service:{}", instances.keySet().toString()); | |
| 56 | + log.info("supported-captchaTypes-service:{}", instances.keySet().toString()); | |
| 59 | 57 | } |
| 60 | 58 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/ClickWordCaptchaServiceImpl.java
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | |
| 9 | +import cn.hutool.core.util.StrUtil; | |
| 9 | 10 | import com.anji.captcha.model.common.CaptchaTypeEnum; |
| 10 | 11 | import com.anji.captcha.model.common.Const; |
| 11 | 12 | import com.anji.captcha.model.common.RepCodeEnum; |
| ... | ... | @@ -13,6 +14,7 @@ import com.anji.captcha.model.common.ResponseModel; |
| 13 | 14 | import com.anji.captcha.model.vo.CaptchaVO; |
| 14 | 15 | import com.anji.captcha.model.vo.PointVO; |
| 15 | 16 | import com.anji.captcha.util.*; |
| 17 | +import lombok.extern.slf4j.Slf4j; | |
| 16 | 18 | |
| 17 | 19 | import java.awt.*; |
| 18 | 20 | import java.awt.geom.AffineTransform; |
| ... | ... | @@ -25,6 +27,7 @@ import java.util.*; |
| 25 | 27 | * <p> |
| 26 | 28 | * Created by raodeming on 2019/12/25. |
| 27 | 29 | */ |
| 30 | +@Slf4j | |
| 28 | 31 | public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 29 | 32 | |
| 30 | 33 | 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 { |
| 43 | 46 | super.init(config); |
| 44 | 47 | clickWordFontStr = config.getProperty(Const.CAPTCHA_FONT_TYPE, "SourceHanSansCN-Normal.otf"); |
| 45 | 48 | try { |
| 46 | - int size = Integer.valueOf(config.getProperty(Const.CAPTCHA_FONT_SIZE,HAN_ZI_SIZE+"")); | |
| 49 | + int size = Integer.parseInt(config.getProperty(Const.CAPTCHA_FONT_SIZE,HAN_ZI_SIZE+"")); | |
| 47 | 50 | |
| 48 | 51 | if (clickWordFontStr.toLowerCase().endsWith(".ttf") |
| 49 | 52 | || clickWordFontStr.toLowerCase().endsWith(".ttc") |
| 50 | 53 | || clickWordFontStr.toLowerCase().endsWith(".otf")) { |
| 51 | 54 | this.clickWordFont = Font.createFont(Font.TRUETYPE_FONT, |
| 52 | - getClass().getResourceAsStream("/fonts/" + clickWordFontStr)) | |
| 55 | + Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + clickWordFontStr))) | |
| 53 | 56 | .deriveFont(Font.BOLD, size); |
| 54 | 57 | } else { |
| 55 | - int style = Integer.valueOf(config.getProperty(Const.CAPTCHA_FONT_STYLE,Font.BOLD+"")); | |
| 58 | + int style = Integer.parseInt(config.getProperty(Const.CAPTCHA_FONT_STYLE,Font.BOLD+"")); | |
| 56 | 59 | this.clickWordFont = new Font(clickWordFontStr, style, size); |
| 57 | 60 | } |
| 58 | 61 | } catch (Exception ex) { |
| 59 | - logger.error("load font error:{}", ex); | |
| 62 | + log.error("load font error:{}", ex); | |
| 60 | 63 | } |
| 61 | - this.wordTotalCount = Integer.valueOf(config.getProperty(Const.CAPTCHA_WORD_COUNT,"4")); | |
| 64 | + this.wordTotalCount = Integer.parseInt(config.getProperty(Const.CAPTCHA_WORD_COUNT,"4")); | |
| 62 | 65 | } |
| 63 | 66 | |
| 64 | 67 | @Override |
| 65 | 68 | public void destroy(Properties config) { |
| 66 | - logger.info("start-clear-history-data-", captchaType()); | |
| 69 | + log.info("start-clear-history-data-", captchaType()); | |
| 67 | 70 | } |
| 68 | 71 | |
| 69 | 72 | @Override |
| ... | ... | @@ -74,12 +77,12 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 74 | 77 | } |
| 75 | 78 | BufferedImage bufferedImage = ImageUtils.getPicClick(); |
| 76 | 79 | if (null == bufferedImage) { |
| 77 | - logger.error("滑动底图未初始化成功,请检查路径"); | |
| 80 | + log.error("滑动底图未初始化成功,请检查路径"); | |
| 78 | 81 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); |
| 79 | 82 | } |
| 80 | 83 | CaptchaVO imageData = getImageData(bufferedImage); |
| 81 | 84 | if (imageData == null |
| 82 | - || StringUtils.isBlank(imageData.getOriginalImageBase64())) { | |
| 85 | + || StrUtil.isBlank(imageData.getOriginalImageBase64())) { | |
| 83 | 86 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); |
| 84 | 87 | } |
| 85 | 88 | return ResponseModel.successData(imageData); |
| ... | ... | @@ -124,7 +127,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 124 | 127 | pointJson = decrypt(captchaVO.getPointJson(), point.get(0).getSecretKey()); |
| 125 | 128 | point1 = JsonUtil.parseArray(pointJson, PointVO.class); |
| 126 | 129 | } catch (Exception e) { |
| 127 | - logger.error("验证码坐标解析失败", e); | |
| 130 | + log.error("验证码坐标解析失败", e); | |
| 128 | 131 | afterValidateFail(captchaVO); |
| 129 | 132 | return ResponseModel.errorMsg(e.getMessage()); |
| 130 | 133 | } |
| ... | ... | @@ -143,7 +146,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 143 | 146 | try { |
| 144 | 147 | value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); |
| 145 | 148 | } catch (Exception e) { |
| 146 | - logger.error("AES加密失败", e); | |
| 149 | + log.error("AES加密失败", e); | |
| 147 | 150 | afterValidateFail(captchaVO); |
| 148 | 151 | return ResponseModel.errorMsg(e.getMessage()); |
| 149 | 152 | } |
| ... | ... | @@ -159,7 +162,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 159 | 162 | /*if (captchaVO == null) { |
| 160 | 163 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 161 | 164 | } |
| 162 | - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { | |
| 165 | + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { | |
| 163 | 166 | return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); |
| 164 | 167 | }*/ |
| 165 | 168 | ResponseModel r = super.verification(captchaVO); |
| ... | ... | @@ -174,7 +177,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 174 | 177 | //二次校验取值后,即刻失效 |
| 175 | 178 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); |
| 176 | 179 | } catch (Exception e) { |
| 177 | - logger.error("验证码坐标解析失败", e); | |
| 180 | + log.error("验证码坐标解析失败", e); | |
| 178 | 181 | return ResponseModel.errorMsg(e.getMessage()); |
| 179 | 182 | } |
| 180 | 183 | return ResponseModel.success(); | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/DefaultCaptchaServiceImpl.java
| ... | ... | @@ -6,17 +6,19 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | |
| 9 | +import cn.hutool.core.util.StrUtil; | |
| 9 | 10 | import com.anji.captcha.model.common.RepCodeEnum; |
| 10 | 11 | import com.anji.captcha.model.common.ResponseModel; |
| 11 | 12 | import com.anji.captcha.model.vo.CaptchaVO; |
| 12 | 13 | import com.anji.captcha.service.CaptchaService; |
| 13 | -import com.anji.captcha.util.StringUtils; | |
| 14 | +import lombok.extern.slf4j.Slf4j; | |
| 14 | 15 | |
| 15 | 16 | import java.util.Properties; |
| 16 | 17 | |
| 17 | 18 | /** |
| 18 | 19 | * Created by raodeming on 2019/12/25. |
| 19 | 20 | */ |
| 21 | +@Slf4j | |
| 20 | 22 | public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ |
| 21 | 23 | |
| 22 | 24 | @Override |
| ... | ... | @@ -53,7 +55,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ |
| 53 | 55 | if (captchaVO == null) { |
| 54 | 56 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 55 | 57 | } |
| 56 | - if (StringUtils.isEmpty(captchaVO.getCaptchaType())) { | |
| 58 | + if (StrUtil.isEmpty(captchaVO.getCaptchaType())) { | |
| 57 | 59 | return RepCodeEnum.NULL_ERROR.parseError("类型"); |
| 58 | 60 | } |
| 59 | 61 | return getService(captchaVO.getCaptchaType()).get(captchaVO); |
| ... | ... | @@ -64,10 +66,10 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ |
| 64 | 66 | if (captchaVO == null) { |
| 65 | 67 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 66 | 68 | } |
| 67 | - if (StringUtils.isEmpty(captchaVO.getCaptchaType())) { | |
| 69 | + if (StrUtil.isEmpty(captchaVO.getCaptchaType())) { | |
| 68 | 70 | return RepCodeEnum.NULL_ERROR.parseError("类型"); |
| 69 | 71 | } |
| 70 | - if (StringUtils.isEmpty(captchaVO.getToken())) { | |
| 72 | + if (StrUtil.isEmpty(captchaVO.getToken())) { | |
| 71 | 73 | return RepCodeEnum.NULL_ERROR.parseError("token"); |
| 72 | 74 | } |
| 73 | 75 | return getService(captchaVO.getCaptchaType()).check(captchaVO); |
| ... | ... | @@ -78,7 +80,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ |
| 78 | 80 | if (captchaVO == null) { |
| 79 | 81 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 80 | 82 | } |
| 81 | - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { | |
| 83 | + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { | |
| 82 | 84 | return RepCodeEnum.NULL_ERROR.parseError("二次校验参数"); |
| 83 | 85 | } |
| 84 | 86 | try { |
| ... | ... | @@ -89,7 +91,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ |
| 89 | 91 | //二次校验取值后,即刻失效 |
| 90 | 92 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); |
| 91 | 93 | } catch (Exception e) { |
| 92 | - logger.error("验证码坐标解析失败", e); | |
| 94 | + log.error("验证码坐标解析失败", e); | |
| 93 | 95 | return ResponseModel.errorMsg(e.getMessage()); |
| 94 | 96 | } |
| 95 | 97 | return ResponseModel.success(); | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/FrequencyLimitHandler.java
| 1 | 1 | package com.anji.captcha.service.impl; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 3 | 4 | import com.anji.captcha.model.common.Const; |
| 4 | 5 | import com.anji.captcha.model.common.RepCodeEnum; |
| 5 | 6 | import com.anji.captcha.model.common.ResponseModel; |
| 6 | 7 | import com.anji.captcha.model.vo.CaptchaVO; |
| 7 | 8 | import com.anji.captcha.service.CaptchaCacheService; |
| 8 | -import com.anji.captcha.util.StringUtils; | |
| 9 | 9 | |
| 10 | 10 | import java.util.Objects; |
| 11 | 11 | import java.util.Properties; |
| ... | ... | @@ -66,15 +66,15 @@ public interface FrequencyLimitHandler { |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | private String getClientCId(CaptchaVO input, String type) { |
| 69 | - return String.format(LIMIT_KEY ,type,input.getClientUid()); | |
| 69 | + return String.format(LIMIT_KEY, type, input.getClientUid()); | |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | @Override |
| 73 | 73 | public ResponseModel validateGet(CaptchaVO d) { |
| 74 | - // 无客户端身份标识,不限制 | |
| 75 | - if(StringUtils.isEmpty(d.getClientUid())){ | |
| 76 | - return null; | |
| 77 | - } | |
| 74 | + // 无客户端身份标识,不限制 | |
| 75 | + if (StrUtil.isEmpty(d.getClientUid())) { | |
| 76 | + return null; | |
| 77 | + } | |
| 78 | 78 | String getKey = getClientCId(d, "GET"); |
| 79 | 79 | String lockKey = getClientCId(d, "LOCK"); |
| 80 | 80 | // 失败次数过多,锁定 |
| ... | ... | @@ -88,7 +88,7 @@ public interface FrequencyLimitHandler { |
| 88 | 88 | } |
| 89 | 89 | cacheService.increment(getKey, 1); |
| 90 | 90 | // 1分钟内请求次数过多 |
| 91 | - if (Long.valueOf(getCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_MINUTE_LIMIT, "120"))) { | |
| 91 | + if (Long.parseLong(getCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_MINUTE_LIMIT, "120"))) { | |
| 92 | 92 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_GET_ERROR); |
| 93 | 93 | } |
| 94 | 94 | |
| ... | ... | @@ -100,9 +100,9 @@ public interface FrequencyLimitHandler { |
| 100 | 100 | return null; |
| 101 | 101 | } |
| 102 | 102 | // 1分钟内失败5次 |
| 103 | - if (Long.valueOf(failCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_LOCK_LIMIT, "5"))) { | |
| 103 | + if (Long.parseLong(failCnts) > Long.parseLong(config.getProperty(Const.REQ_GET_LOCK_LIMIT, "5"))) { | |
| 104 | 104 | // get接口锁定5分钟 |
| 105 | - cacheService.set(lockKey, "1", Long.valueOf(config.getProperty(Const.REQ_GET_LOCK_SECONDS, "300"))); | |
| 105 | + cacheService.set(lockKey, "1", Long.parseLong(config.getProperty(Const.REQ_GET_LOCK_SECONDS, "300"))); | |
| 106 | 106 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LOCK_GET_ERROR); |
| 107 | 107 | } |
| 108 | 108 | return null; |
| ... | ... | @@ -110,10 +110,10 @@ public interface FrequencyLimitHandler { |
| 110 | 110 | |
| 111 | 111 | @Override |
| 112 | 112 | public ResponseModel validateCheck(CaptchaVO d) { |
| 113 | - // 无客户端身份标识,不限制 | |
| 114 | - if(StringUtils.isEmpty(d.getClientUid())){ | |
| 115 | - return null; | |
| 116 | - } | |
| 113 | + // 无客户端身份标识,不限制 | |
| 114 | + if (StrUtil.isEmpty(d.getClientUid())) { | |
| 115 | + return null; | |
| 116 | + } | |
| 117 | 117 | /*String getKey = getClientCId(d, "GET"); |
| 118 | 118 | if(Objects.isNull(cacheService.get(getKey))){ |
| 119 | 119 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_INVALID); |
| ... | ... | @@ -125,7 +125,7 @@ public interface FrequencyLimitHandler { |
| 125 | 125 | v = "1"; |
| 126 | 126 | } |
| 127 | 127 | cacheService.increment(key, 1); |
| 128 | - if (Long.valueOf(v) > Long.valueOf(config.getProperty(Const.REQ_CHECK_MINUTE_LIMIT, "600"))) { | |
| 128 | + if (Long.parseLong(v) > Long.parseLong(config.getProperty(Const.REQ_CHECK_MINUTE_LIMIT, "600"))) { | |
| 129 | 129 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_CHECK_ERROR); |
| 130 | 130 | } |
| 131 | 131 | return null; |
| ... | ... | @@ -144,7 +144,7 @@ public interface FrequencyLimitHandler { |
| 144 | 144 | v = "1"; |
| 145 | 145 | } |
| 146 | 146 | cacheService.increment(key, 1); |
| 147 | - if (Long.valueOf(v) > Long.valueOf(config.getProperty(Const.REQ_VALIDATE_MINUTE_LIMIT, "600"))) { | |
| 147 | + if (Long.parseLong(v) > Long.parseLong(config.getProperty(Const.REQ_VALIDATE_MINUTE_LIMIT, "600"))) { | |
| 148 | 148 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_VERIFY_ERROR); |
| 149 | 149 | } |
| 150 | 150 | return null; | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/AESUtil.java
| ... | ... | @@ -7,10 +7,13 @@ |
| 7 | 7 | package com.anji.captcha.util; |
| 8 | 8 | |
| 9 | 9 | |
| 10 | +import cn.hutool.core.util.StrUtil; | |
| 11 | + | |
| 10 | 12 | import javax.crypto.Cipher; |
| 11 | 13 | import javax.crypto.KeyGenerator; |
| 12 | 14 | import javax.crypto.spec.SecretKeySpec; |
| 13 | 15 | import java.math.BigInteger; |
| 16 | +import java.nio.charset.StandardCharsets; | |
| 14 | 17 | import java.util.Base64; |
| 15 | 18 | |
| 16 | 19 | |
| ... | ... | @@ -20,6 +23,7 @@ public class AESUtil { |
| 20 | 23 | |
| 21 | 24 | /** |
| 22 | 25 | * 获取随机key |
| 26 | + * | |
| 23 | 27 | * @return |
| 24 | 28 | */ |
| 25 | 29 | public static String getKey() { |
| ... | ... | @@ -29,39 +33,43 @@ public class AESUtil { |
| 29 | 33 | |
| 30 | 34 | /** |
| 31 | 35 | * 将byte[]转为各种进制的字符串 |
| 36 | + * | |
| 32 | 37 | * @param bytes byte[] |
| 33 | 38 | * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 |
| 34 | 39 | * @return 转换后的字符串 |
| 35 | 40 | */ |
| 36 | - public static String binary(byte[] bytes, int radix){ | |
| 41 | + public static String binary(byte[] bytes, int radix) { | |
| 37 | 42 | return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 |
| 38 | 43 | } |
| 39 | 44 | |
| 40 | 45 | /** |
| 41 | 46 | * base 64 encode |
| 47 | + * | |
| 42 | 48 | * @param bytes 待编码的byte[] |
| 43 | 49 | * @return 编码后的base 64 code |
| 44 | 50 | */ |
| 45 | - public static String base64Encode(byte[] bytes){ | |
| 51 | + public static String base64Encode(byte[] bytes) { | |
| 46 | 52 | //return Base64.encodeBase64String(bytes); |
| 47 | 53 | return Base64.getEncoder().encodeToString(bytes); |
| 48 | 54 | } |
| 49 | 55 | |
| 50 | 56 | /** |
| 51 | 57 | * base 64 decode |
| 58 | + * | |
| 52 | 59 | * @param base64Code 待解码的base 64 code |
| 53 | 60 | * @return 解码后的byte[] |
| 54 | 61 | * @throws Exception |
| 55 | 62 | */ |
| 56 | - public static byte[] base64Decode(String base64Code) throws Exception{ | |
| 63 | + public static byte[] base64Decode(String base64Code) throws Exception { | |
| 57 | 64 | Base64.Decoder decoder = Base64.getDecoder(); |
| 58 | - return StringUtils.isEmpty(base64Code) ? null : decoder.decode(base64Code); | |
| 65 | + return StrUtil.isEmpty(base64Code) ? null : decoder.decode(base64Code); | |
| 59 | 66 | } |
| 60 | 67 | |
| 61 | 68 | |
| 62 | 69 | /** |
| 63 | 70 | * AES加密 |
| 64 | - * @param content 待加密的内容 | |
| 71 | + * | |
| 72 | + * @param content 待加密的内容 | |
| 65 | 73 | * @param encryptKey 加密密钥 |
| 66 | 74 | * @return 加密后的byte[] |
| 67 | 75 | * @throws Exception |
| ... | ... | @@ -72,19 +80,20 @@ public class AESUtil { |
| 72 | 80 | Cipher cipher = Cipher.getInstance(ALGORITHMSTR); |
| 73 | 81 | cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES")); |
| 74 | 82 | |
| 75 | - return cipher.doFinal(content.getBytes("utf-8")); | |
| 83 | + return cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)); | |
| 76 | 84 | } |
| 77 | 85 | |
| 78 | 86 | |
| 79 | 87 | /** |
| 80 | 88 | * AES加密为base 64 code |
| 81 | - * @param content 待加密的内容 | |
| 89 | + * | |
| 90 | + * @param content 待加密的内容 | |
| 82 | 91 | * @param encryptKey 加密密钥 |
| 83 | 92 | * @return 加密后的base 64 code |
| 84 | 93 | * @throws Exception |
| 85 | 94 | */ |
| 86 | 95 | public static String aesEncrypt(String content, String encryptKey) throws Exception { |
| 87 | - if (StringUtils.isBlank(encryptKey)) { | |
| 96 | + if (StrUtil.isBlank(encryptKey)) { | |
| 88 | 97 | return content; |
| 89 | 98 | } |
| 90 | 99 | return base64Encode(aesEncryptToBytes(content, encryptKey)); |
| ... | ... | @@ -92,8 +101,9 @@ public class AESUtil { |
| 92 | 101 | |
| 93 | 102 | /** |
| 94 | 103 | * AES解密 |
| 104 | + * | |
| 95 | 105 | * @param encryptBytes 待解密的byte[] |
| 96 | - * @param decryptKey 解密密钥 | |
| 106 | + * @param decryptKey 解密密钥 | |
| 97 | 107 | * @return 解密后的String |
| 98 | 108 | * @throws Exception |
| 99 | 109 | */ |
| ... | ... | @@ -110,16 +120,17 @@ public class AESUtil { |
| 110 | 120 | |
| 111 | 121 | /** |
| 112 | 122 | * 将base 64 code AES解密 |
| 123 | + * | |
| 113 | 124 | * @param encryptStr 待解密的base 64 code |
| 114 | 125 | * @param decryptKey 解密密钥 |
| 115 | 126 | * @return 解密后的string |
| 116 | 127 | * @throws Exception |
| 117 | 128 | */ |
| 118 | 129 | public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { |
| 119 | - if (StringUtils.isBlank(decryptKey)) { | |
| 130 | + if (StrUtil.isBlank(decryptKey)) { | |
| 120 | 131 | return encryptStr; |
| 121 | 132 | } |
| 122 | - return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); | |
| 133 | + return StrUtil.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); | |
| 123 | 134 | } |
| 124 | 135 | |
| 125 | 136 | /** | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/Base64Utils.java deleted
| 1 | -// | |
| 2 | -// Source code recreated from a .class file by IntelliJ IDEA | |
| 3 | -// (powered by Fernflower decompiler) | |
| 4 | -// | |
| 5 | - | |
| 6 | -package com.anji.captcha.util; | |
| 7 | - | |
| 8 | -import java.nio.charset.Charset; | |
| 9 | -import java.nio.charset.StandardCharsets; | |
| 10 | -import java.util.Base64; | |
| 11 | - | |
| 12 | -public abstract class Base64Utils { | |
| 13 | - private static final Charset DEFAULT_CHARSET; | |
| 14 | - | |
| 15 | - public Base64Utils() { | |
| 16 | - } | |
| 17 | - | |
| 18 | - public static byte[] encode(byte[] src) { | |
| 19 | - return src.length == 0 ? src : Base64.getEncoder().encode(src); | |
| 20 | - } | |
| 21 | - | |
| 22 | - public static byte[] decode(byte[] src) { | |
| 23 | - return src.length == 0 ? src : Base64.getDecoder().decode(src); | |
| 24 | - } | |
| 25 | - | |
| 26 | - public static byte[] encodeUrlSafe(byte[] src) { | |
| 27 | - return src.length == 0 ? src : Base64.getUrlEncoder().encode(src); | |
| 28 | - } | |
| 29 | - | |
| 30 | - public static byte[] decodeUrlSafe(byte[] src) { | |
| 31 | - return src.length == 0 ? src : Base64.getUrlDecoder().decode(src); | |
| 32 | - } | |
| 33 | - | |
| 34 | - public static String encodeToString(byte[] src) { | |
| 35 | - return src.length == 0 ? "" : new String(encode(src), DEFAULT_CHARSET); | |
| 36 | - } | |
| 37 | - | |
| 38 | - public static byte[] decodeFromString(String src) { | |
| 39 | - return src.isEmpty() ? new byte[0] : decode(src.getBytes(DEFAULT_CHARSET)); | |
| 40 | - } | |
| 41 | - | |
| 42 | - public static String encodeToUrlSafeString(byte[] src) { | |
| 43 | - return new String(encodeUrlSafe(src), DEFAULT_CHARSET); | |
| 44 | - } | |
| 45 | - | |
| 46 | - public static byte[] decodeFromUrlSafeString(String src) { | |
| 47 | - return decodeUrlSafe(src.getBytes(DEFAULT_CHARSET)); | |
| 48 | - } | |
| 49 | - | |
| 50 | - static { | |
| 51 | - DEFAULT_CHARSET = StandardCharsets.UTF_8; | |
| 52 | - } | |
| 53 | -} |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/CacheUtil.java
| ... | ... | @@ -24,8 +24,9 @@ public final class CacheUtil { |
| 24 | 24 | |
| 25 | 25 | /** |
| 26 | 26 | * 初始化 |
| 27 | + * | |
| 27 | 28 | * @param cacheMaxNumber 缓存最大个数 |
| 28 | - * @param second 定时任务 秒执行清除过期缓存 | |
| 29 | + * @param second 定时任务 秒执行清除过期缓存 | |
| 29 | 30 | */ |
| 30 | 31 | public static void init(int cacheMaxNumber, long second) { |
| 31 | 32 | CACHE_MAX_NUMBER = cacheMaxNumber; |
| ... | ... | @@ -37,27 +38,25 @@ public final class CacheUtil { |
| 37 | 38 | refresh(); |
| 38 | 39 | } |
| 39 | 40 | }, 0, second * 1000);*/ |
| 40 | - scheduledExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { | |
| 41 | - @Override | |
| 42 | - public Thread newThread(Runnable r) { | |
| 43 | - return new Thread(r,"thd-captcha-cache-clean"); | |
| 44 | - } | |
| 45 | - },new ThreadPoolExecutor.CallerRunsPolicy()); | |
| 41 | + ScheduledExecutorService scheduledExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { | |
| 42 | + @Override | |
| 43 | + public Thread newThread(Runnable r) { | |
| 44 | + return new Thread(r, "thd-captcha-cache-clean"); | |
| 45 | + } | |
| 46 | + }, new ThreadPoolExecutor.CallerRunsPolicy()); | |
| 46 | 47 | scheduledExecutor.scheduleAtFixedRate(new Runnable() { |
| 47 | - @Override | |
| 48 | - public void run() { | |
| 49 | - refresh(); | |
| 50 | - } | |
| 51 | - },10,second,TimeUnit.SECONDS); | |
| 48 | + @Override | |
| 49 | + public void run() { | |
| 50 | + refresh(); | |
| 51 | + } | |
| 52 | + }, 10, second, TimeUnit.SECONDS); | |
| 52 | 53 | } |
| 53 | 54 | } |
| 54 | 55 | |
| 55 | - private static ScheduledExecutorService scheduledExecutor; | |
| 56 | - | |
| 57 | 56 | /** |
| 58 | 57 | * 缓存刷新,清除过期数据 |
| 59 | 58 | */ |
| 60 | - public static void refresh(){ | |
| 59 | + public static void refresh() { | |
| 61 | 60 | logger.debug("local缓存刷新,清除过期数据"); |
| 62 | 61 | for (String key : CACHE_MAP.keySet()) { |
| 63 | 62 | exists(key); |
| ... | ... | @@ -65,24 +64,24 @@ public final class CacheUtil { |
| 65 | 64 | } |
| 66 | 65 | |
| 67 | 66 | |
| 68 | - public static void set(String key, String value, long expiresInSeconds){ | |
| 67 | + public static void set(String key, String value, long expiresInSeconds) { | |
| 69 | 68 | //设置阈值,达到即clear缓存 |
| 70 | 69 | if (CACHE_MAP.size() > CACHE_MAX_NUMBER * 2) { |
| 71 | 70 | logger.info("CACHE_MAP达到阈值,clear map"); |
| 72 | 71 | clear(); |
| 73 | 72 | } |
| 74 | 73 | CACHE_MAP.put(key, value); |
| 75 | - if(expiresInSeconds >0) { | |
| 76 | - CACHE_MAP.put(key + "_HoldTime", System.currentTimeMillis() + expiresInSeconds * 1000);//缓存失效时间 | |
| 77 | - } | |
| 74 | + if (expiresInSeconds > 0) { | |
| 75 | + CACHE_MAP.put(key + "_HoldTime", System.currentTimeMillis() + expiresInSeconds * 1000);//缓存失效时间 | |
| 76 | + } | |
| 78 | 77 | } |
| 79 | 78 | |
| 80 | - public static void delete(String key){ | |
| 79 | + public static void delete(String key) { | |
| 81 | 80 | CACHE_MAP.remove(key); |
| 82 | 81 | CACHE_MAP.remove(key + "_HoldTime"); |
| 83 | 82 | } |
| 84 | 83 | |
| 85 | - public static boolean exists(String key){ | |
| 84 | + public static boolean exists(String key) { | |
| 86 | 85 | Long cacheHoldTime = (Long) CACHE_MAP.get(key + "_HoldTime"); |
| 87 | 86 | if (cacheHoldTime == null || cacheHoldTime == 0L) { |
| 88 | 87 | return false; |
| ... | ... | @@ -95,9 +94,9 @@ public final class CacheUtil { |
| 95 | 94 | } |
| 96 | 95 | |
| 97 | 96 | |
| 98 | - public static String get(String key){ | |
| 97 | + public static String get(String key) { | |
| 99 | 98 | if (exists(key)) { |
| 100 | - return (String)CACHE_MAP.get(key); | |
| 99 | + return (String) CACHE_MAP.get(key); | |
| 101 | 100 | } |
| 102 | 101 | return null; |
| 103 | 102 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/FileCopyUtils.java
| ... | ... | @@ -18,7 +18,7 @@ public abstract class FileCopyUtils { |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | public static void copy(byte[] in, File out) throws IOException { |
| 21 | - copy((InputStream)(new ByteArrayInputStream(in)), (OutputStream)Files.newOutputStream(out.toPath())); | |
| 21 | + copy((InputStream) (new ByteArrayInputStream(in)), (OutputStream) Files.newOutputStream(out.toPath())); | |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | public static byte[] copyToByteArray(File in) throws IOException { |
| ... | ... | @@ -63,7 +63,7 @@ public abstract class FileCopyUtils { |
| 63 | 63 | return new byte[0]; |
| 64 | 64 | } else { |
| 65 | 65 | ByteArrayOutputStream out = new ByteArrayOutputStream(4096); |
| 66 | - copy((InputStream)in, (OutputStream)out); | |
| 66 | + copy((InputStream) in, (OutputStream) out); | |
| 67 | 67 | return out.toByteArray(); |
| 68 | 68 | } |
| 69 | 69 | } |
| ... | ... | @@ -74,13 +74,12 @@ public abstract class FileCopyUtils { |
| 74 | 74 | char[] buffer = new char[4096]; |
| 75 | 75 | |
| 76 | 76 | int bytesRead; |
| 77 | - for(boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { | |
| 77 | + for (boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { | |
| 78 | 78 | out.write(buffer, 0, bytesRead); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | out.flush(); |
| 82 | - int var5 = byteCount; | |
| 83 | - return var5; | |
| 82 | + return byteCount; | |
| 84 | 83 | } finally { |
| 85 | 84 | try { |
| 86 | 85 | in.close(); |
| ... | ... | @@ -113,7 +112,7 @@ public abstract class FileCopyUtils { |
| 113 | 112 | return ""; |
| 114 | 113 | } else { |
| 115 | 114 | StringWriter out = new StringWriter(); |
| 116 | - copy((Reader)in, (Writer)out); | |
| 115 | + copy((Reader) in, (Writer) out); | |
| 117 | 116 | return out.toString(); |
| 118 | 117 | } |
| 119 | 118 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/ImageUtils.java
| ... | ... | @@ -6,9 +6,10 @@ |
| 6 | 6 | */ |
| 7 | 7 | package com.anji.captcha.util; |
| 8 | 8 | |
| 9 | +import cn.hutool.core.util.StrUtil; | |
| 9 | 10 | import com.anji.captcha.model.common.CaptchaBaseMapEnum; |
| 10 | -import org.slf4j.Logger; | |
| 11 | -import org.slf4j.LoggerFactory; | |
| 11 | +import lombok.extern.slf4j.Slf4j; | |
| 12 | +import org.springframework.util.Base64Utils; | |
| 12 | 13 | |
| 13 | 14 | import javax.imageio.ImageIO; |
| 14 | 15 | import java.awt.image.BufferedImage; |
| ... | ... | @@ -19,9 +20,8 @@ import java.util.HashMap; |
| 19 | 20 | import java.util.Map; |
| 20 | 21 | import java.util.concurrent.ConcurrentHashMap; |
| 21 | 22 | |
| 22 | - | |
| 23 | +@Slf4j | |
| 23 | 24 | public class ImageUtils { |
| 24 | - private static Logger logger = LoggerFactory.getLogger(ImageUtils.class); | |
| 25 | 25 | private static Map<String, String> originalCacheMap = new ConcurrentHashMap(); //滑块底图 |
| 26 | 26 | private static Map<String, String> slidingBlockCacheMap = new ConcurrentHashMap(); //滑块 |
| 27 | 27 | private static Map<String, String> picClickCacheMap = new ConcurrentHashMap(); //点选文字 |
| ... | ... | @@ -29,7 +29,7 @@ public class ImageUtils { |
| 29 | 29 | |
| 30 | 30 | public static void cacheImage(String captchaOriginalPathJigsaw, String captchaOriginalPathClick) { |
| 31 | 31 | //滑动拼图 |
| 32 | - if (StringUtils.isBlank(captchaOriginalPathJigsaw)) { | |
| 32 | + if (StrUtil.isBlank(captchaOriginalPathJigsaw)) { | |
| 33 | 33 | originalCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/original")); |
| 34 | 34 | slidingBlockCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/slidingBlock")); |
| 35 | 35 | } else { |
| ... | ... | @@ -37,7 +37,7 @@ public class ImageUtils { |
| 37 | 37 | slidingBlockCacheMap.putAll(getImagesFile(captchaOriginalPathJigsaw + File.separator + "slidingBlock")); |
| 38 | 38 | } |
| 39 | 39 | //点选文字 |
| 40 | - if (StringUtils.isBlank(captchaOriginalPathClick)) { | |
| 40 | + if (StrUtil.isBlank(captchaOriginalPathClick)) { | |
| 41 | 41 | picClickCacheMap.putAll(getResourcesImagesFile("defaultImages/pic-click")); |
| 42 | 42 | } else { |
| 43 | 43 | picClickCacheMap.putAll(getImagesFile(captchaOriginalPathClick)); |
| ... | ... | @@ -45,7 +45,7 @@ public class ImageUtils { |
| 45 | 45 | fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); |
| 46 | 46 | fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); |
| 47 | 47 | fileNameMap.put(CaptchaBaseMapEnum.PIC_CLICK.getCodeValue(), picClickCacheMap.keySet().toArray(new String[0])); |
| 48 | - logger.info("初始化底图:{}", JsonUtil.toJSONString(fileNameMap)); | |
| 48 | + log.info("初始化底图:{}", JsonUtil.toJSONString(fileNameMap)); | |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | public static void cacheBootImage(Map<String, String> originalMap, Map<String, String> slidingBlockMap, Map<String, String> picClickMap) { |
| ... | ... | @@ -55,7 +55,7 @@ public class ImageUtils { |
| 55 | 55 | fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); |
| 56 | 56 | fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); |
| 57 | 57 | fileNameMap.put(CaptchaBaseMapEnum.PIC_CLICK.getCodeValue(), picClickCacheMap.keySet().toArray(new String[0])); |
| 58 | - logger.info("自定义resource底图:{}", JsonUtil.toJSONString(fileNameMap)); | |
| 58 | + log.info("自定义resource底图:{}", JsonUtil.toJSONString(fileNameMap)); | |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | |
| ... | ... | @@ -75,8 +75,7 @@ public class ImageUtils { |
| 75 | 75 | return null; |
| 76 | 76 | } |
| 77 | 77 | Integer randomInt = RandomUtils.getRandomInt(0, strings.length); |
| 78 | - String s = slidingBlockCacheMap.get(strings[randomInt]); | |
| 79 | - return s; | |
| 78 | + return slidingBlockCacheMap.get(strings[randomInt]); | |
| 80 | 79 | } |
| 81 | 80 | |
| 82 | 81 | public static BufferedImage getPicClick() { |
| ... | ... | @@ -160,8 +159,6 @@ public class ImageUtils { |
| 160 | 159 | byte[] bytes = FileCopyUtils.copyToByteArray(fileInputStream); |
| 161 | 160 | String string = Base64Utils.encodeToString(bytes); |
| 162 | 161 | imgMap.put(item.getName(), string); |
| 163 | - } catch (FileNotFoundException e) { | |
| 164 | - e.printStackTrace(); | |
| 165 | 162 | } catch (IOException e) { |
| 166 | 163 | e.printStackTrace(); |
| 167 | 164 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/JsonUtil.java
| 1 | 1 | package com.anji.captcha.util; |
| 2 | 2 | |
| 3 | 3 | import com.anji.captcha.model.vo.PointVO; |
| 4 | -import org.slf4j.Logger; | |
| 5 | -import org.slf4j.LoggerFactory; | |
| 4 | +import lombok.extern.slf4j.Slf4j; | |
| 6 | 5 | |
| 7 | 6 | import java.util.ArrayList; |
| 8 | 7 | import java.util.List; |
| ... | ... | @@ -12,63 +11,63 @@ import java.util.Map; |
| 12 | 11 | * 替换掉fastjson,自定义实现相关方法 |
| 13 | 12 | * note: 该实现不具有通用性,仅用于本项目。 |
| 14 | 13 | * |
| 15 | - *@author WongBin | |
| 16 | - *@date 2021/1/8 | |
| 14 | + * @author WongBin | |
| 15 | + * @date 2021/1/8 | |
| 17 | 16 | */ |
| 17 | +@Slf4j | |
| 18 | 18 | public class JsonUtil { |
| 19 | - private static Logger logger = LoggerFactory.getLogger(JsonUtil.class); | |
| 20 | - public static List<PointVO> parseArray(String text, Class<PointVO> clazz) { | |
| 21 | - if (text == null) { | |
| 22 | - return null; | |
| 23 | - } else { | |
| 24 | - String[] arr = text.replaceFirst("\\[","") | |
| 25 | - .replaceFirst("\\]","").split("\\}"); | |
| 26 | - List<PointVO> ret = new ArrayList<>(arr.length); | |
| 27 | - for (String s : arr) { | |
| 28 | - ret.add(parseObject(s,PointVO.class)); | |
| 29 | - } | |
| 30 | - return ret; | |
| 31 | - } | |
| 32 | - } | |
| 19 | + public static List<PointVO> parseArray(String text, Class<PointVO> clazz) { | |
| 20 | + if (text == null) { | |
| 21 | + return null; | |
| 22 | + } else { | |
| 23 | + String[] arr = text.replaceFirst("\\[", "") | |
| 24 | + .replaceFirst("\\]", "").split("\\}"); | |
| 25 | + List<PointVO> ret = new ArrayList<>(arr.length); | |
| 26 | + for (String s : arr) { | |
| 27 | + ret.add(parseObject(s, PointVO.class)); | |
| 28 | + } | |
| 29 | + return ret; | |
| 30 | + } | |
| 31 | + } | |
| 33 | 32 | |
| 34 | - public static PointVO parseObject(String text, Class<PointVO> clazz) { | |
| 35 | - if(text == null) { | |
| 36 | - return null; | |
| 37 | - } | |
| 33 | + public static PointVO parseObject(String text, Class<PointVO> clazz) { | |
| 34 | + if (text == null) { | |
| 35 | + return null; | |
| 36 | + } | |
| 38 | 37 | /*if(!clazz.isAssignableFrom(PointVO.class)) { |
| 39 | 38 | throw new UnsupportedOperationException("不支持的输入类型:" |
| 40 | 39 | + clazz.getSimpleName()); |
| 41 | 40 | }*/ |
| 42 | - try { | |
| 43 | - PointVO ret = clazz.newInstance(); | |
| 44 | - return ret.parse(text); | |
| 45 | - }catch (Exception ex){ | |
| 46 | - logger.error("json解析异常", ex); | |
| 41 | + try { | |
| 42 | + PointVO ret = clazz.newInstance(); | |
| 43 | + return ret.parse(text); | |
| 44 | + } catch (Exception ex) { | |
| 45 | + log.error("json解析异常", ex); | |
| 47 | 46 | |
| 48 | - } | |
| 49 | - return null; | |
| 50 | - } | |
| 47 | + } | |
| 48 | + return null; | |
| 49 | + } | |
| 51 | 50 | |
| 52 | - public static String toJSONString(Object object) { | |
| 53 | - if(object == null) { | |
| 54 | - return "{}"; | |
| 55 | - } | |
| 56 | - if(object instanceof PointVO){ | |
| 57 | - PointVO t = (PointVO)object; | |
| 58 | - return t.toJsonString(); | |
| 59 | - } | |
| 60 | - if(object instanceof List){ | |
| 61 | - List<PointVO> list = (List<PointVO>)object; | |
| 62 | - StringBuilder buf = new StringBuilder("["); | |
| 63 | - list.stream().forEach(t->{ | |
| 64 | - buf.append(t.toJsonString()).append(","); | |
| 65 | - }); | |
| 66 | - return buf.deleteCharAt(buf.lastIndexOf(",")).append("]").toString(); | |
| 67 | - } | |
| 68 | - if(object instanceof Map){ | |
| 69 | - return ((Map)object).entrySet().toString(); | |
| 70 | - } | |
| 71 | - throw new UnsupportedOperationException("不支持的输入类型:" | |
| 72 | - +object.getClass().getSimpleName()); | |
| 73 | - } | |
| 51 | + public static String toJSONString(Object object) { | |
| 52 | + if (object == null) { | |
| 53 | + return "{}"; | |
| 54 | + } | |
| 55 | + if (object instanceof PointVO) { | |
| 56 | + PointVO t = (PointVO) object; | |
| 57 | + return t.toJsonString(); | |
| 58 | + } | |
| 59 | + if (object instanceof List) { | |
| 60 | + List<PointVO> list = (List<PointVO>) object; | |
| 61 | + StringBuilder buf = new StringBuilder("["); | |
| 62 | + list.forEach(t -> { | |
| 63 | + buf.append(t.toJsonString()).append(","); | |
| 64 | + }); | |
| 65 | + return buf.deleteCharAt(buf.lastIndexOf(",")).append("]").toString(); | |
| 66 | + } | |
| 67 | + if (object instanceof Map) { | |
| 68 | + return ((Map) object).entrySet().toString(); | |
| 69 | + } | |
| 70 | + throw new UnsupportedOperationException("不支持的输入类型:" | |
| 71 | + + object.getClass().getSimpleName()); | |
| 72 | + } | |
| 74 | 73 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/MD5Util.java
| 1 | 1 | package com.anji.captcha.util; |
| 2 | 2 | |
| 3 | +import java.nio.charset.StandardCharsets; | |
| 3 | 4 | import java.security.MessageDigest; |
| 4 | 5 | |
| 5 | 6 | /** |
| ... | ... | @@ -8,17 +9,18 @@ import java.security.MessageDigest; |
| 8 | 9 | public abstract class MD5Util { |
| 9 | 10 | /** |
| 10 | 11 | * 获取指定字符串的md5值 |
| 12 | + * | |
| 11 | 13 | * @param dataStr 明文 |
| 12 | 14 | * @return String |
| 13 | 15 | */ |
| 14 | 16 | public static String md5(String dataStr) { |
| 15 | 17 | try { |
| 16 | 18 | MessageDigest m = MessageDigest.getInstance("MD5"); |
| 17 | - m.update(dataStr.getBytes("UTF8")); | |
| 19 | + m.update(dataStr.getBytes(StandardCharsets.UTF_8)); | |
| 18 | 20 | byte[] s = m.digest(); |
| 19 | 21 | StringBuilder result = new StringBuilder(); |
| 20 | - for (int i = 0; i < s.length; i++) { | |
| 21 | - result.append(Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00).substring(6)); | |
| 22 | + for (byte b : s) { | |
| 23 | + result.append(Integer.toHexString((0x000000FF & b) | 0xFFFFFF00).substring(6)); | |
| 22 | 24 | } |
| 23 | 25 | return result.toString(); |
| 24 | 26 | } catch (Exception e) { |
| ... | ... | @@ -29,10 +31,11 @@ public abstract class MD5Util { |
| 29 | 31 | |
| 30 | 32 | /** |
| 31 | 33 | * 获取指定字符串的md5值, md5(str+salt) |
| 34 | + * | |
| 32 | 35 | * @param dataStr 明文 |
| 33 | 36 | * @return String |
| 34 | 37 | */ |
| 35 | - public static String md5WithSalt(String dataStr,String salt) { | |
| 38 | + public static String md5WithSalt(String dataStr, String salt) { | |
| 36 | 39 | return md5(dataStr + salt); |
| 37 | 40 | } |
| 38 | 41 | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/RandomUtils.java
| ... | ... | @@ -31,11 +31,10 @@ public class RandomUtils { |
| 31 | 31 | * @return |
| 32 | 32 | */ |
| 33 | 33 | public static String getRandomHan(String hanZi) { |
| 34 | - String ch = hanZi.charAt(new Random().nextInt(hanZi.length())) + ""; | |
| 35 | - return ch; | |
| 34 | + return hanZi.charAt(new Random().nextInt(hanZi.length())) + ""; | |
| 36 | 35 | } |
| 37 | 36 | |
| 38 | - public static int getRandomInt(int bound){ | |
| 37 | + public static int getRandomInt(int bound) { | |
| 39 | 38 | return ThreadLocalRandom.current().nextInt(bound); |
| 40 | 39 | } |
| 41 | 40 | |
| ... | ... | @@ -68,25 +67,27 @@ public class RandomUtils { |
| 68 | 67 | |
| 69 | 68 | /** |
| 70 | 69 | * 随机范围内数字 |
| 70 | + * | |
| 71 | 71 | * @param startNum |
| 72 | 72 | * @param endNum |
| 73 | 73 | * @return |
| 74 | 74 | */ |
| 75 | 75 | public static Integer getRandomInt(int startNum, int endNum) { |
| 76 | - return ThreadLocalRandom.current().nextInt(endNum-startNum) + startNum; | |
| 76 | + return ThreadLocalRandom.current().nextInt(endNum - startNum) + startNum; | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /** |
| 80 | 80 | * 获取随机字符串 |
| 81 | + * | |
| 81 | 82 | * @param length |
| 82 | 83 | * @return |
| 83 | 84 | */ |
| 84 | - public static String getRandomString(int length){ | |
| 85 | - String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
| 86 | - Random random=new Random(); | |
| 87 | - StringBuffer sb=new StringBuffer(); | |
| 88 | - for(int i=0;i<length;i++){ | |
| 89 | - int number=random.nextInt(62); | |
| 85 | + public static String getRandomString(int length) { | |
| 86 | + String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
| 87 | + Random random = new Random(); | |
| 88 | + StringBuffer sb = new StringBuffer(); | |
| 89 | + for (int i = 0; i < length; i++) { | |
| 90 | + int number = random.nextInt(62); | |
| 90 | 91 | sb.append(str.charAt(number)); |
| 91 | 92 | } |
| 92 | 93 | return sb.toString(); | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/StreamUtils.java
| ... | ... | @@ -19,7 +19,7 @@ public abstract class StreamUtils { |
| 19 | 19 | return new byte[0]; |
| 20 | 20 | } else { |
| 21 | 21 | ByteArrayOutputStream out = new ByteArrayOutputStream(4096); |
| 22 | - copy((InputStream)in, out); | |
| 22 | + copy((InputStream) in, out); | |
| 23 | 23 | return out.toByteArray(); |
| 24 | 24 | } |
| 25 | 25 | } |
| ... | ... | @@ -31,10 +31,9 @@ public abstract class StreamUtils { |
| 31 | 31 | StringBuilder out = new StringBuilder(); |
| 32 | 32 | InputStreamReader reader = new InputStreamReader(in, charset); |
| 33 | 33 | char[] buffer = new char[4096]; |
| 34 | - boolean var5 = true; | |
| 35 | 34 | |
| 36 | 35 | int bytesRead; |
| 37 | - while((bytesRead = reader.read(buffer)) != -1) { | |
| 36 | + while ((bytesRead = reader.read(buffer)) != -1) { | |
| 38 | 37 | out.append(buffer, 0, bytesRead); |
| 39 | 38 | } |
| 40 | 39 | |
| ... | ... | @@ -57,7 +56,7 @@ public abstract class StreamUtils { |
| 57 | 56 | byte[] buffer = new byte[4096]; |
| 58 | 57 | |
| 59 | 58 | int bytesRead; |
| 60 | - for(boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { | |
| 59 | + for (boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { | |
| 61 | 60 | out.write(buffer, 0, bytesRead); |
| 62 | 61 | } |
| 63 | 62 | |
| ... | ... | @@ -73,17 +72,17 @@ public abstract class StreamUtils { |
| 73 | 72 | long bytesToCopy = end - start + 1L; |
| 74 | 73 | byte[] buffer = new byte[4096]; |
| 75 | 74 | |
| 76 | - while(bytesToCopy > 0L) { | |
| 75 | + while (bytesToCopy > 0L) { | |
| 77 | 76 | int bytesRead = in.read(buffer); |
| 78 | 77 | if (bytesRead == -1) { |
| 79 | 78 | break; |
| 80 | 79 | } |
| 81 | 80 | |
| 82 | - if ((long)bytesRead <= bytesToCopy) { | |
| 81 | + if ((long) bytesRead <= bytesToCopy) { | |
| 83 | 82 | out.write(buffer, 0, bytesRead); |
| 84 | - bytesToCopy -= (long)bytesRead; | |
| 83 | + bytesToCopy -= (long) bytesRead; | |
| 85 | 84 | } else { |
| 86 | - out.write(buffer, 0, (int)bytesToCopy); | |
| 85 | + out.write(buffer, 0, (int) bytesToCopy); | |
| 87 | 86 | bytesToCopy = 0L; |
| 88 | 87 | } |
| 89 | 88 | } |
| ... | ... | @@ -96,7 +95,7 @@ public abstract class StreamUtils { |
| 96 | 95 | byte[] buffer = new byte[4096]; |
| 97 | 96 | int byteCount; |
| 98 | 97 | int bytesRead; |
| 99 | - for(byteCount = 0; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { | |
| 98 | + for (byteCount = 0; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { | |
| 100 | 99 | } |
| 101 | 100 | |
| 102 | 101 | return byteCount; | ... | ... |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/StringUtils.java deleted
| 1 | -/* | |
| 2 | - *Copyright © 2018 anji-plus | |
| 3 | - *安吉加加信息技术有限公司 | |
| 4 | - *http://www.anji-plus.com | |
| 5 | - *All rights reserved. | |
| 6 | - */ | |
| 7 | -package com.anji.captcha.util; | |
| 8 | - | |
| 9 | -public class StringUtils { | |
| 10 | - | |
| 11 | - /** | |
| 12 | - * The empty String <code>""</code>. | |
| 13 | - * @since 2.0 | |
| 14 | - */ | |
| 15 | - public static final String EMPTY = ""; | |
| 16 | - | |
| 17 | - /** | |
| 18 | - * Represents a failed index search. | |
| 19 | - * @since 2.1 | |
| 20 | - */ | |
| 21 | - public static final int INDEX_NOT_FOUND = -1; | |
| 22 | - | |
| 23 | - /** | |
| 24 | - * <p>The maximum size to which the padding constant(s) can expand.</p> | |
| 25 | - */ | |
| 26 | - private static final int PAD_LIMIT = 8192; | |
| 27 | - | |
| 28 | - /** | |
| 29 | - * <p><code>StringUtils</code> instances should NOT be constructed in | |
| 30 | - * standard programming. Instead, the class should be used as | |
| 31 | - * <code>StringUtils.trim(" foo ");</code>.</p> | |
| 32 | - * | |
| 33 | - * <p>This constructor is public to permit tools that require a JavaBean | |
| 34 | - * instance to operate.</p> | |
| 35 | - */ | |
| 36 | - public StringUtils() { | |
| 37 | - super(); | |
| 38 | - } | |
| 39 | - | |
| 40 | - // Empty checks | |
| 41 | - //----------------------------------------------------------------------- | |
| 42 | - /** | |
| 43 | - * <p>Checks if a String is empty ("") or null.</p> | |
| 44 | - * | |
| 45 | - * <pre> | |
| 46 | - * StringUtils.isEmpty(null) = true | |
| 47 | - * StringUtils.isEmpty("") = true | |
| 48 | - * StringUtils.isEmpty(" ") = false | |
| 49 | - * StringUtils.isEmpty("bob") = false | |
| 50 | - * StringUtils.isEmpty(" bob ") = false | |
| 51 | - * </pre> | |
| 52 | - * | |
| 53 | - * <p>NOTE: This method changed in Lang version 2.0. | |
| 54 | - * It no longer trims the String. | |
| 55 | - * That functionality is available in isBlank().</p> | |
| 56 | - * | |
| 57 | - * @param str the String to check, may be null | |
| 58 | - * @return <code>true</code> if the String is empty or null | |
| 59 | - */ | |
| 60 | - public static boolean isEmpty(String str) { | |
| 61 | - return str == null || str.length() == 0; | |
| 62 | - } | |
| 63 | - | |
| 64 | - /** | |
| 65 | - * <p>Checks if a String is not empty ("") and not null.</p> | |
| 66 | - * | |
| 67 | - * <pre> | |
| 68 | - * StringUtils.isNotEmpty(null) = false | |
| 69 | - * StringUtils.isNotEmpty("") = false | |
| 70 | - * StringUtils.isNotEmpty(" ") = true | |
| 71 | - * StringUtils.isNotEmpty("bob") = true | |
| 72 | - * StringUtils.isNotEmpty(" bob ") = true | |
| 73 | - * </pre> | |
| 74 | - * | |
| 75 | - * @param str the String to check, may be null | |
| 76 | - * @return <code>true</code> if the String is not empty and not null | |
| 77 | - */ | |
| 78 | - public static boolean isNotEmpty(String str) { | |
| 79 | - return !StringUtils.isEmpty(str); | |
| 80 | - } | |
| 81 | - | |
| 82 | - /** | |
| 83 | - * <p>Checks if a String is whitespace, empty ("") or null.</p> | |
| 84 | - * | |
| 85 | - * <pre> | |
| 86 | - * StringUtils.isBlank(null) = true | |
| 87 | - * StringUtils.isBlank("null") = true | |
| 88 | - * StringUtils.isBlank("") = true | |
| 89 | - * StringUtils.isBlank(" ") = true | |
| 90 | - * StringUtils.isBlank("bob") = false | |
| 91 | - * StringUtils.isBlank(" bob ") = false | |
| 92 | - * </pre> | |
| 93 | - * | |
| 94 | - * @param str the String to check, may be null | |
| 95 | - * @return <code>true</code> if the String is null, empty or whitespace | |
| 96 | - * @since 2.0 | |
| 97 | - */ | |
| 98 | - public static boolean isBlank(String str) { | |
| 99 | - int strLen; | |
| 100 | - if (str == null || (strLen = str.length()) == 0) { | |
| 101 | - return true; | |
| 102 | - } | |
| 103 | - if(equals("null", str.trim().toLowerCase())){ | |
| 104 | - return true; | |
| 105 | - } | |
| 106 | - for (int i = 0; i < strLen; i++) { | |
| 107 | - if ((Character.isWhitespace(str.charAt(i)) == false)) { | |
| 108 | - return false; | |
| 109 | - } | |
| 110 | - } | |
| 111 | - return true; | |
| 112 | - } | |
| 113 | - | |
| 114 | - /** | |
| 115 | - * <p>Checks if a String is not empty (""), not null and not whitespace only.</p> | |
| 116 | - * | |
| 117 | - * <pre> | |
| 118 | - * StringUtils.isNotBlank(null) = false | |
| 119 | - * StringUtils.isNotBlank("null") = false | |
| 120 | - * StringUtils.isNotBlank("") = false | |
| 121 | - * StringUtils.isNotBlank(" ") = false | |
| 122 | - * StringUtils.isNotBlank("bob") = true | |
| 123 | - * StringUtils.isNotBlank(" bob ") = true | |
| 124 | - * </pre> | |
| 125 | - * | |
| 126 | - * @param str the String to check, may be null | |
| 127 | - * @return <code>true</code> if the String is | |
| 128 | - * not empty and not null and not whitespace | |
| 129 | - * @since 2.0 | |
| 130 | - */ | |
| 131 | - public static boolean isNotBlank(String str) { | |
| 132 | - return !StringUtils.isBlank(str); | |
| 133 | - } | |
| 134 | - | |
| 135 | - // Trim | |
| 136 | - //----------------------------------------------------------------------- | |
| 137 | - /** | |
| 138 | - * <p>Removes control characters (char <= 32) from both | |
| 139 | - * ends of this String, handling <code>null</code> by returning | |
| 140 | - * an empty String ("").</p> | |
| 141 | - * | |
| 142 | - * <pre> | |
| 143 | - * StringUtils.clean(null) = "" | |
| 144 | - * StringUtils.clean("") = "" | |
| 145 | - * StringUtils.clean("abc") = "abc" | |
| 146 | - * StringUtils.clean(" abc ") = "abc" | |
| 147 | - * StringUtils.clean(" ") = "" | |
| 148 | - * </pre> | |
| 149 | - * | |
| 150 | - * @see String#trim() | |
| 151 | - * @param str the String to clean, may be null | |
| 152 | - * @return the trimmed text, never <code>null</code> | |
| 153 | - * @deprecated Use the clearer named {@link #trimToEmpty(String)}. | |
| 154 | - * Method will be removed in Commons Lang 3.0. | |
| 155 | - */ | |
| 156 | - public static String clean(String str) { | |
| 157 | - return str == null ? EMPTY : str.trim(); | |
| 158 | - } | |
| 159 | - | |
| 160 | - /** | |
| 161 | - * <p>Removes control characters (char <= 32) from both | |
| 162 | - * ends of this String, handling <code>null</code> by returning | |
| 163 | - * <code>null</code>.</p> | |
| 164 | - * | |
| 165 | - * <p>The String is trimmed using {@link String#trim()}. | |
| 166 | - * Trim removes start and end characters <= 32. | |
| 167 | - * To strip whitespace use {@link #strip(String)}.</p> | |
| 168 | - * | |
| 169 | - * <p>To trim your choice of characters, use the | |
| 170 | - * {@link #strip(String, String)} methods.</p> | |
| 171 | - * | |
| 172 | - * <pre> | |
| 173 | - * StringUtils.trim(null) = null | |
| 174 | - * StringUtils.trim("") = "" | |
| 175 | - * StringUtils.trim(" ") = "" | |
| 176 | - * StringUtils.trim("abc") = "abc" | |
| 177 | - * StringUtils.trim(" abc ") = "abc" | |
| 178 | - * </pre> | |
| 179 | - * | |
| 180 | - * @param str the String to be trimmed, may be null | |
| 181 | - * @return the trimmed string, <code>null</code> if null String input | |
| 182 | - */ | |
| 183 | - public static String trim(String str) { | |
| 184 | - return str == null ? null : str.trim(); | |
| 185 | - } | |
| 186 | - | |
| 187 | - /** | |
| 188 | - * <p>Removes control characters (char <= 32) from both | |
| 189 | - * ends of this String returning <code>null</code> if the String is | |
| 190 | - * empty ("") after the trim or if it is <code>null</code>. | |
| 191 | - * | |
| 192 | - * <p>The String is trimmed using {@link String#trim()}. | |
| 193 | - * Trim removes start and end characters <= 32. | |
| 194 | - * To strip whitespace use {@link #stripToNull(String)}.</p> | |
| 195 | - * | |
| 196 | - * <pre> | |
| 197 | - * StringUtils.trimToNull(null) = null | |
| 198 | - * StringUtils.trimToNull("") = null | |
| 199 | - * StringUtils.trimToNull(" ") = null | |
| 200 | - * StringUtils.trimToNull("abc") = "abc" | |
| 201 | - * StringUtils.trimToNull(" abc ") = "abc" | |
| 202 | - * </pre> | |
| 203 | - * | |
| 204 | - * @param str the String to be trimmed, may be null | |
| 205 | - * @return the trimmed String, | |
| 206 | - * <code>null</code> if only chars <= 32, empty or null String input | |
| 207 | - * @since 2.0 | |
| 208 | - */ | |
| 209 | - public static String trimToNull(String str) { | |
| 210 | - String ts = trim(str); | |
| 211 | - return isEmpty(ts) ? null : ts; | |
| 212 | - } | |
| 213 | - | |
| 214 | - /** | |
| 215 | - * <p>Removes control characters (char <= 32) from both | |
| 216 | - * ends of this String returning an empty String ("") if the String | |
| 217 | - * is empty ("") after the trim or if it is <code>null</code>. | |
| 218 | - * | |
| 219 | - * <p>The String is trimmed using {@link String#trim()}. | |
| 220 | - * Trim removes start and end characters <= 32. | |
| 221 | - * To strip whitespace use {@link #stripToEmpty(String)}.</p> | |
| 222 | - * | |
| 223 | - * <pre> | |
| 224 | - * StringUtils.trimToEmpty(null) = "" | |
| 225 | - * StringUtils.trimToEmpty("") = "" | |
| 226 | - * StringUtils.trimToEmpty(" ") = "" | |
| 227 | - * StringUtils.trimToEmpty("abc") = "abc" | |
| 228 | - * StringUtils.trimToEmpty(" abc ") = "abc" | |
| 229 | - * </pre> | |
| 230 | - * | |
| 231 | - * @param str the String to be trimmed, may be null | |
| 232 | - * @return the trimmed String, or an empty String if <code>null</code> input | |
| 233 | - * @since 2.0 | |
| 234 | - */ | |
| 235 | - public static String trimToEmpty(String str) { | |
| 236 | - return str == null ? EMPTY : str.trim(); | |
| 237 | - } | |
| 238 | - | |
| 239 | - // Stripping | |
| 240 | - //----------------------------------------------------------------------- | |
| 241 | - /** | |
| 242 | - * <p>Strips whitespace from the start and end of a String.</p> | |
| 243 | - * | |
| 244 | - * <p>This is similar to {@link #trim(String)} but removes whitespace. | |
| 245 | - * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> | |
| 246 | - * | |
| 247 | - * <p>A <code>null</code> input String returns <code>null</code>.</p> | |
| 248 | - * | |
| 249 | - * <pre> | |
| 250 | - * StringUtils.strip(null) = null | |
| 251 | - * StringUtils.strip("") = "" | |
| 252 | - * StringUtils.strip(" ") = "" | |
| 253 | - * StringUtils.strip("abc") = "abc" | |
| 254 | - * StringUtils.strip(" abc") = "abc" | |
| 255 | - * StringUtils.strip("abc ") = "abc" | |
| 256 | - * StringUtils.strip(" abc ") = "abc" | |
| 257 | - * StringUtils.strip(" ab c ") = "ab c" | |
| 258 | - * </pre> | |
| 259 | - * | |
| 260 | - * @param str the String to remove whitespace from, may be null | |
| 261 | - * @return the stripped String, <code>null</code> if null String input | |
| 262 | - */ | |
| 263 | - public static String strip(String str) { | |
| 264 | - return strip(str, null); | |
| 265 | - } | |
| 266 | - | |
| 267 | - /** | |
| 268 | - * <p>Strips whitespace from the start and end of a String returning | |
| 269 | - * <code>null</code> if the String is empty ("") after the strip.</p> | |
| 270 | - * | |
| 271 | - * <p>This is similar to {@link #trimToNull(String)} but removes whitespace. | |
| 272 | - * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> | |
| 273 | - * | |
| 274 | - * <pre> | |
| 275 | - * StringUtils.stripToNull(null) = null | |
| 276 | - * StringUtils.stripToNull("") = null | |
| 277 | - * StringUtils.stripToNull(" ") = null | |
| 278 | - * StringUtils.stripToNull("abc") = "abc" | |
| 279 | - * StringUtils.stripToNull(" abc") = "abc" | |
| 280 | - * StringUtils.stripToNull("abc ") = "abc" | |
| 281 | - * StringUtils.stripToNull(" abc ") = "abc" | |
| 282 | - * StringUtils.stripToNull(" ab c ") = "ab c" | |
| 283 | - * </pre> | |
| 284 | - * | |
| 285 | - * @param str the String to be stripped, may be null | |
| 286 | - * @return the stripped String, | |
| 287 | - * <code>null</code> if whitespace, empty or null String input | |
| 288 | - * @since 2.0 | |
| 289 | - */ | |
| 290 | - public static String stripToNull(String str) { | |
| 291 | - if (str == null) { | |
| 292 | - return null; | |
| 293 | - } | |
| 294 | - str = strip(str, null); | |
| 295 | - return str.length() == 0 ? null : str; | |
| 296 | - } | |
| 297 | - | |
| 298 | - /** | |
| 299 | - * <p>Strips whitespace from the start and end of a String returning | |
| 300 | - * an empty String if <code>null</code> input.</p> | |
| 301 | - * | |
| 302 | - * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace. | |
| 303 | - * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> | |
| 304 | - * | |
| 305 | - * <pre> | |
| 306 | - * StringUtils.stripToEmpty(null) = "" | |
| 307 | - * StringUtils.stripToEmpty("") = "" | |
| 308 | - * StringUtils.stripToEmpty(" ") = "" | |
| 309 | - * StringUtils.stripToEmpty("abc") = "abc" | |
| 310 | - * StringUtils.stripToEmpty(" abc") = "abc" | |
| 311 | - * StringUtils.stripToEmpty("abc ") = "abc" | |
| 312 | - * StringUtils.stripToEmpty(" abc ") = "abc" | |
| 313 | - * StringUtils.stripToEmpty(" ab c ") = "ab c" | |
| 314 | - * </pre> | |
| 315 | - * | |
| 316 | - * @param str the String to be stripped, may be null | |
| 317 | - * @return the trimmed String, or an empty String if <code>null</code> input | |
| 318 | - * @since 2.0 | |
| 319 | - */ | |
| 320 | - public static String stripToEmpty(String str) { | |
| 321 | - return str == null ? EMPTY : strip(str, null); | |
| 322 | - } | |
| 323 | - | |
| 324 | - /** | |
| 325 | - * <p>Strips any of a set of characters from the start and end of a String. | |
| 326 | - * This is similar to {@link String#trim()} but allows the characters | |
| 327 | - * to be stripped to be controlled.</p> | |
| 328 | - * | |
| 329 | - * <p>A <code>null</code> input String returns <code>null</code>. | |
| 330 | - * An empty string ("") input returns the empty string.</p> | |
| 331 | - * | |
| 332 | - * <p>If the stripChars String is <code>null</code>, whitespace is | |
| 333 | - * stripped as defined by {@link Character#isWhitespace(char)}. | |
| 334 | - * Alternatively use {@link #strip(String)}.</p> | |
| 335 | - * | |
| 336 | - * <pre> | |
| 337 | - * StringUtils.strip(null, *) = null | |
| 338 | - * StringUtils.strip("", *) = "" | |
| 339 | - * StringUtils.strip("abc", null) = "abc" | |
| 340 | - * StringUtils.strip(" abc", null) = "abc" | |
| 341 | - * StringUtils.strip("abc ", null) = "abc" | |
| 342 | - * StringUtils.strip(" abc ", null) = "abc" | |
| 343 | - * StringUtils.strip(" abcyx", "xyz") = " abc" | |
| 344 | - * </pre> | |
| 345 | - * | |
| 346 | - * @param str the String to remove characters from, may be null | |
| 347 | - * @param stripChars the characters to remove, null treated as whitespace | |
| 348 | - * @return the stripped String, <code>null</code> if null String input | |
| 349 | - */ | |
| 350 | - public static String strip(String str, String stripChars) { | |
| 351 | - if (isEmpty(str)) { | |
| 352 | - return str; | |
| 353 | - } | |
| 354 | - str = stripStart(str, stripChars); | |
| 355 | - return stripEnd(str, stripChars); | |
| 356 | - } | |
| 357 | - | |
| 358 | - /** | |
| 359 | - * <p>Strips any of a set of characters from the start of a String.</p> | |
| 360 | - * | |
| 361 | - * <p>A <code>null</code> input String returns <code>null</code>. | |
| 362 | - * An empty string ("") input returns the empty string.</p> | |
| 363 | - * | |
| 364 | - * <p>If the stripChars String is <code>null</code>, whitespace is | |
| 365 | - * stripped as defined by {@link Character#isWhitespace(char)}.</p> | |
| 366 | - * | |
| 367 | - * <pre> | |
| 368 | - * StringUtils.stripStart(null, *) = null | |
| 369 | - * StringUtils.stripStart("", *) = "" | |
| 370 | - * StringUtils.stripStart("abc", "") = "abc" | |
| 371 | - * StringUtils.stripStart("abc", null) = "abc" | |
| 372 | - * StringUtils.stripStart(" abc", null) = "abc" | |
| 373 | - * StringUtils.stripStart("abc ", null) = "abc " | |
| 374 | - * StringUtils.stripStart(" abc ", null) = "abc " | |
| 375 | - * StringUtils.stripStart("yxabc ", "xyz") = "abc " | |
| 376 | - * </pre> | |
| 377 | - * | |
| 378 | - * @param str the String to remove characters from, may be null | |
| 379 | - * @param stripChars the characters to remove, null treated as whitespace | |
| 380 | - * @return the stripped String, <code>null</code> if null String input | |
| 381 | - */ | |
| 382 | - public static String stripStart(String str, String stripChars) { | |
| 383 | - int strLen; | |
| 384 | - if (str == null || (strLen = str.length()) == 0) { | |
| 385 | - return str; | |
| 386 | - } | |
| 387 | - int start = 0; | |
| 388 | - if (stripChars == null) { | |
| 389 | - while ((start != strLen) && Character.isWhitespace(str.charAt(start))) { | |
| 390 | - start++; | |
| 391 | - } | |
| 392 | - } else if (stripChars.length() == 0) { | |
| 393 | - return str; | |
| 394 | - } else { | |
| 395 | - while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND)) { | |
| 396 | - start++; | |
| 397 | - } | |
| 398 | - } | |
| 399 | - return str.substring(start); | |
| 400 | - } | |
| 401 | - | |
| 402 | - /** | |
| 403 | - * <p>Strips any of a set of characters from the end of a String.</p> | |
| 404 | - * | |
| 405 | - * <p>A <code>null</code> input String returns <code>null</code>. | |
| 406 | - * An empty string ("") input returns the empty string.</p> | |
| 407 | - * | |
| 408 | - * <p>If the stripChars String is <code>null</code>, whitespace is | |
| 409 | - * stripped as defined by {@link Character#isWhitespace(char)}.</p> | |
| 410 | - * | |
| 411 | - * <pre> | |
| 412 | - * StringUtils.stripEnd(null, *) = null | |
| 413 | - * StringUtils.stripEnd("", *) = "" | |
| 414 | - * StringUtils.stripEnd("abc", "") = "abc" | |
| 415 | - * StringUtils.stripEnd("abc", null) = "abc" | |
| 416 | - * StringUtils.stripEnd(" abc", null) = " abc" | |
| 417 | - * StringUtils.stripEnd("abc ", null) = "abc" | |
| 418 | - * StringUtils.stripEnd(" abc ", null) = " abc" | |
| 419 | - * StringUtils.stripEnd(" abcyx", "xyz") = " abc" | |
| 420 | - * StringUtils.stripEnd("120.00", ".0") = "12" | |
| 421 | - * </pre> | |
| 422 | - * | |
| 423 | - * @param str the String to remove characters from, may be null | |
| 424 | - * @param stripChars the set of characters to remove, null treated as whitespace | |
| 425 | - * @return the stripped String, <code>null</code> if null String input | |
| 426 | - */ | |
| 427 | - public static String stripEnd(String str, String stripChars) { | |
| 428 | - int end; | |
| 429 | - if (str == null || (end = str.length()) == 0) { | |
| 430 | - return str; | |
| 431 | - } | |
| 432 | - | |
| 433 | - if (stripChars == null) { | |
| 434 | - while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) { | |
| 435 | - end--; | |
| 436 | - } | |
| 437 | - } else if (stripChars.length() == 0) { | |
| 438 | - return str; | |
| 439 | - } else { | |
| 440 | - while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND)) { | |
| 441 | - end--; | |
| 442 | - } | |
| 443 | - } | |
| 444 | - return str.substring(0, end); | |
| 445 | - } | |
| 446 | - | |
| 447 | - // StripAll | |
| 448 | - //----------------------------------------------------------------------- | |
| 449 | - /** | |
| 450 | - * <p>Strips whitespace from the start and end of every String in an array. | |
| 451 | - * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> | |
| 452 | - * | |
| 453 | - * <p>A new array is returned each time, except for length zero. | |
| 454 | - * A <code>null</code> array will return <code>null</code>. | |
| 455 | - * An empty array will return itself. | |
| 456 | - * A <code>null</code> array entry will be ignored.</p> | |
| 457 | - * | |
| 458 | - * <pre> | |
| 459 | - * StringUtils.stripAll(null) = null | |
| 460 | - * StringUtils.stripAll([]) = [] | |
| 461 | - * StringUtils.stripAll(["abc", " abc"]) = ["abc", "abc"] | |
| 462 | - * StringUtils.stripAll(["abc ", null]) = ["abc", null] | |
| 463 | - * </pre> | |
| 464 | - * | |
| 465 | - * @param strs the array to remove whitespace from, may be null | |
| 466 | - * @return the stripped Strings, <code>null</code> if null array input | |
| 467 | - */ | |
| 468 | - public static String[] stripAll(String[] strs) { | |
| 469 | - return stripAll(strs, null); | |
| 470 | - } | |
| 471 | - | |
| 472 | - /** | |
| 473 | - * <p>Strips any of a set of characters from the start and end of every | |
| 474 | - * String in an array.</p> | |
| 475 | - * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> | |
| 476 | - * | |
| 477 | - * <p>A new array is returned each time, except for length zero. | |
| 478 | - * A <code>null</code> array will return <code>null</code>. | |
| 479 | - * An empty array will return itself. | |
| 480 | - * A <code>null</code> array entry will be ignored. | |
| 481 | - * A <code>null</code> stripChars will strip whitespace as defined by | |
| 482 | - * {@link Character#isWhitespace(char)}.</p> | |
| 483 | - * | |
| 484 | - * <pre> | |
| 485 | - * StringUtils.stripAll(null, *) = null | |
| 486 | - * StringUtils.stripAll([], *) = [] | |
| 487 | - * StringUtils.stripAll(["abc", " abc"], null) = ["abc", "abc"] | |
| 488 | - * StringUtils.stripAll(["abc ", null], null) = ["abc", null] | |
| 489 | - * StringUtils.stripAll(["abc ", null], "yz") = ["abc ", null] | |
| 490 | - * StringUtils.stripAll(["yabcz", null], "yz") = ["abc", null] | |
| 491 | - * </pre> | |
| 492 | - * | |
| 493 | - * @param strs the array to remove characters from, may be null | |
| 494 | - * @param stripChars the characters to remove, null treated as whitespace | |
| 495 | - * @return the stripped Strings, <code>null</code> if null array input | |
| 496 | - */ | |
| 497 | - public static String[] stripAll(String[] strs, String stripChars) { | |
| 498 | - int strsLen; | |
| 499 | - if (strs == null || (strsLen = strs.length) == 0) { | |
| 500 | - return strs; | |
| 501 | - } | |
| 502 | - String[] newArr = new String[strsLen]; | |
| 503 | - for (int i = 0; i < strsLen; i++) { | |
| 504 | - newArr[i] = strip(strs[i], stripChars); | |
| 505 | - } | |
| 506 | - return newArr; | |
| 507 | - } | |
| 508 | - | |
| 509 | - // Equals | |
| 510 | - //----------------------------------------------------------------------- | |
| 511 | - /** | |
| 512 | - * <p>Compares two Strings, returning <code>true</code> if they are equal.</p> | |
| 513 | - * | |
| 514 | - * <p><code>null</code>s are handled without exceptions. Two <code>null</code> | |
| 515 | - * references are considered to be equal. The comparison is case sensitive.</p> | |
| 516 | - * | |
| 517 | - * <pre> | |
| 518 | - * StringUtils.equals(null, null) = true | |
| 519 | - * StringUtils.equals(null, "abc") = false | |
| 520 | - * StringUtils.equals("abc", null) = false | |
| 521 | - * StringUtils.equals("abc", "abc") = true | |
| 522 | - * StringUtils.equals("abc", "ABC") = false | |
| 523 | - * </pre> | |
| 524 | - * | |
| 525 | - * @see String#equals(Object) | |
| 526 | - * @param str1 the first String, may be null | |
| 527 | - * @param str2 the second String, may be null | |
| 528 | - * @return <code>true</code> if the Strings are equal, case sensitive, or | |
| 529 | - * both <code>null</code> | |
| 530 | - */ | |
| 531 | - public static boolean equals(String str1, String str2) { | |
| 532 | - return str1 == null ? str2 == null : str1.equals(str2); | |
| 533 | - } | |
| 534 | - | |
| 535 | - /** | |
| 536 | - * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring | |
| 537 | - * the case.</p> | |
| 538 | - * | |
| 539 | - * <p><code>null</code>s are handled without exceptions. Two <code>null</code> | |
| 540 | - * references are considered equal. Comparison is case insensitive.</p> | |
| 541 | - * | |
| 542 | - * <pre> | |
| 543 | - * StringUtils.equalsIgnoreCase(null, null) = true | |
| 544 | - * StringUtils.equalsIgnoreCase(null, "abc") = false | |
| 545 | - * StringUtils.equalsIgnoreCase("abc", null) = false | |
| 546 | - * StringUtils.equalsIgnoreCase("abc", "abc") = true | |
| 547 | - * StringUtils.equalsIgnoreCase("abc", "ABC") = true | |
| 548 | - * </pre> | |
| 549 | - * | |
| 550 | - * @see String#equalsIgnoreCase(String) | |
| 551 | - * @param str1 the first String, may be null | |
| 552 | - * @param str2 the second String, may be null | |
| 553 | - * @return <code>true</code> if the Strings are equal, case insensitive, or | |
| 554 | - * both <code>null</code> | |
| 555 | - */ | |
| 556 | - public static boolean equalsIgnoreCase(String str1, String str2) { | |
| 557 | - return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); | |
| 558 | - } | |
| 559 | - | |
| 560 | - // IndexOf | |
| 561 | - //----------------------------------------------------------------------- | |
| 562 | - /** | |
| 563 | - * <p>Finds the first index within a String, handling <code>null</code>. | |
| 564 | - * This method uses {@link String#indexOf(int)}.</p> | |
| 565 | - * | |
| 566 | - * <p>A <code>null</code> or empty ("") String will return <code>INDEX_NOT_FOUND (-1)</code>.</p> | |
| 567 | - * | |
| 568 | - * <pre> | |
| 569 | - * StringUtils.indexOf(null, *) = -1 | |
| 570 | - * StringUtils.indexOf("", *) = -1 | |
| 571 | - * StringUtils.indexOf("aabaabaa", 'a') = 0 | |
| 572 | - * StringUtils.indexOf("aabaabaa", 'b') = 2 | |
| 573 | - * </pre> | |
| 574 | - * | |
| 575 | - * @param str the String to check, may be null | |
| 576 | - * @param searchChar the character to find | |
| 577 | - * @return the first index of the search character, | |
| 578 | - * -1 if no match or <code>null</code> string input | |
| 579 | - * @since 2.0 | |
| 580 | - */ | |
| 581 | - public static int indexOf(String str, char searchChar) { | |
| 582 | - if (isEmpty(str)) { | |
| 583 | - return INDEX_NOT_FOUND; | |
| 584 | - } | |
| 585 | - return str.indexOf(searchChar); | |
| 586 | - } | |
| 587 | - | |
| 588 | - /** | |
| 589 | - * <p>Finds the first index within a String from a start position, | |
| 590 | - * handling <code>null</code>. | |
| 591 | - * This method uses {@link String#indexOf(int, int)}.</p> | |
| 592 | - * | |
| 593 | - * <p>A <code>null</code> or empty ("") String will return <code>(INDEX_NOT_FOUND) -1</code>. | |
| 594 | - * A negative start position is treated as zero. | |
| 595 | - * A start position greater than the string length returns <code>-1</code>.</p> | |
| 596 | - * | |
| 597 | - * <pre> | |
| 598 | - * StringUtils.indexOf(null, *, *) = -1 | |
| 599 | - * StringUtils.indexOf("", *, *) = -1 | |
| 600 | - * StringUtils.indexOf("aabaabaa", 'b', 0) = 2 | |
| 601 | - * StringUtils.indexOf("aabaabaa", 'b', 3) = 5 | |
| 602 | - * StringUtils.indexOf("aabaabaa", 'b', 9) = -1 | |
| 603 | - * StringUtils.indexOf("aabaabaa", 'b', -1) = 2 | |
| 604 | - * </pre> | |
| 605 | - * | |
| 606 | - * @param str the String to check, may be null | |
| 607 | - * @param searchChar the character to find | |
| 608 | - * @param startPos the start position, negative treated as zero | |
| 609 | - * @return the first index of the search character, | |
| 610 | - * -1 if no match or <code>null</code> string input | |
| 611 | - * @since 2.0 | |
| 612 | - */ | |
| 613 | - public static int indexOf(String str, char searchChar, int startPos) { | |
| 614 | - if (isEmpty(str)) { | |
| 615 | - return INDEX_NOT_FOUND; | |
| 616 | - } | |
| 617 | - return str.indexOf(searchChar, startPos); | |
| 618 | - } | |
| 619 | - | |
| 620 | - /** | |
| 621 | - * <p>Finds the first index within a String, handling <code>null</code>. | |
| 622 | - * This method uses {@link String#indexOf(String)}.</p> | |
| 623 | - * | |
| 624 | - * <p>A <code>null</code> String will return <code>-1</code>.</p> | |
| 625 | - * | |
| 626 | - * <pre> | |
| 627 | - * StringUtils.indexOf(null, *) = -1 | |
| 628 | - * StringUtils.indexOf(*, null) = -1 | |
| 629 | - * StringUtils.indexOf("", "") = 0 | |
| 630 | - * StringUtils.indexOf("", *) = -1 (except when * = "") | |
| 631 | - * StringUtils.indexOf("aabaabaa", "a") = 0 | |
| 632 | - * StringUtils.indexOf("aabaabaa", "b") = 2 | |
| 633 | - * StringUtils.indexOf("aabaabaa", "ab") = 1 | |
| 634 | - * StringUtils.indexOf("aabaabaa", "") = 0 | |
| 635 | - * </pre> | |
| 636 | - * | |
| 637 | - * @param str the String to check, may be null | |
| 638 | - * @param searchStr the String to find, may be null | |
| 639 | - * @return the first index of the search String, | |
| 640 | - * -1 if no match or <code>null</code> string input | |
| 641 | - * @since 2.0 | |
| 642 | - */ | |
| 643 | - public static int indexOf(String str, String searchStr) { | |
| 644 | - if (str == null || searchStr == null) { | |
| 645 | - return INDEX_NOT_FOUND; | |
| 646 | - } | |
| 647 | - return str.indexOf(searchStr); | |
| 648 | - } | |
| 649 | - | |
| 650 | - /** | |
| 651 | - * <p>Finds the n-th index within a String, handling <code>null</code>. | |
| 652 | - * This method uses {@link String#indexOf(String)}.</p> | |
| 653 | - * | |
| 654 | - * <p>A <code>null</code> String will return <code>-1</code>.</p> | |
| 655 | - * | |
| 656 | - * <pre> | |
| 657 | - * StringUtils.ordinalIndexOf(null, *, *) = -1 | |
| 658 | - * StringUtils.ordinalIndexOf(*, null, *) = -1 | |
| 659 | - * StringUtils.ordinalIndexOf("", "", *) = 0 | |
| 660 | - * StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0 | |
| 661 | - * StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1 | |
| 662 | - * StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2 | |
| 663 | - * StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5 | |
| 664 | - * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1 | |
| 665 | - * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4 | |
| 666 | - * StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0 | |
| 667 | - * StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0 | |
| 668 | - * </pre> | |
| 669 | - * | |
| 670 | - * <p>Note that 'head(String str, int n)' may be implemented as: </p> | |
| 671 | - * | |
| 672 | - * <pre> | |
| 673 | - * str.substring(0, lastOrdinalIndexOf(str, "\n", n)) | |
| 674 | - * </pre> | |
| 675 | - * | |
| 676 | - * @param str the String to check, may be null | |
| 677 | - * @param searchStr the String to find, may be null | |
| 678 | - * @param ordinal the n-th <code>searchStr</code> to find | |
| 679 | - * @return the n-th index of the search String, | |
| 680 | - * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input | |
| 681 | - * @since 2.1 | |
| 682 | - */ | |
| 683 | - public static int ordinalIndexOf(String str, String searchStr, int ordinal) { | |
| 684 | - return ordinalIndexOf(str, searchStr, ordinal, false); | |
| 685 | - } | |
| 686 | - | |
| 687 | - /** | |
| 688 | - * <p>Finds the n-th index within a String, handling <code>null</code>. | |
| 689 | - * This method uses {@link String#indexOf(String)}.</p> | |
| 690 | - * | |
| 691 | - * <p>A <code>null</code> String will return <code>-1</code>.</p> | |
| 692 | - * | |
| 693 | - * @param str the String to check, may be null | |
| 694 | - * @param searchStr the String to find, may be null | |
| 695 | - * @param ordinal the n-th <code>searchStr</code> to find | |
| 696 | - * @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf() | |
| 697 | - * @return the n-th index of the search String, | |
| 698 | - * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input | |
| 699 | - */ | |
| 700 | - // Shared code between ordinalIndexOf(String,String,int) and lastOrdinalIndexOf(String,String,int) | |
| 701 | - private static int ordinalIndexOf(String str, String searchStr, int ordinal, boolean lastIndex) { | |
| 702 | - if (str == null || searchStr == null || ordinal <= 0) { | |
| 703 | - return INDEX_NOT_FOUND; | |
| 704 | - } | |
| 705 | - if (searchStr.length() == 0) { | |
| 706 | - return lastIndex ? str.length() : 0; | |
| 707 | - } | |
| 708 | - int found = 0; | |
| 709 | - int index = lastIndex ? str.length() : INDEX_NOT_FOUND; | |
| 710 | - do { | |
| 711 | - if(lastIndex) { | |
| 712 | - index = str.lastIndexOf(searchStr, index - 1); | |
| 713 | - } else { | |
| 714 | - index = str.indexOf(searchStr, index + 1); | |
| 715 | - } | |
| 716 | - if (index < 0) { | |
| 717 | - return index; | |
| 718 | - } | |
| 719 | - found++; | |
| 720 | - } while (found < ordinal); | |
| 721 | - return index; | |
| 722 | - } | |
| 723 | - | |
| 724 | - /** | |
| 725 | - * <p>Finds the first index within a String, handling <code>null</code>. | |
| 726 | - * This method uses {@link String#indexOf(String, int)}.</p> | |
| 727 | - * | |
| 728 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 729 | - * A negative start position is treated as zero. | |
| 730 | - * An empty ("") search String always matches. | |
| 731 | - * A start position greater than the string length only matches | |
| 732 | - * an empty search String.</p> | |
| 733 | - * | |
| 734 | - * <pre> | |
| 735 | - * StringUtils.indexOf(null, *, *) = -1 | |
| 736 | - * StringUtils.indexOf(*, null, *) = -1 | |
| 737 | - * StringUtils.indexOf("", "", 0) = 0 | |
| 738 | - * StringUtils.indexOf("", *, 0) = -1 (except when * = "") | |
| 739 | - * StringUtils.indexOf("aabaabaa", "a", 0) = 0 | |
| 740 | - * StringUtils.indexOf("aabaabaa", "b", 0) = 2 | |
| 741 | - * StringUtils.indexOf("aabaabaa", "ab", 0) = 1 | |
| 742 | - * StringUtils.indexOf("aabaabaa", "b", 3) = 5 | |
| 743 | - * StringUtils.indexOf("aabaabaa", "b", 9) = -1 | |
| 744 | - * StringUtils.indexOf("aabaabaa", "b", -1) = 2 | |
| 745 | - * StringUtils.indexOf("aabaabaa", "", 2) = 2 | |
| 746 | - * StringUtils.indexOf("abc", "", 9) = 3 | |
| 747 | - * </pre> | |
| 748 | - * | |
| 749 | - * @param str the String to check, may be null | |
| 750 | - * @param searchStr the String to find, may be null | |
| 751 | - * @param startPos the start position, negative treated as zero | |
| 752 | - * @return the first index of the search String, | |
| 753 | - * -1 if no match or <code>null</code> string input | |
| 754 | - * @since 2.0 | |
| 755 | - */ | |
| 756 | - public static int indexOf(String str, String searchStr, int startPos) { | |
| 757 | - if (str == null || searchStr == null) { | |
| 758 | - return INDEX_NOT_FOUND; | |
| 759 | - } | |
| 760 | - // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence | |
| 761 | - if (searchStr.length() == 0 && startPos >= str.length()) { | |
| 762 | - return str.length(); | |
| 763 | - } | |
| 764 | - return str.indexOf(searchStr, startPos); | |
| 765 | - } | |
| 766 | - | |
| 767 | - /** | |
| 768 | - * <p>Case in-sensitive find of the first index within a String.</p> | |
| 769 | - * | |
| 770 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 771 | - * A negative start position is treated as zero. | |
| 772 | - * An empty ("") search String always matches. | |
| 773 | - * A start position greater than the string length only matches | |
| 774 | - * an empty search String.</p> | |
| 775 | - * | |
| 776 | - * <pre> | |
| 777 | - * StringUtils.indexOfIgnoreCase(null, *) = -1 | |
| 778 | - * StringUtils.indexOfIgnoreCase(*, null) = -1 | |
| 779 | - * StringUtils.indexOfIgnoreCase("", "") = 0 | |
| 780 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "a") = 0 | |
| 781 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "b") = 2 | |
| 782 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1 | |
| 783 | - * </pre> | |
| 784 | - * | |
| 785 | - * @param str the String to check, may be null | |
| 786 | - * @param searchStr the String to find, may be null | |
| 787 | - * @return the first index of the search String, | |
| 788 | - * -1 if no match or <code>null</code> string input | |
| 789 | - * @since 2.5 | |
| 790 | - */ | |
| 791 | - public static int indexOfIgnoreCase(String str, String searchStr) { | |
| 792 | - return indexOfIgnoreCase(str, searchStr, 0); | |
| 793 | - } | |
| 794 | - | |
| 795 | - /** | |
| 796 | - * <p>Case in-sensitive find of the first index within a String | |
| 797 | - * from the specified position.</p> | |
| 798 | - * | |
| 799 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 800 | - * A negative start position is treated as zero. | |
| 801 | - * An empty ("") search String always matches. | |
| 802 | - * A start position greater than the string length only matches | |
| 803 | - * an empty search String.</p> | |
| 804 | - * | |
| 805 | - * <pre> | |
| 806 | - * StringUtils.indexOfIgnoreCase(null, *, *) = -1 | |
| 807 | - * StringUtils.indexOfIgnoreCase(*, null, *) = -1 | |
| 808 | - * StringUtils.indexOfIgnoreCase("", "", 0) = 0 | |
| 809 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0) = 0 | |
| 810 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0) = 2 | |
| 811 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1 | |
| 812 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3) = 5 | |
| 813 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9) = -1 | |
| 814 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2 | |
| 815 | - * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2) = 2 | |
| 816 | - * StringUtils.indexOfIgnoreCase("abc", "", 9) = 3 | |
| 817 | - * </pre> | |
| 818 | - * | |
| 819 | - * @param str the String to check, may be null | |
| 820 | - * @param searchStr the String to find, may be null | |
| 821 | - * @param startPos the start position, negative treated as zero | |
| 822 | - * @return the first index of the search String, | |
| 823 | - * -1 if no match or <code>null</code> string input | |
| 824 | - * @since 2.5 | |
| 825 | - */ | |
| 826 | - public static int indexOfIgnoreCase(String str, String searchStr, int startPos) { | |
| 827 | - if (str == null || searchStr == null) { | |
| 828 | - return INDEX_NOT_FOUND; | |
| 829 | - } | |
| 830 | - if (startPos < 0) { | |
| 831 | - startPos = 0; | |
| 832 | - } | |
| 833 | - int endLimit = (str.length() - searchStr.length()) + 1; | |
| 834 | - if (startPos > endLimit) { | |
| 835 | - return INDEX_NOT_FOUND; | |
| 836 | - } | |
| 837 | - if (searchStr.length() == 0) { | |
| 838 | - return startPos; | |
| 839 | - } | |
| 840 | - for (int i = startPos; i < endLimit; i++) { | |
| 841 | - if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) { | |
| 842 | - return i; | |
| 843 | - } | |
| 844 | - } | |
| 845 | - return INDEX_NOT_FOUND; | |
| 846 | - } | |
| 847 | - | |
| 848 | - // LastIndexOf | |
| 849 | - //----------------------------------------------------------------------- | |
| 850 | - /** | |
| 851 | - * <p>Finds the last index within a String, handling <code>null</code>. | |
| 852 | - * This method uses {@link String#lastIndexOf(int)}.</p> | |
| 853 | - * | |
| 854 | - * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p> | |
| 855 | - * | |
| 856 | - * <pre> | |
| 857 | - * StringUtils.lastIndexOf(null, *) = -1 | |
| 858 | - * StringUtils.lastIndexOf("", *) = -1 | |
| 859 | - * StringUtils.lastIndexOf("aabaabaa", 'a') = 7 | |
| 860 | - * StringUtils.lastIndexOf("aabaabaa", 'b') = 5 | |
| 861 | - * </pre> | |
| 862 | - * | |
| 863 | - * @param str the String to check, may be null | |
| 864 | - * @param searchChar the character to find | |
| 865 | - * @return the last index of the search character, | |
| 866 | - * -1 if no match or <code>null</code> string input | |
| 867 | - * @since 2.0 | |
| 868 | - */ | |
| 869 | - public static int lastIndexOf(String str, char searchChar) { | |
| 870 | - if (isEmpty(str)) { | |
| 871 | - return INDEX_NOT_FOUND; | |
| 872 | - } | |
| 873 | - return str.lastIndexOf(searchChar); | |
| 874 | - } | |
| 875 | - | |
| 876 | - /** | |
| 877 | - * <p>Finds the last index within a String from a start position, | |
| 878 | - * handling <code>null</code>. | |
| 879 | - * This method uses {@link String#lastIndexOf(int, int)}.</p> | |
| 880 | - * | |
| 881 | - * <p>A <code>null</code> or empty ("") String will return <code>-1</code>. | |
| 882 | - * A negative start position returns <code>-1</code>. | |
| 883 | - * A start position greater than the string length searches the whole string.</p> | |
| 884 | - * | |
| 885 | - * <pre> | |
| 886 | - * StringUtils.lastIndexOf(null, *, *) = -1 | |
| 887 | - * StringUtils.lastIndexOf("", *, *) = -1 | |
| 888 | - * StringUtils.lastIndexOf("aabaabaa", 'b', 8) = 5 | |
| 889 | - * StringUtils.lastIndexOf("aabaabaa", 'b', 4) = 2 | |
| 890 | - * StringUtils.lastIndexOf("aabaabaa", 'b', 0) = -1 | |
| 891 | - * StringUtils.lastIndexOf("aabaabaa", 'b', 9) = 5 | |
| 892 | - * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1 | |
| 893 | - * StringUtils.lastIndexOf("aabaabaa", 'a', 0) = 0 | |
| 894 | - * </pre> | |
| 895 | - * | |
| 896 | - * @param str the String to check, may be null | |
| 897 | - * @param searchChar the character to find | |
| 898 | - * @param startPos the start position | |
| 899 | - * @return the last index of the search character, | |
| 900 | - * -1 if no match or <code>null</code> string input | |
| 901 | - * @since 2.0 | |
| 902 | - */ | |
| 903 | - public static int lastIndexOf(String str, char searchChar, int startPos) { | |
| 904 | - if (isEmpty(str)) { | |
| 905 | - return INDEX_NOT_FOUND; | |
| 906 | - } | |
| 907 | - return str.lastIndexOf(searchChar, startPos); | |
| 908 | - } | |
| 909 | - | |
| 910 | - /** | |
| 911 | - * <p>Finds the last index within a String, handling <code>null</code>. | |
| 912 | - * This method uses {@link String#lastIndexOf(String)}.</p> | |
| 913 | - * | |
| 914 | - * <p>A <code>null</code> String will return <code>-1</code>.</p> | |
| 915 | - * | |
| 916 | - * <pre> | |
| 917 | - * StringUtils.lastIndexOf(null, *) = -1 | |
| 918 | - * StringUtils.lastIndexOf(*, null) = -1 | |
| 919 | - * StringUtils.lastIndexOf("", "") = 0 | |
| 920 | - * StringUtils.lastIndexOf("aabaabaa", "a") = 7 | |
| 921 | - * StringUtils.lastIndexOf("aabaabaa", "b") = 5 | |
| 922 | - * StringUtils.lastIndexOf("aabaabaa", "ab") = 4 | |
| 923 | - * StringUtils.lastIndexOf("aabaabaa", "") = 8 | |
| 924 | - * </pre> | |
| 925 | - * | |
| 926 | - * @param str the String to check, may be null | |
| 927 | - * @param searchStr the String to find, may be null | |
| 928 | - * @return the last index of the search String, | |
| 929 | - * -1 if no match or <code>null</code> string input | |
| 930 | - * @since 2.0 | |
| 931 | - */ | |
| 932 | - public static int lastIndexOf(String str, String searchStr) { | |
| 933 | - if (str == null || searchStr == null) { | |
| 934 | - return INDEX_NOT_FOUND; | |
| 935 | - } | |
| 936 | - return str.lastIndexOf(searchStr); | |
| 937 | - } | |
| 938 | - | |
| 939 | - /** | |
| 940 | - * <p>Finds the n-th last index within a String, handling <code>null</code>. | |
| 941 | - * This method uses {@link String#lastIndexOf(String)}.</p> | |
| 942 | - * | |
| 943 | - * <p>A <code>null</code> String will return <code>-1</code>.</p> | |
| 944 | - * | |
| 945 | - * <pre> | |
| 946 | - * StringUtils.lastOrdinalIndexOf(null, *, *) = -1 | |
| 947 | - * StringUtils.lastOrdinalIndexOf(*, null, *) = -1 | |
| 948 | - * StringUtils.lastOrdinalIndexOf("", "", *) = 0 | |
| 949 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1) = 7 | |
| 950 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2) = 6 | |
| 951 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1) = 5 | |
| 952 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2) = 2 | |
| 953 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4 | |
| 954 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1 | |
| 955 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1) = 8 | |
| 956 | - * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2) = 8 | |
| 957 | - * </pre> | |
| 958 | - * | |
| 959 | - * <p>Note that 'tail(String str, int n)' may be implemented as: </p> | |
| 960 | - * | |
| 961 | - * <pre> | |
| 962 | - * str.substring(lastOrdinalIndexOf(str, "\n", n) + 1) | |
| 963 | - * </pre> | |
| 964 | - * | |
| 965 | - * @param str the String to check, may be null | |
| 966 | - * @param searchStr the String to find, may be null | |
| 967 | - * @param ordinal the n-th last <code>searchStr</code> to find | |
| 968 | - * @return the n-th last index of the search String, | |
| 969 | - * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input | |
| 970 | - * @since 2.5 | |
| 971 | - */ | |
| 972 | - public static int lastOrdinalIndexOf(String str, String searchStr, int ordinal) { | |
| 973 | - return ordinalIndexOf(str, searchStr, ordinal, true); | |
| 974 | - } | |
| 975 | - | |
| 976 | - /** | |
| 977 | - * <p>Finds the first index within a String, handling <code>null</code>. | |
| 978 | - * This method uses {@link String#lastIndexOf(String, int)}.</p> | |
| 979 | - * | |
| 980 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 981 | - * A negative start position returns <code>-1</code>. | |
| 982 | - * An empty ("") search String always matches unless the start position is negative. | |
| 983 | - * A start position greater than the string length searches the whole string.</p> | |
| 984 | - * | |
| 985 | - * <pre> | |
| 986 | - * StringUtils.lastIndexOf(null, *, *) = -1 | |
| 987 | - * StringUtils.lastIndexOf(*, null, *) = -1 | |
| 988 | - * StringUtils.lastIndexOf("aabaabaa", "a", 8) = 7 | |
| 989 | - * StringUtils.lastIndexOf("aabaabaa", "b", 8) = 5 | |
| 990 | - * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4 | |
| 991 | - * StringUtils.lastIndexOf("aabaabaa", "b", 9) = 5 | |
| 992 | - * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1 | |
| 993 | - * StringUtils.lastIndexOf("aabaabaa", "a", 0) = 0 | |
| 994 | - * StringUtils.lastIndexOf("aabaabaa", "b", 0) = -1 | |
| 995 | - * </pre> | |
| 996 | - * | |
| 997 | - * @param str the String to check, may be null | |
| 998 | - * @param searchStr the String to find, may be null | |
| 999 | - * @param startPos the start position, negative treated as zero | |
| 1000 | - * @return the first index of the search String, | |
| 1001 | - * -1 if no match or <code>null</code> string input | |
| 1002 | - * @since 2.0 | |
| 1003 | - */ | |
| 1004 | - public static int lastIndexOf(String str, String searchStr, int startPos) { | |
| 1005 | - if (str == null || searchStr == null) { | |
| 1006 | - return INDEX_NOT_FOUND; | |
| 1007 | - } | |
| 1008 | - return str.lastIndexOf(searchStr, startPos); | |
| 1009 | - } | |
| 1010 | - | |
| 1011 | - /** | |
| 1012 | - * <p>Case in-sensitive find of the last index within a String.</p> | |
| 1013 | - * | |
| 1014 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 1015 | - * A negative start position returns <code>-1</code>. | |
| 1016 | - * An empty ("") search String always matches unless the start position is negative. | |
| 1017 | - * A start position greater than the string length searches the whole string.</p> | |
| 1018 | - * | |
| 1019 | - * <pre> | |
| 1020 | - * StringUtils.lastIndexOfIgnoreCase(null, *) = -1 | |
| 1021 | - * StringUtils.lastIndexOfIgnoreCase(*, null) = -1 | |
| 1022 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A") = 7 | |
| 1023 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B") = 5 | |
| 1024 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4 | |
| 1025 | - * </pre> | |
| 1026 | - * | |
| 1027 | - * @param str the String to check, may be null | |
| 1028 | - * @param searchStr the String to find, may be null | |
| 1029 | - * @return the first index of the search String, | |
| 1030 | - * -1 if no match or <code>null</code> string input | |
| 1031 | - * @since 2.5 | |
| 1032 | - */ | |
| 1033 | - public static int lastIndexOfIgnoreCase(String str, String searchStr) { | |
| 1034 | - if (str == null || searchStr == null) { | |
| 1035 | - return INDEX_NOT_FOUND; | |
| 1036 | - } | |
| 1037 | - return lastIndexOfIgnoreCase(str, searchStr, str.length()); | |
| 1038 | - } | |
| 1039 | - | |
| 1040 | - /** | |
| 1041 | - * <p>Case in-sensitive find of the last index within a String | |
| 1042 | - * from the specified position.</p> | |
| 1043 | - * | |
| 1044 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 1045 | - * A negative start position returns <code>-1</code>. | |
| 1046 | - * An empty ("") search String always matches unless the start position is negative. | |
| 1047 | - * A start position greater than the string length searches the whole string.</p> | |
| 1048 | - * | |
| 1049 | - * <pre> | |
| 1050 | - * StringUtils.lastIndexOfIgnoreCase(null, *, *) = -1 | |
| 1051 | - * StringUtils.lastIndexOfIgnoreCase(*, null, *) = -1 | |
| 1052 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8) = 7 | |
| 1053 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8) = 5 | |
| 1054 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4 | |
| 1055 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9) = 5 | |
| 1056 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1 | |
| 1057 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0) = 0 | |
| 1058 | - * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0) = -1 | |
| 1059 | - * </pre> | |
| 1060 | - * | |
| 1061 | - * @param str the String to check, may be null | |
| 1062 | - * @param searchStr the String to find, may be null | |
| 1063 | - * @param startPos the start position | |
| 1064 | - * @return the first index of the search String, | |
| 1065 | - * -1 if no match or <code>null</code> string input | |
| 1066 | - * @since 2.5 | |
| 1067 | - */ | |
| 1068 | - public static int lastIndexOfIgnoreCase(String str, String searchStr, int startPos) { | |
| 1069 | - if (str == null || searchStr == null) { | |
| 1070 | - return INDEX_NOT_FOUND; | |
| 1071 | - } | |
| 1072 | - if (startPos > (str.length() - searchStr.length())) { | |
| 1073 | - startPos = str.length() - searchStr.length(); | |
| 1074 | - } | |
| 1075 | - if (startPos < 0) { | |
| 1076 | - return INDEX_NOT_FOUND; | |
| 1077 | - } | |
| 1078 | - if (searchStr.length() == 0) { | |
| 1079 | - return startPos; | |
| 1080 | - } | |
| 1081 | - | |
| 1082 | - for (int i = startPos; i >= 0; i--) { | |
| 1083 | - if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) { | |
| 1084 | - return i; | |
| 1085 | - } | |
| 1086 | - } | |
| 1087 | - return INDEX_NOT_FOUND; | |
| 1088 | - } | |
| 1089 | - | |
| 1090 | - // Contains | |
| 1091 | - //----------------------------------------------------------------------- | |
| 1092 | - /** | |
| 1093 | - * <p>Checks if String contains a search character, handling <code>null</code>. | |
| 1094 | - * This method uses {@link String#indexOf(int)}.</p> | |
| 1095 | - * | |
| 1096 | - * <p>A <code>null</code> or empty ("") String will return <code>false</code>.</p> | |
| 1097 | - * | |
| 1098 | - * <pre> | |
| 1099 | - * StringUtils.contains(null, *) = false | |
| 1100 | - * StringUtils.contains("", *) = false | |
| 1101 | - * StringUtils.contains("abc", 'a') = true | |
| 1102 | - * StringUtils.contains("abc", 'z') = false | |
| 1103 | - * </pre> | |
| 1104 | - * | |
| 1105 | - * @param str the String to check, may be null | |
| 1106 | - * @param searchChar the character to find | |
| 1107 | - * @return true if the String contains the search character, | |
| 1108 | - * false if not or <code>null</code> string input | |
| 1109 | - * @since 2.0 | |
| 1110 | - */ | |
| 1111 | - public static boolean contains(String str, char searchChar) { | |
| 1112 | - if (isEmpty(str)) { | |
| 1113 | - return false; | |
| 1114 | - } | |
| 1115 | - return str.indexOf(searchChar) >= 0; | |
| 1116 | - } | |
| 1117 | - | |
| 1118 | - /** | |
| 1119 | - * <p>Checks if String contains a search String, handling <code>null</code>. | |
| 1120 | - * This method uses {@link String#indexOf(String)}.</p> | |
| 1121 | - * | |
| 1122 | - * <p>A <code>null</code> String will return <code>false</code>.</p> | |
| 1123 | - * | |
| 1124 | - * <pre> | |
| 1125 | - * StringUtils.contains(null, *) = false | |
| 1126 | - * StringUtils.contains(*, null) = false | |
| 1127 | - * StringUtils.contains("", "") = true | |
| 1128 | - * StringUtils.contains("abc", "") = true | |
| 1129 | - * StringUtils.contains("abc", "a") = true | |
| 1130 | - * StringUtils.contains("abc", "z") = false | |
| 1131 | - * </pre> | |
| 1132 | - * | |
| 1133 | - * @param str the String to check, may be null | |
| 1134 | - * @param searchStr the String to find, may be null | |
| 1135 | - * @return true if the String contains the search String, | |
| 1136 | - * false if not or <code>null</code> string input | |
| 1137 | - * @since 2.0 | |
| 1138 | - */ | |
| 1139 | - public static boolean contains(String str, String searchStr) { | |
| 1140 | - if (str == null || searchStr == null) { | |
| 1141 | - return false; | |
| 1142 | - } | |
| 1143 | - return str.indexOf(searchStr) >= 0; | |
| 1144 | - } | |
| 1145 | - | |
| 1146 | - /** | |
| 1147 | - * <p>Checks if String contains a search String irrespective of case, | |
| 1148 | - * handling <code>null</code>. Case-insensitivity is defined as by | |
| 1149 | - * {@link String#equalsIgnoreCase(String)}. | |
| 1150 | - * | |
| 1151 | - * <p>A <code>null</code> String will return <code>false</code>.</p> | |
| 1152 | - * | |
| 1153 | - * <pre> | |
| 1154 | - * StringUtils.contains(null, *) = false | |
| 1155 | - * StringUtils.contains(*, null) = false | |
| 1156 | - * StringUtils.contains("", "") = true | |
| 1157 | - * StringUtils.contains("abc", "") = true | |
| 1158 | - * StringUtils.contains("abc", "a") = true | |
| 1159 | - * StringUtils.contains("abc", "z") = false | |
| 1160 | - * StringUtils.contains("abc", "A") = true | |
| 1161 | - * StringUtils.contains("abc", "Z") = false | |
| 1162 | - * </pre> | |
| 1163 | - * | |
| 1164 | - * @param str the String to check, may be null | |
| 1165 | - * @param searchStr the String to find, may be null | |
| 1166 | - * @return true if the String contains the search String irrespective of | |
| 1167 | - * case or false if not or <code>null</code> string input | |
| 1168 | - */ | |
| 1169 | - public static boolean containsIgnoreCase(String str, String searchStr) { | |
| 1170 | - if (str == null || searchStr == null) { | |
| 1171 | - return false; | |
| 1172 | - } | |
| 1173 | - int len = searchStr.length(); | |
| 1174 | - int max = str.length() - len; | |
| 1175 | - for (int i = 0; i <= max; i++) { | |
| 1176 | - if (str.regionMatches(true, i, searchStr, 0, len)) { | |
| 1177 | - return true; | |
| 1178 | - } | |
| 1179 | - } | |
| 1180 | - return false; | |
| 1181 | - } | |
| 1182 | - | |
| 1183 | - | |
| 1184 | - // IndexOfAny strings | |
| 1185 | - //----------------------------------------------------------------------- | |
| 1186 | - /** | |
| 1187 | - * <p>Find the first index of any of a set of potential substrings.</p> | |
| 1188 | - * | |
| 1189 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 1190 | - * A <code>null</code> or zero length search array will return <code>-1</code>. | |
| 1191 | - * A <code>null</code> search array entry will be ignored, but a search | |
| 1192 | - * array containing "" will return <code>0</code> if <code>str</code> is not | |
| 1193 | - * null. This method uses {@link String#indexOf(String)}.</p> | |
| 1194 | - * | |
| 1195 | - * <pre> | |
| 1196 | - * StringUtils.indexOfAny(null, *) = -1 | |
| 1197 | - * StringUtils.indexOfAny(*, null) = -1 | |
| 1198 | - * StringUtils.indexOfAny(*, []) = -1 | |
| 1199 | - * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"]) = 2 | |
| 1200 | - * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"]) = 2 | |
| 1201 | - * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"]) = -1 | |
| 1202 | - * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1 | |
| 1203 | - * StringUtils.indexOfAny("zzabyycdxx", [""]) = 0 | |
| 1204 | - * StringUtils.indexOfAny("", [""]) = 0 | |
| 1205 | - * StringUtils.indexOfAny("", ["a"]) = -1 | |
| 1206 | - * </pre> | |
| 1207 | - * | |
| 1208 | - * @param str the String to check, may be null | |
| 1209 | - * @param searchStrs the Strings to search for, may be null | |
| 1210 | - * @return the first index of any of the searchStrs in str, -1 if no match | |
| 1211 | - */ | |
| 1212 | - public static int indexOfAny(String str, String[] searchStrs) { | |
| 1213 | - if ((str == null) || (searchStrs == null)) { | |
| 1214 | - return INDEX_NOT_FOUND; | |
| 1215 | - } | |
| 1216 | - int sz = searchStrs.length; | |
| 1217 | - | |
| 1218 | - // String's can't have a MAX_VALUEth index. | |
| 1219 | - int ret = Integer.MAX_VALUE; | |
| 1220 | - | |
| 1221 | - int tmp = 0; | |
| 1222 | - for (int i = 0; i < sz; i++) { | |
| 1223 | - String search = searchStrs[i]; | |
| 1224 | - if (search == null) { | |
| 1225 | - continue; | |
| 1226 | - } | |
| 1227 | - tmp = str.indexOf(search); | |
| 1228 | - if (tmp == INDEX_NOT_FOUND) { | |
| 1229 | - continue; | |
| 1230 | - } | |
| 1231 | - | |
| 1232 | - if (tmp < ret) { | |
| 1233 | - ret = tmp; | |
| 1234 | - } | |
| 1235 | - } | |
| 1236 | - | |
| 1237 | - return (ret == Integer.MAX_VALUE) ? INDEX_NOT_FOUND : ret; | |
| 1238 | - } | |
| 1239 | - | |
| 1240 | - /** | |
| 1241 | - * <p>Find the latest index of any of a set of potential substrings.</p> | |
| 1242 | - * | |
| 1243 | - * <p>A <code>null</code> String will return <code>-1</code>. | |
| 1244 | - * A <code>null</code> search array will return <code>-1</code>. | |
| 1245 | - * A <code>null</code> or zero length search array entry will be ignored, | |
| 1246 | - * but a search array containing "" will return the length of <code>str</code> | |
| 1247 | - * if <code>str</code> is not null. This method uses {@link String#indexOf(String)}</p> | |
| 1248 | - * | |
| 1249 | - * <pre> | |
| 1250 | - * StringUtils.lastIndexOfAny(null, *) = -1 | |
| 1251 | - * StringUtils.lastIndexOfAny(*, null) = -1 | |
| 1252 | - * StringUtils.lastIndexOfAny(*, []) = -1 | |
| 1253 | - * StringUtils.lastIndexOfAny(*, [null]) = -1 | |
| 1254 | - * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6 | |
| 1255 | - * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6 | |
| 1256 | - * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1 | |
| 1257 | - * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1 | |
| 1258 | - * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""]) = 10 | |
| 1259 | - * </pre> | |
| 1260 | - * | |
| 1261 | - * @param str the String to check, may be null | |
| 1262 | - * @param searchStrs the Strings to search for, may be null | |
| 1263 | - * @return the last index of any of the Strings, -1 if no match | |
| 1264 | - */ | |
| 1265 | - public static int lastIndexOfAny(String str, String[] searchStrs) { | |
| 1266 | - if ((str == null) || (searchStrs == null)) { | |
| 1267 | - return INDEX_NOT_FOUND; | |
| 1268 | - } | |
| 1269 | - int sz = searchStrs.length; | |
| 1270 | - int ret = INDEX_NOT_FOUND; | |
| 1271 | - int tmp = 0; | |
| 1272 | - for (int i = 0; i < sz; i++) { | |
| 1273 | - String search = searchStrs[i]; | |
| 1274 | - if (search == null) { | |
| 1275 | - continue; | |
| 1276 | - } | |
| 1277 | - tmp = str.lastIndexOf(search); | |
| 1278 | - if (tmp > ret) { | |
| 1279 | - ret = tmp; | |
| 1280 | - } | |
| 1281 | - } | |
| 1282 | - return ret; | |
| 1283 | - } | |
| 1284 | - | |
| 1285 | - // Substring | |
| 1286 | - //----------------------------------------------------------------------- | |
| 1287 | - /** | |
| 1288 | - * <p>Gets a substring from the specified String avoiding exceptions.</p> | |
| 1289 | - * | |
| 1290 | - * <p>A negative start position can be used to start <code>n</code> | |
| 1291 | - * characters from the end of the String.</p> | |
| 1292 | - * | |
| 1293 | - * <p>A <code>null</code> String will return <code>null</code>. | |
| 1294 | - * An empty ("") String will return "".</p> | |
| 1295 | - * | |
| 1296 | - * <pre> | |
| 1297 | - * StringUtils.substring(null, *) = null | |
| 1298 | - * StringUtils.substring("", *) = "" | |
| 1299 | - * StringUtils.substring("abc", 0) = "abc" | |
| 1300 | - * StringUtils.substring("abc", 2) = "c" | |
| 1301 | - * StringUtils.substring("abc", 4) = "" | |
| 1302 | - * StringUtils.substring("abc", -2) = "bc" | |
| 1303 | - * StringUtils.substring("abc", -4) = "abc" | |
| 1304 | - * </pre> | |
| 1305 | - * | |
| 1306 | - * @param str the String to get the substring from, may be null | |
| 1307 | - * @param start the position to start from, negative means | |
| 1308 | - * count back from the end of the String by this many characters | |
| 1309 | - * @return substring from start position, <code>null</code> if null String input | |
| 1310 | - */ | |
| 1311 | - public static String substring(String str, int start) { | |
| 1312 | - if (str == null) { | |
| 1313 | - return null; | |
| 1314 | - } | |
| 1315 | - | |
| 1316 | - // handle negatives, which means last n characters | |
| 1317 | - if (start < 0) { | |
| 1318 | - start = str.length() + start; // remember start is negative | |
| 1319 | - } | |
| 1320 | - | |
| 1321 | - if (start < 0) { | |
| 1322 | - start = 0; | |
| 1323 | - } | |
| 1324 | - if (start > str.length()) { | |
| 1325 | - return EMPTY; | |
| 1326 | - } | |
| 1327 | - | |
| 1328 | - return str.substring(start); | |
| 1329 | - } | |
| 1330 | - | |
| 1331 | - /** | |
| 1332 | - * <p>Gets a substring from the specified String avoiding exceptions.</p> | |
| 1333 | - * | |
| 1334 | - * <p>A negative start position can be used to start/end <code>n</code> | |
| 1335 | - * characters from the end of the String.</p> | |
| 1336 | - * | |
| 1337 | - * <p>The returned substring starts with the character in the <code>start</code> | |
| 1338 | - * position and ends before the <code>end</code> position. All position counting is | |
| 1339 | - * zero-based -- i.e., to start at the beginning of the string use | |
| 1340 | - * <code>start = 0</code>. Negative start and end positions can be used to | |
| 1341 | - * specify offsets relative to the end of the String.</p> | |
| 1342 | - * | |
| 1343 | - * <p>If <code>start</code> is not strictly to the left of <code>end</code>, "" | |
| 1344 | - * is returned.</p> | |
| 1345 | - * | |
| 1346 | - * <pre> | |
| 1347 | - * StringUtils.substring(null, *, *) = null | |
| 1348 | - * StringUtils.substring("", * , *) = ""; | |
| 1349 | - * StringUtils.substring("abc", 0, 2) = "ab" | |
| 1350 | - * StringUtils.substring("abc", 2, 0) = "" | |
| 1351 | - * StringUtils.substring("abc", 2, 4) = "c" | |
| 1352 | - * StringUtils.substring("abc", 4, 6) = "" | |
| 1353 | - * StringUtils.substring("abc", 2, 2) = "" | |
| 1354 | - * StringUtils.substring("abc", -2, -1) = "b" | |
| 1355 | - * StringUtils.substring("abc", -4, 2) = "ab" | |
| 1356 | - * </pre> | |
| 1357 | - * | |
| 1358 | - * @param str the String to get the substring from, may be null | |
| 1359 | - * @param start the position to start from, negative means | |
| 1360 | - * count back from the end of the String by this many characters | |
| 1361 | - * @param end the position to end at (exclusive), negative means | |
| 1362 | - * count back from the end of the String by this many characters | |
| 1363 | - * @return substring from start position to end positon, | |
| 1364 | - * <code>null</code> if null String input | |
| 1365 | - */ | |
| 1366 | - public static String substring(String str, int start, int end) { | |
| 1367 | - if (str == null) { | |
| 1368 | - return null; | |
| 1369 | - } | |
| 1370 | - | |
| 1371 | - // handle negatives | |
| 1372 | - if (end < 0) { | |
| 1373 | - end = str.length() + end; // remember end is negative | |
| 1374 | - } | |
| 1375 | - if (start < 0) { | |
| 1376 | - start = str.length() + start; // remember start is negative | |
| 1377 | - } | |
| 1378 | - | |
| 1379 | - // check length next | |
| 1380 | - if (end > str.length()) { | |
| 1381 | - end = str.length(); | |
| 1382 | - } | |
| 1383 | - | |
| 1384 | - // if start is greater than end, return "" | |
| 1385 | - if (start > end) { | |
| 1386 | - return EMPTY; | |
| 1387 | - } | |
| 1388 | - | |
| 1389 | - if (start < 0) { | |
| 1390 | - start = 0; | |
| 1391 | - } | |
| 1392 | - if (end < 0) { | |
| 1393 | - end = 0; | |
| 1394 | - } | |
| 1395 | - | |
| 1396 | - return str.substring(start, end); | |
| 1397 | - } | |
| 1398 | - | |
| 1399 | - // Left/Right/Mid | |
| 1400 | - //----------------------------------------------------------------------- | |
| 1401 | - /** | |
| 1402 | - * <p>Gets the leftmost <code>len</code> characters of a String.</p> | |
| 1403 | - * | |
| 1404 | - * <p>If <code>len</code> characters are not available, or the | |
| 1405 | - * String is <code>null</code>, the String will be returned without | |
| 1406 | - * an exception. An empty String is returned if len is negative.</p> | |
| 1407 | - * | |
| 1408 | - * <pre> | |
| 1409 | - * StringUtils.left(null, *) = null | |
| 1410 | - * StringUtils.left(*, -ve) = "" | |
| 1411 | - * StringUtils.left("", *) = "" | |
| 1412 | - * StringUtils.left("abc", 0) = "" | |
| 1413 | - * StringUtils.left("abc", 2) = "ab" | |
| 1414 | - * StringUtils.left("abc", 4) = "abc" | |
| 1415 | - * </pre> | |
| 1416 | - * | |
| 1417 | - * @param str the String to get the leftmost characters from, may be null | |
| 1418 | - * @param len the length of the required String | |
| 1419 | - * @return the leftmost characters, <code>null</code> if null String input | |
| 1420 | - */ | |
| 1421 | - public static String left(String str, int len) { | |
| 1422 | - if (str == null) { | |
| 1423 | - return null; | |
| 1424 | - } | |
| 1425 | - if (len < 0) { | |
| 1426 | - return EMPTY; | |
| 1427 | - } | |
| 1428 | - if (str.length() <= len) { | |
| 1429 | - return str; | |
| 1430 | - } | |
| 1431 | - return str.substring(0, len); | |
| 1432 | - } | |
| 1433 | - | |
| 1434 | - /** | |
| 1435 | - * <p>Gets the rightmost <code>len</code> characters of a String.</p> | |
| 1436 | - * | |
| 1437 | - * <p>If <code>len</code> characters are not available, or the String | |
| 1438 | - * is <code>null</code>, the String will be returned without an | |
| 1439 | - * an exception. An empty String is returned if len is negative.</p> | |
| 1440 | - * | |
| 1441 | - * <pre> | |
| 1442 | - * StringUtils.right(null, *) = null | |
| 1443 | - * StringUtils.right(*, -ve) = "" | |
| 1444 | - * StringUtils.right("", *) = "" | |
| 1445 | - * StringUtils.right("abc", 0) = "" | |
| 1446 | - * StringUtils.right("abc", 2) = "bc" | |
| 1447 | - * StringUtils.right("abc", 4) = "abc" | |
| 1448 | - * </pre> | |
| 1449 | - * | |
| 1450 | - * @param str the String to get the rightmost characters from, may be null | |
| 1451 | - * @param len the length of the required String | |
| 1452 | - * @return the rightmost characters, <code>null</code> if null String input | |
| 1453 | - */ | |
| 1454 | - public static String right(String str, int len) { | |
| 1455 | - if (str == null) { | |
| 1456 | - return null; | |
| 1457 | - } | |
| 1458 | - if (len < 0) { | |
| 1459 | - return EMPTY; | |
| 1460 | - } | |
| 1461 | - if (str.length() <= len) { | |
| 1462 | - return str; | |
| 1463 | - } | |
| 1464 | - return str.substring(str.length() - len); | |
| 1465 | - } | |
| 1466 | - | |
| 1467 | - /** | |
| 1468 | - * <p>Gets <code>len</code> characters from the middle of a String.</p> | |
| 1469 | - * | |
| 1470 | - * <p>If <code>len</code> characters are not available, the remainder | |
| 1471 | - * of the String will be returned without an exception. If the | |
| 1472 | - * String is <code>null</code>, <code>null</code> will be returned. | |
| 1473 | - * An empty String is returned if len is negative or exceeds the | |
| 1474 | - * length of <code>str</code>.</p> | |
| 1475 | - * | |
| 1476 | - * <pre> | |
| 1477 | - * StringUtils.mid(null, *, *) = null | |
| 1478 | - * StringUtils.mid(*, *, -ve) = "" | |
| 1479 | - * StringUtils.mid("", 0, *) = "" | |
| 1480 | - * StringUtils.mid("abc", 0, 2) = "ab" | |
| 1481 | - * StringUtils.mid("abc", 0, 4) = "abc" | |
| 1482 | - * StringUtils.mid("abc", 2, 4) = "c" | |
| 1483 | - * StringUtils.mid("abc", 4, 2) = "" | |
| 1484 | - * StringUtils.mid("abc", -2, 2) = "ab" | |
| 1485 | - * </pre> | |
| 1486 | - * | |
| 1487 | - * @param str the String to get the characters from, may be null | |
| 1488 | - * @param pos the position to start from, negative treated as zero | |
| 1489 | - * @param len the length of the required String | |
| 1490 | - * @return the middle characters, <code>null</code> if null String input | |
| 1491 | - */ | |
| 1492 | - public static String mid(String str, int pos, int len) { | |
| 1493 | - if (str == null) { | |
| 1494 | - return null; | |
| 1495 | - } | |
| 1496 | - if (len < 0 || pos > str.length()) { | |
| 1497 | - return EMPTY; | |
| 1498 | - } | |
| 1499 | - if (pos < 0) { | |
| 1500 | - pos = 0; | |
| 1501 | - } | |
| 1502 | - if (str.length() <= (pos + len)) { | |
| 1503 | - return str.substring(pos); | |
| 1504 | - } | |
| 1505 | - return str.substring(pos, pos + len); | |
| 1506 | - } | |
| 1507 | - | |
| 1508 | - // SubStringAfter/SubStringBefore | |
| 1509 | - //----------------------------------------------------------------------- | |
| 1510 | - /** | |
| 1511 | - * <p>Gets the substring before the first occurrence of a separator. | |
| 1512 | - * The separator is not returned.</p> | |
| 1513 | - * | |
| 1514 | - * <p>A <code>null</code> string input will return <code>null</code>. | |
| 1515 | - * An empty ("") string input will return the empty string. | |
| 1516 | - * A <code>null</code> separator will return the input string.</p> | |
| 1517 | - * | |
| 1518 | - * <p>If nothing is found, the string input is returned.</p> | |
| 1519 | - * | |
| 1520 | - * <pre> | |
| 1521 | - * StringUtils.substringBefore(null, *) = null | |
| 1522 | - * StringUtils.substringBefore("", *) = "" | |
| 1523 | - * StringUtils.substringBefore("abc", "a") = "" | |
| 1524 | - * StringUtils.substringBefore("abcba", "b") = "a" | |
| 1525 | - * StringUtils.substringBefore("abc", "c") = "ab" | |
| 1526 | - * StringUtils.substringBefore("abc", "d") = "abc" | |
| 1527 | - * StringUtils.substringBefore("abc", "") = "" | |
| 1528 | - * StringUtils.substringBefore("abc", null) = "abc" | |
| 1529 | - * </pre> | |
| 1530 | - * | |
| 1531 | - * @param str the String to get a substring from, may be null | |
| 1532 | - * @param separator the String to search for, may be null | |
| 1533 | - * @return the substring before the first occurrence of the separator, | |
| 1534 | - * <code>null</code> if null String input | |
| 1535 | - * @since 2.0 | |
| 1536 | - */ | |
| 1537 | - public static String substringBefore(String str, String separator) { | |
| 1538 | - if (isEmpty(str) || separator == null) { | |
| 1539 | - return str; | |
| 1540 | - } | |
| 1541 | - if (separator.length() == 0) { | |
| 1542 | - return EMPTY; | |
| 1543 | - } | |
| 1544 | - int pos = str.indexOf(separator); | |
| 1545 | - if (pos == INDEX_NOT_FOUND) { | |
| 1546 | - return str; | |
| 1547 | - } | |
| 1548 | - return str.substring(0, pos); | |
| 1549 | - } | |
| 1550 | - | |
| 1551 | - /** | |
| 1552 | - * <p>Gets the substring after the first occurrence of a separator. | |
| 1553 | - * The separator is not returned.</p> | |
| 1554 | - * | |
| 1555 | - * <p>A <code>null</code> string input will return <code>null</code>. | |
| 1556 | - * An empty ("") string input will return the empty string. | |
| 1557 | - * A <code>null</code> separator will return the empty string if the | |
| 1558 | - * input string is not <code>null</code>.</p> | |
| 1559 | - * | |
| 1560 | - * <p>If nothing is found, the empty string is returned.</p> | |
| 1561 | - * | |
| 1562 | - * <pre> | |
| 1563 | - * StringUtils.substringAfter(null, *) = null | |
| 1564 | - * StringUtils.substringAfter("", *) = "" | |
| 1565 | - * StringUtils.substringAfter(*, null) = "" | |
| 1566 | - * StringUtils.substringAfter("abc", "a") = "bc" | |
| 1567 | - * StringUtils.substringAfter("abcba", "b") = "cba" | |
| 1568 | - * StringUtils.substringAfter("abc", "c") = "" | |
| 1569 | - * StringUtils.substringAfter("abc", "d") = "" | |
| 1570 | - * StringUtils.substringAfter("abc", "") = "abc" | |
| 1571 | - * </pre> | |
| 1572 | - * | |
| 1573 | - * @param str the String to get a substring from, may be null | |
| 1574 | - * @param separator the String to search for, may be null | |
| 1575 | - * @return the substring after the first occurrence of the separator, | |
| 1576 | - * <code>null</code> if null String input | |
| 1577 | - * @since 2.0 | |
| 1578 | - */ | |
| 1579 | - public static String substringAfter(String str, String separator) { | |
| 1580 | - if (isEmpty(str)) { | |
| 1581 | - return str; | |
| 1582 | - } | |
| 1583 | - if (separator == null) { | |
| 1584 | - return EMPTY; | |
| 1585 | - } | |
| 1586 | - int pos = str.indexOf(separator); | |
| 1587 | - if (pos == INDEX_NOT_FOUND) { | |
| 1588 | - return EMPTY; | |
| 1589 | - } | |
| 1590 | - return str.substring(pos + separator.length()); | |
| 1591 | - } | |
| 1592 | - | |
| 1593 | - /** | |
| 1594 | - * <p>Gets the substring before the last occurrence of a separator. | |
| 1595 | - * The separator is not returned.</p> | |
| 1596 | - * | |
| 1597 | - * <p>A <code>null</code> string input will return <code>null</code>. | |
| 1598 | - * An empty ("") string input will return the empty string. | |
| 1599 | - * An empty or <code>null</code> separator will return the input string.</p> | |
| 1600 | - * | |
| 1601 | - * <p>If nothing is found, the string input is returned.</p> | |
| 1602 | - * | |
| 1603 | - * <pre> | |
| 1604 | - * StringUtils.substringBeforeLast(null, *) = null | |
| 1605 | - * StringUtils.substringBeforeLast("", *) = "" | |
| 1606 | - * StringUtils.substringBeforeLast("abcba", "b") = "abc" | |
| 1607 | - * StringUtils.substringBeforeLast("abc", "c") = "ab" | |
| 1608 | - * StringUtils.substringBeforeLast("a", "a") = "" | |
| 1609 | - * StringUtils.substringBeforeLast("a", "z") = "a" | |
| 1610 | - * StringUtils.substringBeforeLast("a", null) = "a" | |
| 1611 | - * StringUtils.substringBeforeLast("a", "") = "a" | |
| 1612 | - * </pre> | |
| 1613 | - * | |
| 1614 | - * @param str the String to get a substring from, may be null | |
| 1615 | - * @param separator the String to search for, may be null | |
| 1616 | - * @return the substring before the last occurrence of the separator, | |
| 1617 | - * <code>null</code> if null String input | |
| 1618 | - * @since 2.0 | |
| 1619 | - */ | |
| 1620 | - public static String substringBeforeLast(String str, String separator) { | |
| 1621 | - if (isEmpty(str) || isEmpty(separator)) { | |
| 1622 | - return str; | |
| 1623 | - } | |
| 1624 | - int pos = str.lastIndexOf(separator); | |
| 1625 | - if (pos == INDEX_NOT_FOUND) { | |
| 1626 | - return str; | |
| 1627 | - } | |
| 1628 | - return str.substring(0, pos); | |
| 1629 | - } | |
| 1630 | - | |
| 1631 | - /** | |
| 1632 | - * <p>Gets the substring after the last occurrence of a separator. | |
| 1633 | - * The separator is not returned.</p> | |
| 1634 | - * | |
| 1635 | - * <p>A <code>null</code> string input will return <code>null</code>. | |
| 1636 | - * An empty ("") string input will return the empty string. | |
| 1637 | - * An empty or <code>null</code> separator will return the empty string if | |
| 1638 | - * the input string is not <code>null</code>.</p> | |
| 1639 | - * | |
| 1640 | - * <p>If nothing is found, the empty string is returned.</p> | |
| 1641 | - * | |
| 1642 | - * <pre> | |
| 1643 | - * StringUtils.substringAfterLast(null, *) = null | |
| 1644 | - * StringUtils.substringAfterLast("", *) = "" | |
| 1645 | - * StringUtils.substringAfterLast(*, "") = "" | |
| 1646 | - * StringUtils.substringAfterLast(*, null) = "" | |
| 1647 | - * StringUtils.substringAfterLast("abc", "a") = "bc" | |
| 1648 | - * StringUtils.substringAfterLast("abcba", "b") = "a" | |
| 1649 | - * StringUtils.substringAfterLast("abc", "c") = "" | |
| 1650 | - * StringUtils.substringAfterLast("a", "a") = "" | |
| 1651 | - * StringUtils.substringAfterLast("a", "z") = "" | |
| 1652 | - * </pre> | |
| 1653 | - * | |
| 1654 | - * @param str the String to get a substring from, may be null | |
| 1655 | - * @param separator the String to search for, may be null | |
| 1656 | - * @return the substring after the last occurrence of the separator, | |
| 1657 | - * <code>null</code> if null String input | |
| 1658 | - * @since 2.0 | |
| 1659 | - */ | |
| 1660 | - public static String substringAfterLast(String str, String separator) { | |
| 1661 | - if (isEmpty(str)) { | |
| 1662 | - return str; | |
| 1663 | - } | |
| 1664 | - if (isEmpty(separator)) { | |
| 1665 | - return EMPTY; | |
| 1666 | - } | |
| 1667 | - int pos = str.lastIndexOf(separator); | |
| 1668 | - if (pos == INDEX_NOT_FOUND || pos == (str.length() - separator.length())) { | |
| 1669 | - return EMPTY; | |
| 1670 | - } | |
| 1671 | - return str.substring(pos + separator.length()); | |
| 1672 | - } | |
| 1673 | - | |
| 1674 | - // Substring between | |
| 1675 | - //----------------------------------------------------------------------- | |
| 1676 | - /** | |
| 1677 | - * <p>Gets the String that is nested in between two instances of the | |
| 1678 | - * same String.</p> | |
| 1679 | - * | |
| 1680 | - * <p>A <code>null</code> input String returns <code>null</code>. | |
| 1681 | - * A <code>null</code> tag returns <code>null</code>.</p> | |
| 1682 | - * | |
| 1683 | - * <pre> | |
| 1684 | - * StringUtils.substringBetween(null, *) = null | |
| 1685 | - * StringUtils.substringBetween("", "") = "" | |
| 1686 | - * StringUtils.substringBetween("", "tag") = null | |
| 1687 | - * StringUtils.substringBetween("tagabctag", null) = null | |
| 1688 | - * StringUtils.substringBetween("tagabctag", "") = "" | |
| 1689 | - * StringUtils.substringBetween("tagabctag", "tag") = "abc" | |
| 1690 | - * </pre> | |
| 1691 | - * | |
| 1692 | - * @param str the String containing the substring, may be null | |
| 1693 | - * @param tag the String before and after the substring, may be null | |
| 1694 | - * @return the substring, <code>null</code> if no match | |
| 1695 | - * @since 2.0 | |
| 1696 | - */ | |
| 1697 | - public static String substringBetween(String str, String tag) { | |
| 1698 | - return substringBetween(str, tag, tag); | |
| 1699 | - } | |
| 1700 | - | |
| 1701 | - /** | |
| 1702 | - * <p>Gets the String that is nested in between two Strings. | |
| 1703 | - * Only the first match is returned.</p> | |
| 1704 | - * | |
| 1705 | - * <p>A <code>null</code> input String returns <code>null</code>. | |
| 1706 | - * A <code>null</code> open/close returns <code>null</code> (no match). | |
| 1707 | - * An empty ("") open and close returns an empty string.</p> | |
| 1708 | - * | |
| 1709 | - * <pre> | |
| 1710 | - * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b" | |
| 1711 | - * StringUtils.substringBetween(null, *, *) = null | |
| 1712 | - * StringUtils.substringBetween(*, null, *) = null | |
| 1713 | - * StringUtils.substringBetween(*, *, null) = null | |
| 1714 | - * StringUtils.substringBetween("", "", "") = "" | |
| 1715 | - * StringUtils.substringBetween("", "", "]") = null | |
| 1716 | - * StringUtils.substringBetween("", "[", "]") = null | |
| 1717 | - * StringUtils.substringBetween("yabcz", "", "") = "" | |
| 1718 | - * StringUtils.substringBetween("yabcz", "y", "z") = "abc" | |
| 1719 | - * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc" | |
| 1720 | - * </pre> | |
| 1721 | - * | |
| 1722 | - * @param str the String containing the substring, may be null | |
| 1723 | - * @param open the String before the substring, may be null | |
| 1724 | - * @param close the String after the substring, may be null | |
| 1725 | - * @return the substring, <code>null</code> if no match | |
| 1726 | - * @since 2.0 | |
| 1727 | - */ | |
| 1728 | - public static String substringBetween(String str, String open, String close) { | |
| 1729 | - if (str == null || open == null || close == null) { | |
| 1730 | - return null; | |
| 1731 | - } | |
| 1732 | - int start = str.indexOf(open); | |
| 1733 | - if (start != INDEX_NOT_FOUND) { | |
| 1734 | - int end = str.indexOf(close, start + open.length()); | |
| 1735 | - if (end != INDEX_NOT_FOUND) { | |
| 1736 | - return str.substring(start + open.length(), end); | |
| 1737 | - } | |
| 1738 | - } | |
| 1739 | - return null; | |
| 1740 | - } | |
| 1741 | - | |
| 1742 | -} | |
| 1743 | 0 | \ No newline at end of file |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java
| 1 | 1 | package cn.iocoder.yudao.module.system.controller.admin.captcha; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 4 | 5 | import com.anji.captcha.model.common.ResponseModel; |
| 5 | 6 | import com.anji.captcha.model.vo.CaptchaVO; |
| 7 | +import com.anji.captcha.service.CaptchaService; | |
| 6 | 8 | import io.swagger.annotations.Api; |
| 7 | 9 | import io.swagger.annotations.ApiOperation; |
| 8 | 10 | import org.springframework.web.bind.annotation.PostMapping; |
| ... | ... | @@ -10,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody; |
| 10 | 12 | import org.springframework.web.bind.annotation.RequestMapping; |
| 11 | 13 | import org.springframework.web.bind.annotation.RestController; |
| 12 | 14 | |
| 15 | +import javax.annotation.Resource; | |
| 13 | 16 | import javax.annotation.security.PermitAll; |
| 14 | 17 | import javax.servlet.http.HttpServletRequest; |
| 15 | 18 | |
| ... | ... | @@ -24,24 +27,46 @@ import javax.servlet.http.HttpServletRequest; |
| 24 | 27 | @Api(tags = "管理后台 - 验证码") |
| 25 | 28 | @RestController("adminCaptchaController") |
| 26 | 29 | @RequestMapping("/system/captcha") |
| 27 | -public class CaptchaController extends com.anji.captcha.controller.CaptchaController { | |
| 30 | +public class CaptchaController { | |
| 31 | + | |
| 32 | + @Resource | |
| 33 | + private CaptchaService captchaService; | |
| 28 | 34 | |
| 29 | 35 | @PostMapping({"/get"}) |
| 30 | 36 | @ApiOperation("获得验证码") |
| 31 | 37 | @PermitAll |
| 32 | 38 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 33 | - @Override | |
| 34 | 39 | public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) { |
| 35 | - return super.get(data, request); | |
| 40 | + assert request.getRemoteHost() != null; | |
| 41 | + data.setBrowserInfo(getRemoteId(request)); | |
| 42 | + return captchaService.get(data); | |
| 36 | 43 | } |
| 37 | 44 | |
| 38 | 45 | @PostMapping("/check") |
| 39 | 46 | @ApiOperation("校验验证码") |
| 40 | 47 | @PermitAll |
| 41 | 48 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 42 | - @Override | |
| 43 | 49 | public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) { |
| 44 | - return super.check(data, request); | |
| 50 | + data.setBrowserInfo(getRemoteId(request)); | |
| 51 | + return captchaService.check(data); | |
| 52 | + } | |
| 53 | + | |
| 54 | + public static String getRemoteId(HttpServletRequest request) { | |
| 55 | + String xfwd = request.getHeader("X-Forwarded-For"); | |
| 56 | + String ip = getRemoteIpFromXfwd(xfwd); | |
| 57 | + String ua = request.getHeader("user-agent"); | |
| 58 | + if (StrUtil.isNotBlank(ip)) { | |
| 59 | + return ip + ua; | |
| 60 | + } | |
| 61 | + return request.getRemoteAddr() + ua; | |
| 62 | + } | |
| 63 | + | |
| 64 | + private static String getRemoteIpFromXfwd(String xfwd) { | |
| 65 | + if (StrUtil.isNotBlank(xfwd)) { | |
| 66 | + String[] ipList = xfwd.split(","); | |
| 67 | + return StrUtil.trim(ipList[0]); | |
| 68 | + } | |
| 69 | + return null; | |
| 45 | 70 | } |
| 46 | 71 | |
| 47 | 72 | } | ... | ... |