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
| @@ -21,6 +21,7 @@ | @@ -21,6 +21,7 @@ | ||
| 21 | <dependency> | 21 | <dependency> |
| 22 | <groupId>org.springframework.boot</groupId> | 22 | <groupId>org.springframework.boot</groupId> |
| 23 | <artifactId>spring-boot-starter</artifactId> | 23 | <artifactId>spring-boot-starter</artifactId> |
| 24 | + <scope>provided</scope> | ||
| 24 | </dependency> | 25 | </dependency> |
| 25 | 26 | ||
| 26 | <dependency> | 27 | <dependency> |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/config/AjCaptchaServiceAutoConfiguration.java
| 1 | package com.anji.captcha.config; | 1 | package com.anji.captcha.config; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 3 | import com.anji.captcha.model.common.Const; | 4 | import com.anji.captcha.model.common.Const; |
| 4 | import com.anji.captcha.properties.AjCaptchaProperties; | 5 | import com.anji.captcha.properties.AjCaptchaProperties; |
| 5 | import com.anji.captcha.service.CaptchaService; | 6 | import com.anji.captcha.service.CaptchaService; |
| 6 | import com.anji.captcha.service.impl.CaptchaServiceFactory; | 7 | import com.anji.captcha.service.impl.CaptchaServiceFactory; |
| 7 | import com.anji.captcha.util.ImageUtils; | 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 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
| 12 | import org.springframework.context.annotation.Bean; | 11 | import org.springframework.context.annotation.Bean; |
| 13 | import org.springframework.context.annotation.Configuration; | 12 | import org.springframework.context.annotation.Configuration; |
| @@ -21,15 +20,14 @@ import java.util.HashMap; | @@ -21,15 +20,14 @@ import java.util.HashMap; | ||
| 21 | import java.util.Map; | 20 | import java.util.Map; |
| 22 | import java.util.Properties; | 21 | import java.util.Properties; |
| 23 | 22 | ||
| 23 | +@Slf4j | ||
| 24 | @Configuration | 24 | @Configuration |
| 25 | public class AjCaptchaServiceAutoConfiguration { | 25 | public class AjCaptchaServiceAutoConfiguration { |
| 26 | 26 | ||
| 27 | - private static Logger logger = LoggerFactory.getLogger(AjCaptchaServiceAutoConfiguration.class); | ||
| 28 | - | ||
| 29 | @Bean | 27 | @Bean |
| 30 | @ConditionalOnMissingBean | 28 | @ConditionalOnMissingBean |
| 31 | public CaptchaService captchaService(AjCaptchaProperties prop) { | 29 | public CaptchaService captchaService(AjCaptchaProperties prop) { |
| 32 | - logger.info("自定义配置项:{}", prop.toString()); | 30 | + log.info("自定义配置项:{}", prop.toString()); |
| 33 | Properties config = new Properties(); | 31 | Properties config = new Properties(); |
| 34 | config.put(Const.CAPTCHA_CACHETYPE, prop.getCacheType().name()); | 32 | config.put(Const.CAPTCHA_CACHETYPE, prop.getCacheType().name()); |
| 35 | config.put(Const.CAPTCHA_WATER_MARK, prop.getWaterMark()); | 33 | config.put(Const.CAPTCHA_WATER_MARK, prop.getWaterMark()); |
| @@ -57,14 +55,13 @@ public class AjCaptchaServiceAutoConfiguration { | @@ -57,14 +55,13 @@ public class AjCaptchaServiceAutoConfiguration { | ||
| 57 | config.put(Const.CAPTCHA_FONT_STYLE, prop.getFontStyle() + ""); | 55 | config.put(Const.CAPTCHA_FONT_STYLE, prop.getFontStyle() + ""); |
| 58 | config.put(Const.CAPTCHA_WORD_COUNT, prop.getClickWordCount() + ""); | 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 | //自定义resources目录下初始化底图 | 60 | //自定义resources目录下初始化底图 |
| 63 | config.put(Const.CAPTCHA_INIT_ORIGINAL, "true"); | 61 | config.put(Const.CAPTCHA_INIT_ORIGINAL, "true"); |
| 64 | initializeBaseMap(prop.getJigsaw(), prop.getPicClick()); | 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 | private static void initializeBaseMap(String jigsaw, String picClick) { | 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,14 +8,13 @@ import org.springframework.context.annotation.Configuration; | ||
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | * 存储策略自动配置. | 10 | * 存储策略自动配置. |
| 11 | - * | ||
| 12 | */ | 11 | */ |
| 13 | @Configuration | 12 | @Configuration |
| 14 | public class AjCaptchaStorageAutoConfiguration { | 13 | public class AjCaptchaStorageAutoConfiguration { |
| 15 | 14 | ||
| 16 | @Bean(name = "AjCaptchaCacheService") | 15 | @Bean(name = "AjCaptchaCacheService") |
| 17 | - public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties){ | ||
| 18 | - //缓存类型redis/local/.... | 16 | + public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties) { |
| 17 | + // 缓存类型redis/local/.... | ||
| 19 | return CaptchaServiceFactory.getCache(ajCaptchaProperties.getCacheType().name()); | 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 | package com.anji.captcha.model.common; | 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 | public enum CaptchaBaseMapEnum { | 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 | //根据codeValue获取枚举 | 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 | return null; | 26 | return null; |
| 29 | } | 27 | } |
| 30 | 28 | ||
| 31 | //根据codeValue获取描述 | 29 | //根据codeValue获取描述 |
| 32 | - public static String getCodeDescByCodeBalue(String codeValue){ | 30 | + public static String getCodeDescByCodeBalue(String codeValue) { |
| 33 | CaptchaBaseMapEnum enumItem = parseFromCodeValue(codeValue); | 31 | CaptchaBaseMapEnum enumItem = parseFromCodeValue(codeValue); |
| 34 | return enumItem == null ? "" : enumItem.getCodeDesc(); | 32 | return enumItem == null ? "" : enumItem.getCodeDesc(); |
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | //验证codeValue是否有效 | 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 | StringBuffer buffer = new StringBuffer(); | 42 | StringBuffer buffer = new StringBuffer(); |
| 43 | - for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()){ | 43 | + for (CaptchaBaseMapEnum e : CaptchaBaseMapEnum.values()) { |
| 44 | buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); | 44 | buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); |
| 45 | } | 45 | } |
| 46 | buffer.deleteCharAt(buffer.lastIndexOf(",")); | 46 | buffer.deleteCharAt(buffer.lastIndexOf(",")); |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/model/common/CaptchaTypeEnum.java
| 1 | package com.anji.captcha.model.common; | 1 | package com.anji.captcha.model.common; |
| 2 | 2 | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Getter; | ||
| 5 | + | ||
| 6 | +@Getter | ||
| 7 | +@AllArgsConstructor | ||
| 3 | public enum CaptchaTypeEnum { | 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 | //根据codeValue获取枚举 | 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 | return null; | 32 | return null; |
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | //根据codeValue获取描述 | 35 | //根据codeValue获取描述 |
| 38 | - public static String getCodeDescByCodeBalue(String codeValue){ | 36 | + public static String getCodeDescByCodeBalue(String codeValue) { |
| 39 | CaptchaTypeEnum enumItem = parseFromCodeValue(codeValue); | 37 | CaptchaTypeEnum enumItem = parseFromCodeValue(codeValue); |
| 40 | return enumItem == null ? "" : enumItem.getCodeDesc(); | 38 | return enumItem == null ? "" : enumItem.getCodeDesc(); |
| 41 | } | 39 | } |
| 42 | 40 | ||
| 43 | //验证codeValue是否有效 | 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 | buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); | 50 | buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", "); |
| 51 | } | 51 | } |
| 52 | buffer.deleteCharAt(buffer.lastIndexOf(",")); | 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,7 +6,7 @@ package com.anji.captcha.model.common; | ||
| 6 | public interface Const { | 6 | public interface Const { |
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | - *滑块底图路径 | 9 | + * 滑块底图路径 |
| 10 | */ | 10 | */ |
| 11 | String ORIGINAL_PATH_JIGSAW = "captcha.captchaOriginalPath.jigsaw"; | 11 | String ORIGINAL_PATH_JIGSAW = "captcha.captchaOriginalPath.jigsaw"; |
| 12 | 12 | ||
| @@ -29,8 +29,8 @@ public interface Const { | @@ -29,8 +29,8 @@ public interface Const { | ||
| 29 | * 点选文字验证码的文字字体(宋体) | 29 | * 点选文字验证码的文字字体(宋体) |
| 30 | */ | 30 | */ |
| 31 | String CAPTCHA_FONT_TYPE = "captcha.font.type"; | 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 | * 验证码类型default两种都实例化。 | 36 | * 验证码类型default两种都实例化。 |
| @@ -72,41 +72,41 @@ public interface Const { | @@ -72,41 +72,41 @@ public interface Const { | ||
| 72 | */ | 72 | */ |
| 73 | String CAPTCHA_TIMING_CLEAR_SECOND = "captcha.timing.clear"; | 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,16 +6,23 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.model.common; | 7 | package com.anji.captcha.model.common; |
| 8 | 8 | ||
| 9 | +import lombok.AllArgsConstructor; | ||
| 10 | +import lombok.Getter; | ||
| 11 | + | ||
| 9 | import java.text.MessageFormat; | 12 | import java.text.MessageFormat; |
| 10 | 13 | ||
| 11 | /** | 14 | /** |
| 12 | * 返回应答码 | 15 | * 返回应答码 |
| 13 | - * @author | ||
| 14 | * | 16 | * |
| 17 | + * @author | ||
| 15 | */ | 18 | */ |
| 19 | +@AllArgsConstructor | ||
| 20 | +@Getter | ||
| 16 | public enum RepCodeEnum { | 21 | public enum RepCodeEnum { |
| 17 | 22 | ||
| 18 | - /** 0001 - 0099 网关应答码 */ | 23 | + /** |
| 24 | + * 0001 - 0099 网关应答码 | ||
| 25 | + */ | ||
| 19 | SUCCESS("0000", "成功"), | 26 | SUCCESS("0000", "成功"), |
| 20 | ERROR("0001", "操作失败"), | 27 | ERROR("0001", "操作失败"), |
| 21 | EXCEPTION("9999", "服务器内部异常"), | 28 | EXCEPTION("9999", "服务器内部异常"), |
| @@ -33,36 +40,24 @@ public enum RepCodeEnum { | @@ -33,36 +40,24 @@ public enum RepCodeEnum { | ||
| 33 | API_CAPTCHA_ERROR("6112", "获取验证码失败,请联系管理员"), | 40 | API_CAPTCHA_ERROR("6112", "获取验证码失败,请联系管理员"), |
| 34 | API_CAPTCHA_BASEMAP_NULL("6113", "底图未初始化成功,请检查路径"), | 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 | API_REQ_INVALID("6206", "无效请求,请重新获取验证码"), | 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 | * @param fieldNames | 56 | * @param fieldNames |
| 62 | * @return | 57 | * @return |
| 63 | */ | 58 | */ |
| 64 | public ResponseModel parseError(Object... fieldNames) { | 59 | public ResponseModel parseError(Object... fieldNames) { |
| 65 | - ResponseModel errorMessage=new ResponseModel(); | 60 | + ResponseModel errorMessage = new ResponseModel(); |
| 66 | String newDesc = MessageFormat.format(this.desc, fieldNames); | 61 | String newDesc = MessageFormat.format(this.desc, fieldNames); |
| 67 | 62 | ||
| 68 | errorMessage.setRepCode(this.code); | 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,23 +6,32 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.model.common; | 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 | import java.io.Serializable; | 13 | import java.io.Serializable; |
| 12 | import java.util.HashMap; | 14 | import java.util.HashMap; |
| 13 | import java.util.List; | 15 | import java.util.List; |
| 14 | 16 | ||
| 17 | +@Data | ||
| 15 | public class RequestModel implements Serializable { | 18 | public class RequestModel implements Serializable { |
| 16 | 19 | ||
| 17 | private static final long serialVersionUID = -5800786065305114784L; | 20 | private static final long serialVersionUID = -5800786065305114784L; |
| 18 | 21 | ||
| 19 | - /**当前请求接口路径 /business/accessUser/login */ | 22 | + /** |
| 23 | + * 当前请求接口路径 /business/accessUser/login | ||
| 24 | + */ | ||
| 20 | private String servletPath; | 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 | private String requestString; | 30 | private String requestString; |
| 24 | 31 | ||
| 25 | - /** {"password":"****","userName":"admin"} */ | 32 | + /** |
| 33 | + * {"password":"****","userName":"admin"} | ||
| 34 | + */ | ||
| 26 | private HashMap reqData; | 35 | private HashMap reqData; |
| 27 | 36 | ||
| 28 | private String token; | 37 | private String token; |
| @@ -46,10 +55,11 @@ public class RequestModel implements Serializable { | @@ -46,10 +55,11 @@ public class RequestModel implements Serializable { | ||
| 46 | 55 | ||
| 47 | /** | 56 | /** |
| 48 | * 校验自身参数合法性 | 57 | * 校验自身参数合法性 |
| 58 | + * | ||
| 49 | * @return | 59 | * @return |
| 50 | */ | 60 | */ |
| 51 | public boolean isVaildateRequest() { | 61 | public boolean isVaildateRequest() { |
| 52 | - if (StringUtils.isBlank(sign) || StringUtils.isBlank(time)) { | 62 | + if (StrUtil.isBlank(sign) || StrUtil.isBlank(time)) { |
| 53 | return false; | 63 | return false; |
| 54 | } | 64 | } |
| 55 | return true; | 65 | return true; |
| @@ -63,95 +73,4 @@ public class RequestModel implements Serializable { | @@ -63,95 +73,4 @@ public class RequestModel implements Serializable { | ||
| 63 | this.servletPath = servletPath; | 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,38 +6,42 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.model.common; | 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 | import java.io.Serializable; | 12 | import java.io.Serializable; |
| 12 | 13 | ||
| 14 | +@Data | ||
| 13 | public class ResponseModel implements Serializable { | 15 | public class ResponseModel implements Serializable { |
| 14 | 16 | ||
| 15 | private static final long serialVersionUID = 8445617032523881407L; | 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 | public ResponseModel() { | 25 | public ResponseModel() { |
| 24 | this.repCode = RepCodeEnum.SUCCESS.getCode(); | 26 | this.repCode = RepCodeEnum.SUCCESS.getCode(); |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | public ResponseModel(RepCodeEnum repCodeEnum) { | 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 | return ResponseModel.successMsg("成功"); | 35 | return ResponseModel.successMsg("成功"); |
| 34 | } | 36 | } |
| 35 | - public static ResponseModel successMsg(String message){ | 37 | + |
| 38 | + public static ResponseModel successMsg(String message) { | ||
| 36 | ResponseModel responseModel = new ResponseModel(); | 39 | ResponseModel responseModel = new ResponseModel(); |
| 37 | responseModel.setRepMsg(message); | 40 | responseModel.setRepMsg(message); |
| 38 | return responseModel; | 41 | return responseModel; |
| 39 | } | 42 | } |
| 40 | - public static ResponseModel successData(Object data){ | 43 | + |
| 44 | + public static ResponseModel successData(Object data) { | ||
| 41 | ResponseModel responseModel = new ResponseModel(); | 45 | ResponseModel responseModel = new ResponseModel(); |
| 42 | responseModel.setRepCode(RepCodeEnum.SUCCESS.getCode()); | 46 | responseModel.setRepCode(RepCodeEnum.SUCCESS.getCode()); |
| 43 | responseModel.setRepData(data); | 47 | responseModel.setRepData(data); |
| @@ -45,67 +49,45 @@ public class ResponseModel implements Serializable { | @@ -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 | ResponseModel responseModel = new ResponseModel(); | 53 | ResponseModel responseModel = new ResponseModel(); |
| 50 | responseModel.setRepCodeEnum(message); | 54 | responseModel.setRepCodeEnum(message); |
| 51 | return responseModel; | 55 | return responseModel; |
| 52 | } | 56 | } |
| 53 | - public static ResponseModel errorMsg(String message){ | 57 | + |
| 58 | + public static ResponseModel errorMsg(String message) { | ||
| 54 | ResponseModel responseModel = new ResponseModel(); | 59 | ResponseModel responseModel = new ResponseModel(); |
| 55 | responseModel.setRepCode(RepCodeEnum.ERROR.getCode()); | 60 | responseModel.setRepCode(RepCodeEnum.ERROR.getCode()); |
| 56 | responseModel.setRepMsg(message); | 61 | responseModel.setRepMsg(message); |
| 57 | return responseModel; | 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 | ResponseModel responseModel = new ResponseModel(); | 66 | ResponseModel responseModel = new ResponseModel(); |
| 61 | responseModel.setRepCode(repCodeEnum.getCode()); | 67 | responseModel.setRepCode(repCodeEnum.getCode()); |
| 62 | responseModel.setRepMsg(message); | 68 | responseModel.setRepMsg(message); |
| 63 | return responseModel; | 69 | return responseModel; |
| 64 | } | 70 | } |
| 65 | - public static ResponseModel exceptionMsg(String message){ | 71 | + |
| 72 | + public static ResponseModel exceptionMsg(String message) { | ||
| 66 | ResponseModel responseModel = new ResponseModel(); | 73 | ResponseModel responseModel = new ResponseModel(); |
| 67 | responseModel.setRepCode(RepCodeEnum.EXCEPTION.getCode()); | 74 | responseModel.setRepCode(RepCodeEnum.EXCEPTION.getCode()); |
| 68 | responseModel.setRepMsg(RepCodeEnum.EXCEPTION.getDesc() + ": " + message); | 75 | responseModel.setRepMsg(RepCodeEnum.EXCEPTION.getDesc() + ": " + message); |
| 69 | return responseModel; | 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 | public String getRepCode() { | 84 | public String getRepCode() { |
| 83 | return repCode; | 85 | return repCode; |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | - public void setRepCode(String repCode) { | ||
| 87 | - this.repCode = repCode; | ||
| 88 | - } | ||
| 89 | public void setRepCodeEnum(RepCodeEnum repCodeEnum) { | 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,10 +6,13 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.model.vo; | 7 | package com.anji.captcha.model.vo; |
| 8 | 8 | ||
| 9 | +import lombok.Data; | ||
| 10 | + | ||
| 9 | import java.awt.*; | 11 | import java.awt.*; |
| 10 | import java.io.Serializable; | 12 | import java.io.Serializable; |
| 11 | import java.util.List; | 13 | import java.util.List; |
| 12 | 14 | ||
| 15 | +@Data | ||
| 13 | public class CaptchaVO implements Serializable { | 16 | public class CaptchaVO implements Serializable { |
| 14 | 17 | ||
| 15 | /** | 18 | /** |
| @@ -79,173 +82,23 @@ public class CaptchaVO implements Serializable { | @@ -79,173 +82,23 @@ public class CaptchaVO implements Serializable { | ||
| 79 | */ | 82 | */ |
| 80 | private String captchaVerification; | 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 | * 客户端ip+userAgent | 95 | * 客户端ip+userAgent |
| 93 | */ | 96 | */ |
| 94 | private String browserInfo; | 97 | private String browserInfo; |
| 95 | - public void resetClientFlag(){ | 98 | + |
| 99 | + public void resetClientFlag() { | ||
| 96 | this.browserInfo = null; | 100 | this.browserInfo = null; |
| 97 | this.clientUid = null; | 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 | package com.anji.captcha.model.vo; | 1 | package com.anji.captcha.model.vo; |
| 2 | 2 | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 3 | import java.util.Arrays; | 5 | import java.util.Arrays; |
| 4 | import java.util.HashMap; | 6 | import java.util.HashMap; |
| 5 | import java.util.Map; | 7 | import java.util.Map; |
| @@ -9,6 +11,7 @@ import java.util.regex.Pattern; | @@ -9,6 +11,7 @@ import java.util.regex.Pattern; | ||
| 9 | /** | 11 | /** |
| 10 | * Created by raodeming on 2020/5/16. | 12 | * Created by raodeming on 2020/5/16. |
| 11 | */ | 13 | */ |
| 14 | +@Data | ||
| 12 | public class PointVO { | 15 | public class PointVO { |
| 13 | private String secretKey; | 16 | private String secretKey; |
| 14 | 17 | ||
| @@ -16,30 +19,6 @@ public class PointVO { | @@ -16,30 +19,6 @@ public class PointVO { | ||
| 16 | 19 | ||
| 17 | public int y; | 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 | public PointVO(int x, int y, String secretKey) { | 22 | public PointVO(int x, int y, String secretKey) { |
| 44 | this.secretKey = secretKey; | 23 | this.secretKey = secretKey; |
| 45 | this.x = x; | 24 | this.x = x; |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/properties/AjCaptchaProperties.java
| 1 | package com.anji.captcha.properties; | 1 | package com.anji.captcha.properties; |
| 2 | 2 | ||
| 3 | import com.anji.captcha.model.common.CaptchaTypeEnum; | 3 | import com.anji.captcha.model.common.CaptchaTypeEnum; |
| 4 | +import lombok.Data; | ||
| 4 | import org.springframework.boot.context.properties.ConfigurationProperties; | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; |
| 5 | 6 | ||
| 6 | import java.awt.*; | 7 | import java.awt.*; |
| @@ -8,6 +9,7 @@ import java.awt.*; | @@ -8,6 +9,7 @@ import java.awt.*; | ||
| 8 | import static com.anji.captcha.properties.AjCaptchaProperties.PREFIX; | 9 | import static com.anji.captcha.properties.AjCaptchaProperties.PREFIX; |
| 9 | import static com.anji.captcha.properties.AjCaptchaProperties.StorageType.local; | 10 | import static com.anji.captcha.properties.AjCaptchaProperties.StorageType.local; |
| 10 | 11 | ||
| 12 | +@Data | ||
| 11 | @ConfigurationProperties(PREFIX) | 13 | @ConfigurationProperties(PREFIX) |
| 12 | public class AjCaptchaProperties { | 14 | public class AjCaptchaProperties { |
| 13 | public static final String PREFIX = "aj.captcha"; | 15 | public static final String PREFIX = "aj.captcha"; |
| @@ -113,90 +115,10 @@ public class AjCaptchaProperties { | @@ -113,90 +115,10 @@ public class AjCaptchaProperties { | ||
| 113 | */ | 115 | */ |
| 114 | private int clickWordCount = 4; | 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 | public boolean getReqFrequencyLimitEnable() { | 118 | public boolean getReqFrequencyLimitEnable() { |
| 153 | return reqFrequencyLimitEnable; | 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 | public enum StorageType { | 122 | public enum StorageType { |
| 201 | /** | 123 | /** |
| 202 | * 内存. | 124 | * 内存. |
| @@ -216,123 +138,4 @@ public class AjCaptchaProperties { | @@ -216,123 +138,4 @@ public class AjCaptchaProperties { | ||
| 216 | return PREFIX; | 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,34 +8,36 @@ package com.anji.captcha.service; | ||
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | * 验证码缓存接口 | 10 | * 验证码缓存接口 |
| 11 | + * | ||
| 11 | * @author lide1202@hotmail.com | 12 | * @author lide1202@hotmail.com |
| 12 | * @date 2018-08-21 | 13 | * @date 2018-08-21 |
| 13 | */ | 14 | */ |
| 14 | public interface CaptchaCacheService { | 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,6 +13,7 @@ import java.util.Properties; | ||
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | * 验证码服务接口 | 15 | * 验证码服务接口 |
| 16 | + * | ||
| 16 | * @author lide1202@hotmail.com | 17 | * @author lide1202@hotmail.com |
| 17 | * @date 2020-05-12 | 18 | * @date 2020-05-12 |
| 18 | */ | 19 | */ |
| @@ -24,6 +25,7 @@ public interface CaptchaService { | @@ -24,6 +25,7 @@ public interface CaptchaService { | ||
| 24 | 25 | ||
| 25 | /** | 26 | /** |
| 26 | * 获取验证码 | 27 | * 获取验证码 |
| 28 | + * | ||
| 27 | * @param captchaVO | 29 | * @param captchaVO |
| 28 | * @return | 30 | * @return |
| 29 | */ | 31 | */ |
| @@ -31,6 +33,7 @@ public interface CaptchaService { | @@ -31,6 +33,7 @@ public interface CaptchaService { | ||
| 31 | 33 | ||
| 32 | /** | 34 | /** |
| 33 | * 核对验证码(前端) | 35 | * 核对验证码(前端) |
| 36 | + * | ||
| 34 | * @param captchaVO | 37 | * @param captchaVO |
| 35 | * @return | 38 | * @return |
| 36 | */ | 39 | */ |
| @@ -38,6 +41,7 @@ public interface CaptchaService { | @@ -38,6 +41,7 @@ public interface CaptchaService { | ||
| 38 | 41 | ||
| 39 | /** | 42 | /** |
| 40 | * 二次校验验证码(后端) | 43 | * 二次校验验证码(后端) |
| 44 | + * | ||
| 41 | * @param captchaVO | 45 | * @param captchaVO |
| 42 | * @return | 46 | * @return |
| 43 | */ | 47 | */ |
| @@ -50,9 +54,10 @@ public interface CaptchaService { | @@ -50,9 +54,10 @@ public interface CaptchaService { | ||
| 50 | */ | 54 | */ |
| 51 | String captchaType(); | 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 +6,7 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.service.impl; | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | ||
| 9 | +import cn.hutool.core.util.StrUtil; | ||
| 9 | import com.anji.captcha.model.common.Const; | 10 | import com.anji.captcha.model.common.Const; |
| 10 | import com.anji.captcha.model.common.RepCodeEnum; | 11 | import com.anji.captcha.model.common.RepCodeEnum; |
| 11 | import com.anji.captcha.model.common.ResponseModel; | 12 | import com.anji.captcha.model.common.ResponseModel; |
| @@ -13,29 +14,28 @@ import com.anji.captcha.model.vo.CaptchaVO; | @@ -13,29 +14,28 @@ import com.anji.captcha.model.vo.CaptchaVO; | ||
| 13 | import com.anji.captcha.service.CaptchaCacheService; | 14 | import com.anji.captcha.service.CaptchaCacheService; |
| 14 | import com.anji.captcha.service.CaptchaService; | 15 | import com.anji.captcha.service.CaptchaService; |
| 15 | import com.anji.captcha.util.*; | 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 | import java.awt.*; | 19 | import java.awt.*; |
| 20 | import java.io.File; | 20 | import java.io.File; |
| 21 | -import java.io.FileOutputStream; | ||
| 22 | import java.io.OutputStream; | 21 | import java.io.OutputStream; |
| 23 | import java.nio.charset.StandardCharsets; | 22 | import java.nio.charset.StandardCharsets; |
| 23 | +import java.nio.file.Files; | ||
| 24 | import java.util.Base64; | 24 | import java.util.Base64; |
| 25 | +import java.util.Objects; | ||
| 25 | import java.util.Properties; | 26 | import java.util.Properties; |
| 26 | 27 | ||
| 27 | /** | 28 | /** |
| 28 | * Created by raodeming on 2019/12/25. | 29 | * Created by raodeming on 2019/12/25. |
| 29 | */ | 30 | */ |
| 31 | +@Slf4j | ||
| 30 | public abstract class AbstractCaptchaService implements CaptchaService { | 32 | public abstract class AbstractCaptchaService implements CaptchaService { |
| 31 | 33 | ||
| 32 | - protected Logger logger = LoggerFactory.getLogger(getClass()); | ||
| 33 | - | ||
| 34 | protected static final String IMAGE_TYPE_PNG = "png"; | 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 | //check校验坐标 | 39 | //check校验坐标 |
| 40 | protected static String REDIS_CAPTCHA_KEY = "RUNNING:CAPTCHA:%s"; | 40 | protected static String REDIS_CAPTCHA_KEY = "RUNNING:CAPTCHA:%s"; |
| 41 | 41 | ||
| @@ -73,7 +73,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { | @@ -73,7 +73,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { | ||
| 73 | ImageUtils.cacheImage(config.getProperty(Const.ORIGINAL_PATH_JIGSAW), | 73 | ImageUtils.cacheImage(config.getProperty(Const.ORIGINAL_PATH_JIGSAW), |
| 74 | config.getProperty(Const.ORIGINAL_PATH_PIC_CLICK)); | 74 | config.getProperty(Const.ORIGINAL_PATH_PIC_CLICK)); |
| 75 | } | 75 | } |
| 76 | - logger.info("--->>>初始化验证码底图<<<---" + captchaType()); | 76 | + log.info("--->>>初始化验证码底图<<<---" + captchaType()); |
| 77 | waterMark = config.getProperty(Const.CAPTCHA_WATER_MARK, "我的水印"); | 77 | waterMark = config.getProperty(Const.CAPTCHA_WATER_MARK, "我的水印"); |
| 78 | slipOffset = config.getProperty(Const.CAPTCHA_SLIP_OFFSET, "5"); | 78 | slipOffset = config.getProperty(Const.CAPTCHA_SLIP_OFFSET, "5"); |
| 79 | waterMarkFontStr = config.getProperty(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); | 79 | waterMarkFontStr = config.getProperty(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); |
| @@ -88,13 +88,13 @@ public abstract class AbstractCaptchaService implements CaptchaService { | @@ -88,13 +88,13 @@ public abstract class AbstractCaptchaService implements CaptchaService { | ||
| 88 | // 通过加载resources下的font字体解决,无需在linux中安装字体 | 88 | // 通过加载resources下的font字体解决,无需在linux中安装字体 |
| 89 | loadWaterMarkFont(); | 89 | loadWaterMarkFont(); |
| 90 | 90 | ||
| 91 | - if (cacheType.equals("local")) { | ||
| 92 | - logger.info("初始化local缓存..."); | 91 | + if ("local".equals(cacheType)) { |
| 92 | + log.info("初始化local缓存..."); | ||
| 93 | CacheUtil.init(Integer.parseInt(config.getProperty(Const.CAPTCHA_CACAHE_MAX_NUMBER, "1000")), | 93 | CacheUtil.init(Integer.parseInt(config.getProperty(Const.CAPTCHA_CACAHE_MAX_NUMBER, "1000")), |
| 94 | Long.parseLong(config.getProperty(Const.CAPTCHA_TIMING_CLEAR_SECOND, "180"))); | 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 | Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { | 98 | Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { |
| 99 | @Override | 99 | @Override |
| 100 | public void run() { | 100 | public void run() { |
| @@ -102,9 +102,9 @@ public abstract class AbstractCaptchaService implements CaptchaService { | @@ -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 | if (limitHandler == null) { | 106 | if (limitHandler == null) { |
| 107 | - logger.info("接口分钟内限流开关...开启..."); | 107 | + log.info("接口分钟内限流开关...开启..."); |
| 108 | limitHandler = new FrequencyLimitHandler.DefaultLimitHandler(config, getCacheService(cacheType)); | 108 | limitHandler = new FrequencyLimitHandler.DefaultLimitHandler(config, getCacheService(cacheType)); |
| 109 | } | 109 | } |
| 110 | } | 110 | } |
| @@ -150,7 +150,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { | @@ -150,7 +150,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { | ||
| 150 | if (captchaVO == null) { | 150 | if (captchaVO == null) { |
| 151 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); | 151 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 152 | } | 152 | } |
| 153 | - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { | 153 | + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { |
| 154 | return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); | 154 | return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); |
| 155 | } | 155 | } |
| 156 | if (limitHandler != null) { | 156 | if (limitHandler != null) { |
| @@ -163,17 +163,17 @@ public abstract class AbstractCaptchaService implements CaptchaService { | @@ -163,17 +163,17 @@ public abstract class AbstractCaptchaService implements CaptchaService { | ||
| 163 | return resp == null || resp.isSuccess(); | 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 | protected void afterValidateFail(CaptchaVO data) { | 178 | protected void afterValidateFail(CaptchaVO data) { |
| 179 | if (limitHandler != null) { | 179 | if (limitHandler != null) { |
| @@ -197,14 +197,14 @@ public abstract class AbstractCaptchaService implements CaptchaService { | @@ -197,14 +197,14 @@ public abstract class AbstractCaptchaService implements CaptchaService { | ||
| 197 | if (waterMarkFontStr.toLowerCase().endsWith(".ttf") || waterMarkFontStr.toLowerCase().endsWith(".ttc") | 197 | if (waterMarkFontStr.toLowerCase().endsWith(".ttf") || waterMarkFontStr.toLowerCase().endsWith(".ttc") |
| 198 | || waterMarkFontStr.toLowerCase().endsWith(".otf")) { | 198 | || waterMarkFontStr.toLowerCase().endsWith(".otf")) { |
| 199 | this.waterMarkFont = Font.createFont(Font.TRUETYPE_FONT, | 199 | this.waterMarkFont = Font.createFont(Font.TRUETYPE_FONT, |
| 200 | - getClass().getResourceAsStream("/fonts/" + waterMarkFontStr)) | 200 | + Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + waterMarkFontStr))) |
| 201 | .deriveFont(Font.BOLD, HAN_ZI_SIZE / 2); | 201 | .deriveFont(Font.BOLD, HAN_ZI_SIZE / 2); |
| 202 | } else { | 202 | } else { |
| 203 | this.waterMarkFont = new Font(waterMarkFontStr, Font.BOLD, HAN_ZI_SIZE / 2); | 203 | this.waterMarkFont = new Font(waterMarkFontStr, Font.BOLD, HAN_ZI_SIZE / 2); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | } catch (Exception e) { | 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,7 +228,7 @@ public abstract class AbstractCaptchaService implements CaptchaService { | ||
| 228 | if (!tempFile.getParentFile().exists()) { | 228 | if (!tempFile.getParentFile().exists()) { |
| 229 | tempFile.getParentFile().mkdirs(); | 229 | tempFile.getParentFile().mkdirs(); |
| 230 | } | 230 | } |
| 231 | - OutputStream out = new FileOutputStream(tempFile); | 231 | + OutputStream out = Files.newOutputStream(tempFile.toPath()); |
| 232 | out.write(b); | 232 | out.write(b); |
| 233 | out.flush(); | 233 | out.flush(); |
| 234 | out.close(); | 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,12 +6,14 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.service.impl; | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | ||
| 9 | +import cn.hutool.core.util.StrUtil; | ||
| 9 | import com.anji.captcha.model.common.CaptchaTypeEnum; | 10 | import com.anji.captcha.model.common.CaptchaTypeEnum; |
| 10 | import com.anji.captcha.model.common.RepCodeEnum; | 11 | import com.anji.captcha.model.common.RepCodeEnum; |
| 11 | import com.anji.captcha.model.common.ResponseModel; | 12 | import com.anji.captcha.model.common.ResponseModel; |
| 12 | import com.anji.captcha.model.vo.CaptchaVO; | 13 | import com.anji.captcha.model.vo.CaptchaVO; |
| 13 | import com.anji.captcha.model.vo.PointVO; | 14 | import com.anji.captcha.model.vo.PointVO; |
| 14 | import com.anji.captcha.util.*; | 15 | import com.anji.captcha.util.*; |
| 16 | +import lombok.extern.slf4j.Slf4j; | ||
| 15 | 17 | ||
| 16 | import javax.imageio.ImageIO; | 18 | import javax.imageio.ImageIO; |
| 17 | import java.awt.*; | 19 | import java.awt.*; |
| @@ -27,6 +29,7 @@ import java.util.Random; | @@ -27,6 +29,7 @@ import java.util.Random; | ||
| 27 | * <p> | 29 | * <p> |
| 28 | * Created by raodeming on 2019/12/25. | 30 | * Created by raodeming on 2019/12/25. |
| 29 | */ | 31 | */ |
| 32 | +@Slf4j | ||
| 30 | public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | 33 | public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { |
| 31 | 34 | ||
| 32 | @Override | 35 | @Override |
| @@ -34,10 +37,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -34,10 +37,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 34 | super.init(config); | 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 | @Override | 45 | @Override |
| 43 | public String captchaType() { | 46 | public String captchaType() { |
| @@ -46,14 +49,14 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -46,14 +49,14 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 46 | 49 | ||
| 47 | @Override | 50 | @Override |
| 48 | public ResponseModel get(CaptchaVO captchaVO) { | 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 | BufferedImage originalImage = ImageUtils.getOriginal(); | 57 | BufferedImage originalImage = ImageUtils.getOriginal(); |
| 55 | if (null == originalImage) { | 58 | if (null == originalImage) { |
| 56 | - logger.error("滑动底图未初始化成功,请检查路径"); | 59 | + log.error("滑动底图未初始化成功,请检查路径"); |
| 57 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); | 60 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); |
| 58 | } | 61 | } |
| 59 | //设置水印 | 62 | //设置水印 |
| @@ -68,13 +71,13 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -68,13 +71,13 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 68 | String jigsawImageBase64 = ImageUtils.getslidingBlock(); | 71 | String jigsawImageBase64 = ImageUtils.getslidingBlock(); |
| 69 | BufferedImage jigsawImage = ImageUtils.getBase64StrToImage(jigsawImageBase64); | 72 | BufferedImage jigsawImage = ImageUtils.getBase64StrToImage(jigsawImageBase64); |
| 70 | if (null == jigsawImage) { | 73 | if (null == jigsawImage) { |
| 71 | - logger.error("滑动底图未初始化成功,请检查路径"); | 74 | + log.error("滑动底图未初始化成功,请检查路径"); |
| 72 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); | 75 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); |
| 73 | } | 76 | } |
| 74 | CaptchaVO captcha = pictureTemplatesCut(originalImage, jigsawImage, jigsawImageBase64); | 77 | CaptchaVO captcha = pictureTemplatesCut(originalImage, jigsawImage, jigsawImageBase64); |
| 75 | if (captcha == null | 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 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); | 81 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); |
| 79 | } | 82 | } |
| 80 | return ResponseModel.successData(captcha); | 83 | return ResponseModel.successData(captcha); |
| @@ -82,10 +85,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -82,10 +85,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 82 | 85 | ||
| 83 | @Override | 86 | @Override |
| 84 | public ResponseModel check(CaptchaVO captchaVO) { | 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 | String codeKey = String.format(REDIS_CAPTCHA_KEY, captchaVO.getToken()); | 93 | String codeKey = String.format(REDIS_CAPTCHA_KEY, captchaVO.getToken()); |
| 91 | if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { | 94 | if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { |
| @@ -103,7 +106,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -103,7 +106,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 103 | pointJson = decrypt(captchaVO.getPointJson(), point.getSecretKey()); | 106 | pointJson = decrypt(captchaVO.getPointJson(), point.getSecretKey()); |
| 104 | point1 = JsonUtil.parseObject(pointJson, PointVO.class); | 107 | point1 = JsonUtil.parseObject(pointJson, PointVO.class); |
| 105 | } catch (Exception e) { | 108 | } catch (Exception e) { |
| 106 | - logger.error("验证码坐标解析失败", e); | 109 | + log.error("验证码坐标解析失败", e); |
| 107 | afterValidateFail(captchaVO); | 110 | afterValidateFail(captchaVO); |
| 108 | return ResponseModel.errorMsg(e.getMessage()); | 111 | return ResponseModel.errorMsg(e.getMessage()); |
| 109 | } | 112 | } |
| @@ -119,7 +122,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -119,7 +122,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 119 | try { | 122 | try { |
| 120 | value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); | 123 | value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); |
| 121 | } catch (Exception e) { | 124 | } catch (Exception e) { |
| 122 | - logger.error("AES加密失败", e); | 125 | + log.error("AES加密失败", e); |
| 123 | afterValidateFail(captchaVO); | 126 | afterValidateFail(captchaVO); |
| 124 | return ResponseModel.errorMsg(e.getMessage()); | 127 | return ResponseModel.errorMsg(e.getMessage()); |
| 125 | } | 128 | } |
| @@ -132,10 +135,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -132,10 +135,10 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 132 | 135 | ||
| 133 | @Override | 136 | @Override |
| 134 | public ResponseModel verification(CaptchaVO captchaVO) { | 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 | try { | 142 | try { |
| 140 | String codeKey = String.format(REDIS_SECOND_CAPTCHA_KEY, captchaVO.getCaptchaVerification()); | 143 | String codeKey = String.format(REDIS_SECOND_CAPTCHA_KEY, captchaVO.getCaptchaVerification()); |
| 141 | if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { | 144 | if (!CaptchaServiceFactory.getCache(cacheType).exists(codeKey)) { |
| @@ -144,7 +147,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -144,7 +147,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 144 | //二次校验取值后,即刻失效 | 147 | //二次校验取值后,即刻失效 |
| 145 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); | 148 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); |
| 146 | } catch (Exception e) { | 149 | } catch (Exception e) { |
| 147 | - logger.error("验证码坐标解析失败", e); | 150 | + log.error("验证码坐标解析失败", e); |
| 148 | return ResponseModel.errorMsg(e.getMessage()); | 151 | return ResponseModel.errorMsg(e.getMessage()); |
| 149 | } | 152 | } |
| 150 | return ResponseModel.success(); | 153 | return ResponseModel.success(); |
| @@ -234,7 +237,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | @@ -234,7 +237,7 @@ public class BlockPuzzleCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 234 | //将坐标信息存入redis中 | 237 | //将坐标信息存入redis中 |
| 235 | String codeKey = String.format(REDIS_CAPTCHA_KEY, dataVO.getToken()); | 238 | String codeKey = String.format(REDIS_CAPTCHA_KEY, dataVO.getToken()); |
| 236 | CaptchaServiceFactory.getCache(cacheType).set(codeKey, JsonUtil.toJSONString(point), EXPIRESIN_SECONDS); | 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 | return dataVO; | 241 | return dataVO; |
| 239 | } catch (Exception e) { | 242 | } catch (Exception e) { |
| 240 | e.printStackTrace(); | 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,12 +3,15 @@ package com.anji.captcha.service.impl; | ||
| 3 | import com.anji.captcha.service.CaptchaCacheService; | 3 | import com.anji.captcha.service.CaptchaCacheService; |
| 4 | import com.anji.captcha.util.CacheUtil; | 4 | import com.anji.captcha.util.CacheUtil; |
| 5 | 5 | ||
| 6 | +import java.util.Objects; | ||
| 7 | + | ||
| 6 | /** | 8 | /** |
| 7 | * 对于分布式部署的应用,我们建议应用自己实现CaptchaCacheService,比如用Redis,参考service/spring-boot代码示例。 | 9 | * 对于分布式部署的应用,我们建议应用自己实现CaptchaCacheService,比如用Redis,参考service/spring-boot代码示例。 |
| 8 | * 如果应用是单点的,也没有使用redis,那默认使用内存。 | 10 | * 如果应用是单点的,也没有使用redis,那默认使用内存。 |
| 9 | * 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。 | 11 | * 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。 |
| 10 | - * @Title: 默认使用内存当缓存 | 12 | + * |
| 11 | * @author lide1202@hotmail.com | 13 | * @author lide1202@hotmail.com |
| 14 | + * @Title: 默认使用内存当缓存 | ||
| 12 | * @date 2020-05-12 | 15 | * @date 2020-05-12 |
| 13 | */ | 16 | */ |
| 14 | public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { | 17 | public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { |
| @@ -33,14 +36,14 @@ public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { | @@ -33,14 +36,14 @@ public class CaptchaCacheServiceMemImpl implements CaptchaCacheService { | ||
| 33 | return CacheUtil.get(key); | 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 | public String type() { | 47 | public String type() { |
| 45 | return "local"; | 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,8 +3,7 @@ package com.anji.captcha.service.impl; | ||
| 3 | import com.anji.captcha.model.common.Const; | 3 | import com.anji.captcha.model.common.Const; |
| 4 | import com.anji.captcha.service.CaptchaCacheService; | 4 | import com.anji.captcha.service.CaptchaCacheService; |
| 5 | import com.anji.captcha.service.CaptchaService; | 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 | import java.util.HashMap; | 8 | import java.util.HashMap; |
| 10 | import java.util.Map; | 9 | import java.util.Map; |
| @@ -14,10 +13,9 @@ import java.util.ServiceLoader; | @@ -14,10 +13,9 @@ import java.util.ServiceLoader; | ||
| 14 | /** | 13 | /** |
| 15 | * Created by raodeming on 2020/5/26. | 14 | * Created by raodeming on 2020/5/26. |
| 16 | */ | 15 | */ |
| 16 | +@Slf4j | ||
| 17 | public class CaptchaServiceFactory { | 17 | public class CaptchaServiceFactory { |
| 18 | 18 | ||
| 19 | - private static Logger logger = LoggerFactory.getLogger(CaptchaServiceFactory.class); | ||
| 20 | - | ||
| 21 | public static CaptchaService getInstance(Properties config) { | 19 | public static CaptchaService getInstance(Properties config) { |
| 22 | //先把所有CaptchaService初始化,通过init方法,实例字体等,add by lide1202@hotmail.com | 20 | //先把所有CaptchaService初始化,通过init方法,实例字体等,add by lide1202@hotmail.com |
| 23 | /*try{ | 21 | /*try{ |
| @@ -41,20 +39,20 @@ public class CaptchaServiceFactory { | @@ -41,20 +39,20 @@ public class CaptchaServiceFactory { | ||
| 41 | return cacheService.get(cacheType); | 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 | static { | 45 | static { |
| 48 | ServiceLoader<CaptchaCacheService> cacheServices = ServiceLoader.load(CaptchaCacheService.class); | 46 | ServiceLoader<CaptchaCacheService> cacheServices = ServiceLoader.load(CaptchaCacheService.class); |
| 49 | for (CaptchaCacheService item : cacheServices) { | 47 | for (CaptchaCacheService item : cacheServices) { |
| 50 | cacheService.put(item.type(), item); | 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 | ServiceLoader<CaptchaService> services = ServiceLoader.load(CaptchaService.class); | 51 | ServiceLoader<CaptchaService> services = ServiceLoader.load(CaptchaService.class); |
| 54 | for (CaptchaService item : services) { | 52 | for (CaptchaService item : services) { |
| 55 | instances.put(item.captchaType(), item); | 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 +6,7 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.service.impl; | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | ||
| 9 | +import cn.hutool.core.util.StrUtil; | ||
| 9 | import com.anji.captcha.model.common.CaptchaTypeEnum; | 10 | import com.anji.captcha.model.common.CaptchaTypeEnum; |
| 10 | import com.anji.captcha.model.common.Const; | 11 | import com.anji.captcha.model.common.Const; |
| 11 | import com.anji.captcha.model.common.RepCodeEnum; | 12 | import com.anji.captcha.model.common.RepCodeEnum; |
| @@ -13,6 +14,7 @@ import com.anji.captcha.model.common.ResponseModel; | @@ -13,6 +14,7 @@ import com.anji.captcha.model.common.ResponseModel; | ||
| 13 | import com.anji.captcha.model.vo.CaptchaVO; | 14 | import com.anji.captcha.model.vo.CaptchaVO; |
| 14 | import com.anji.captcha.model.vo.PointVO; | 15 | import com.anji.captcha.model.vo.PointVO; |
| 15 | import com.anji.captcha.util.*; | 16 | import com.anji.captcha.util.*; |
| 17 | +import lombok.extern.slf4j.Slf4j; | ||
| 16 | 18 | ||
| 17 | import java.awt.*; | 19 | import java.awt.*; |
| 18 | import java.awt.geom.AffineTransform; | 20 | import java.awt.geom.AffineTransform; |
| @@ -25,6 +27,7 @@ import java.util.*; | @@ -25,6 +27,7 @@ import java.util.*; | ||
| 25 | * <p> | 27 | * <p> |
| 26 | * Created by raodeming on 2019/12/25. | 28 | * Created by raodeming on 2019/12/25. |
| 27 | */ | 29 | */ |
| 30 | +@Slf4j | ||
| 28 | public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | 31 | public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { |
| 29 | 32 | ||
| 30 | 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"; | 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,27 +46,27 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 43 | super.init(config); | 46 | super.init(config); |
| 44 | clickWordFontStr = config.getProperty(Const.CAPTCHA_FONT_TYPE, "SourceHanSansCN-Normal.otf"); | 47 | clickWordFontStr = config.getProperty(Const.CAPTCHA_FONT_TYPE, "SourceHanSansCN-Normal.otf"); |
| 45 | try { | 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 | if (clickWordFontStr.toLowerCase().endsWith(".ttf") | 51 | if (clickWordFontStr.toLowerCase().endsWith(".ttf") |
| 49 | || clickWordFontStr.toLowerCase().endsWith(".ttc") | 52 | || clickWordFontStr.toLowerCase().endsWith(".ttc") |
| 50 | || clickWordFontStr.toLowerCase().endsWith(".otf")) { | 53 | || clickWordFontStr.toLowerCase().endsWith(".otf")) { |
| 51 | this.clickWordFont = Font.createFont(Font.TRUETYPE_FONT, | 54 | this.clickWordFont = Font.createFont(Font.TRUETYPE_FONT, |
| 52 | - getClass().getResourceAsStream("/fonts/" + clickWordFontStr)) | 55 | + Objects.requireNonNull(getClass().getResourceAsStream("/fonts/" + clickWordFontStr))) |
| 53 | .deriveFont(Font.BOLD, size); | 56 | .deriveFont(Font.BOLD, size); |
| 54 | } else { | 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 | this.clickWordFont = new Font(clickWordFontStr, style, size); | 59 | this.clickWordFont = new Font(clickWordFontStr, style, size); |
| 57 | } | 60 | } |
| 58 | } catch (Exception ex) { | 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 | @Override | 67 | @Override |
| 65 | public void destroy(Properties config) { | 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 | @Override | 72 | @Override |
| @@ -74,12 +77,12 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | @@ -74,12 +77,12 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 74 | } | 77 | } |
| 75 | BufferedImage bufferedImage = ImageUtils.getPicClick(); | 78 | BufferedImage bufferedImage = ImageUtils.getPicClick(); |
| 76 | if (null == bufferedImage) { | 79 | if (null == bufferedImage) { |
| 77 | - logger.error("滑动底图未初始化成功,请检查路径"); | 80 | + log.error("滑动底图未初始化成功,请检查路径"); |
| 78 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); | 81 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_BASEMAP_NULL); |
| 79 | } | 82 | } |
| 80 | CaptchaVO imageData = getImageData(bufferedImage); | 83 | CaptchaVO imageData = getImageData(bufferedImage); |
| 81 | if (imageData == null | 84 | if (imageData == null |
| 82 | - || StringUtils.isBlank(imageData.getOriginalImageBase64())) { | 85 | + || StrUtil.isBlank(imageData.getOriginalImageBase64())) { |
| 83 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); | 86 | return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_ERROR); |
| 84 | } | 87 | } |
| 85 | return ResponseModel.successData(imageData); | 88 | return ResponseModel.successData(imageData); |
| @@ -124,7 +127,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | @@ -124,7 +127,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 124 | pointJson = decrypt(captchaVO.getPointJson(), point.get(0).getSecretKey()); | 127 | pointJson = decrypt(captchaVO.getPointJson(), point.get(0).getSecretKey()); |
| 125 | point1 = JsonUtil.parseArray(pointJson, PointVO.class); | 128 | point1 = JsonUtil.parseArray(pointJson, PointVO.class); |
| 126 | } catch (Exception e) { | 129 | } catch (Exception e) { |
| 127 | - logger.error("验证码坐标解析失败", e); | 130 | + log.error("验证码坐标解析失败", e); |
| 128 | afterValidateFail(captchaVO); | 131 | afterValidateFail(captchaVO); |
| 129 | return ResponseModel.errorMsg(e.getMessage()); | 132 | return ResponseModel.errorMsg(e.getMessage()); |
| 130 | } | 133 | } |
| @@ -143,7 +146,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | @@ -143,7 +146,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 143 | try { | 146 | try { |
| 144 | value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); | 147 | value = AESUtil.aesEncrypt(captchaVO.getToken().concat("---").concat(pointJson), secretKey); |
| 145 | } catch (Exception e) { | 148 | } catch (Exception e) { |
| 146 | - logger.error("AES加密失败", e); | 149 | + log.error("AES加密失败", e); |
| 147 | afterValidateFail(captchaVO); | 150 | afterValidateFail(captchaVO); |
| 148 | return ResponseModel.errorMsg(e.getMessage()); | 151 | return ResponseModel.errorMsg(e.getMessage()); |
| 149 | } | 152 | } |
| @@ -159,7 +162,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | @@ -159,7 +162,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 159 | /*if (captchaVO == null) { | 162 | /*if (captchaVO == null) { |
| 160 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); | 163 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 161 | } | 164 | } |
| 162 | - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { | 165 | + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { |
| 163 | return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); | 166 | return RepCodeEnum.NULL_ERROR.parseError("captchaVerification"); |
| 164 | }*/ | 167 | }*/ |
| 165 | ResponseModel r = super.verification(captchaVO); | 168 | ResponseModel r = super.verification(captchaVO); |
| @@ -174,7 +177,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | @@ -174,7 +177,7 @@ public class ClickWordCaptchaServiceImpl extends AbstractCaptchaService { | ||
| 174 | //二次校验取值后,即刻失效 | 177 | //二次校验取值后,即刻失效 |
| 175 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); | 178 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); |
| 176 | } catch (Exception e) { | 179 | } catch (Exception e) { |
| 177 | - logger.error("验证码坐标解析失败", e); | 180 | + log.error("验证码坐标解析失败", e); |
| 178 | return ResponseModel.errorMsg(e.getMessage()); | 181 | return ResponseModel.errorMsg(e.getMessage()); |
| 179 | } | 182 | } |
| 180 | return ResponseModel.success(); | 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,17 +6,19 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.service.impl; | 7 | package com.anji.captcha.service.impl; |
| 8 | 8 | ||
| 9 | +import cn.hutool.core.util.StrUtil; | ||
| 9 | import com.anji.captcha.model.common.RepCodeEnum; | 10 | import com.anji.captcha.model.common.RepCodeEnum; |
| 10 | import com.anji.captcha.model.common.ResponseModel; | 11 | import com.anji.captcha.model.common.ResponseModel; |
| 11 | import com.anji.captcha.model.vo.CaptchaVO; | 12 | import com.anji.captcha.model.vo.CaptchaVO; |
| 12 | import com.anji.captcha.service.CaptchaService; | 13 | import com.anji.captcha.service.CaptchaService; |
| 13 | -import com.anji.captcha.util.StringUtils; | 14 | +import lombok.extern.slf4j.Slf4j; |
| 14 | 15 | ||
| 15 | import java.util.Properties; | 16 | import java.util.Properties; |
| 16 | 17 | ||
| 17 | /** | 18 | /** |
| 18 | * Created by raodeming on 2019/12/25. | 19 | * Created by raodeming on 2019/12/25. |
| 19 | */ | 20 | */ |
| 21 | +@Slf4j | ||
| 20 | public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | 22 | public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ |
| 21 | 23 | ||
| 22 | @Override | 24 | @Override |
| @@ -53,7 +55,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | @@ -53,7 +55,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | ||
| 53 | if (captchaVO == null) { | 55 | if (captchaVO == null) { |
| 54 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); | 56 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 55 | } | 57 | } |
| 56 | - if (StringUtils.isEmpty(captchaVO.getCaptchaType())) { | 58 | + if (StrUtil.isEmpty(captchaVO.getCaptchaType())) { |
| 57 | return RepCodeEnum.NULL_ERROR.parseError("类型"); | 59 | return RepCodeEnum.NULL_ERROR.parseError("类型"); |
| 58 | } | 60 | } |
| 59 | return getService(captchaVO.getCaptchaType()).get(captchaVO); | 61 | return getService(captchaVO.getCaptchaType()).get(captchaVO); |
| @@ -64,10 +66,10 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | @@ -64,10 +66,10 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | ||
| 64 | if (captchaVO == null) { | 66 | if (captchaVO == null) { |
| 65 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); | 67 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 66 | } | 68 | } |
| 67 | - if (StringUtils.isEmpty(captchaVO.getCaptchaType())) { | 69 | + if (StrUtil.isEmpty(captchaVO.getCaptchaType())) { |
| 68 | return RepCodeEnum.NULL_ERROR.parseError("类型"); | 70 | return RepCodeEnum.NULL_ERROR.parseError("类型"); |
| 69 | } | 71 | } |
| 70 | - if (StringUtils.isEmpty(captchaVO.getToken())) { | 72 | + if (StrUtil.isEmpty(captchaVO.getToken())) { |
| 71 | return RepCodeEnum.NULL_ERROR.parseError("token"); | 73 | return RepCodeEnum.NULL_ERROR.parseError("token"); |
| 72 | } | 74 | } |
| 73 | return getService(captchaVO.getCaptchaType()).check(captchaVO); | 75 | return getService(captchaVO.getCaptchaType()).check(captchaVO); |
| @@ -78,7 +80,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | @@ -78,7 +80,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | ||
| 78 | if (captchaVO == null) { | 80 | if (captchaVO == null) { |
| 79 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); | 81 | return RepCodeEnum.NULL_ERROR.parseError("captchaVO"); |
| 80 | } | 82 | } |
| 81 | - if (StringUtils.isEmpty(captchaVO.getCaptchaVerification())) { | 83 | + if (StrUtil.isEmpty(captchaVO.getCaptchaVerification())) { |
| 82 | return RepCodeEnum.NULL_ERROR.parseError("二次校验参数"); | 84 | return RepCodeEnum.NULL_ERROR.parseError("二次校验参数"); |
| 83 | } | 85 | } |
| 84 | try { | 86 | try { |
| @@ -89,7 +91,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | @@ -89,7 +91,7 @@ public class DefaultCaptchaServiceImpl extends AbstractCaptchaService{ | ||
| 89 | //二次校验取值后,即刻失效 | 91 | //二次校验取值后,即刻失效 |
| 90 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); | 92 | CaptchaServiceFactory.getCache(cacheType).delete(codeKey); |
| 91 | } catch (Exception e) { | 93 | } catch (Exception e) { |
| 92 | - logger.error("验证码坐标解析失败", e); | 94 | + log.error("验证码坐标解析失败", e); |
| 93 | return ResponseModel.errorMsg(e.getMessage()); | 95 | return ResponseModel.errorMsg(e.getMessage()); |
| 94 | } | 96 | } |
| 95 | return ResponseModel.success(); | 97 | return ResponseModel.success(); |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/service/impl/FrequencyLimitHandler.java
| 1 | package com.anji.captcha.service.impl; | 1 | package com.anji.captcha.service.impl; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 3 | import com.anji.captcha.model.common.Const; | 4 | import com.anji.captcha.model.common.Const; |
| 4 | import com.anji.captcha.model.common.RepCodeEnum; | 5 | import com.anji.captcha.model.common.RepCodeEnum; |
| 5 | import com.anji.captcha.model.common.ResponseModel; | 6 | import com.anji.captcha.model.common.ResponseModel; |
| 6 | import com.anji.captcha.model.vo.CaptchaVO; | 7 | import com.anji.captcha.model.vo.CaptchaVO; |
| 7 | import com.anji.captcha.service.CaptchaCacheService; | 8 | import com.anji.captcha.service.CaptchaCacheService; |
| 8 | -import com.anji.captcha.util.StringUtils; | ||
| 9 | 9 | ||
| 10 | import java.util.Objects; | 10 | import java.util.Objects; |
| 11 | import java.util.Properties; | 11 | import java.util.Properties; |
| @@ -66,15 +66,15 @@ public interface FrequencyLimitHandler { | @@ -66,15 +66,15 @@ public interface FrequencyLimitHandler { | ||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | private String getClientCId(CaptchaVO input, String type) { | 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 | @Override | 72 | @Override |
| 73 | public ResponseModel validateGet(CaptchaVO d) { | 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 | String getKey = getClientCId(d, "GET"); | 78 | String getKey = getClientCId(d, "GET"); |
| 79 | String lockKey = getClientCId(d, "LOCK"); | 79 | String lockKey = getClientCId(d, "LOCK"); |
| 80 | // 失败次数过多,锁定 | 80 | // 失败次数过多,锁定 |
| @@ -88,7 +88,7 @@ public interface FrequencyLimitHandler { | @@ -88,7 +88,7 @@ public interface FrequencyLimitHandler { | ||
| 88 | } | 88 | } |
| 89 | cacheService.increment(getKey, 1); | 89 | cacheService.increment(getKey, 1); |
| 90 | // 1分钟内请求次数过多 | 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 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_GET_ERROR); | 92 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_GET_ERROR); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -100,9 +100,9 @@ public interface FrequencyLimitHandler { | @@ -100,9 +100,9 @@ public interface FrequencyLimitHandler { | ||
| 100 | return null; | 100 | return null; |
| 101 | } | 101 | } |
| 102 | // 1分钟内失败5次 | 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 | // get接口锁定5分钟 | 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 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LOCK_GET_ERROR); | 106 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LOCK_GET_ERROR); |
| 107 | } | 107 | } |
| 108 | return null; | 108 | return null; |
| @@ -110,10 +110,10 @@ public interface FrequencyLimitHandler { | @@ -110,10 +110,10 @@ public interface FrequencyLimitHandler { | ||
| 110 | 110 | ||
| 111 | @Override | 111 | @Override |
| 112 | public ResponseModel validateCheck(CaptchaVO d) { | 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 | /*String getKey = getClientCId(d, "GET"); | 117 | /*String getKey = getClientCId(d, "GET"); |
| 118 | if(Objects.isNull(cacheService.get(getKey))){ | 118 | if(Objects.isNull(cacheService.get(getKey))){ |
| 119 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_INVALID); | 119 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_INVALID); |
| @@ -125,7 +125,7 @@ public interface FrequencyLimitHandler { | @@ -125,7 +125,7 @@ public interface FrequencyLimitHandler { | ||
| 125 | v = "1"; | 125 | v = "1"; |
| 126 | } | 126 | } |
| 127 | cacheService.increment(key, 1); | 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 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_CHECK_ERROR); | 129 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_CHECK_ERROR); |
| 130 | } | 130 | } |
| 131 | return null; | 131 | return null; |
| @@ -144,7 +144,7 @@ public interface FrequencyLimitHandler { | @@ -144,7 +144,7 @@ public interface FrequencyLimitHandler { | ||
| 144 | v = "1"; | 144 | v = "1"; |
| 145 | } | 145 | } |
| 146 | cacheService.increment(key, 1); | 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 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_VERIFY_ERROR); | 148 | return ResponseModel.errorMsg(RepCodeEnum.API_REQ_LIMIT_VERIFY_ERROR); |
| 149 | } | 149 | } |
| 150 | return null; | 150 | return null; |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/AESUtil.java
| @@ -7,10 +7,13 @@ | @@ -7,10 +7,13 @@ | ||
| 7 | package com.anji.captcha.util; | 7 | package com.anji.captcha.util; |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | +import cn.hutool.core.util.StrUtil; | ||
| 11 | + | ||
| 10 | import javax.crypto.Cipher; | 12 | import javax.crypto.Cipher; |
| 11 | import javax.crypto.KeyGenerator; | 13 | import javax.crypto.KeyGenerator; |
| 12 | import javax.crypto.spec.SecretKeySpec; | 14 | import javax.crypto.spec.SecretKeySpec; |
| 13 | import java.math.BigInteger; | 15 | import java.math.BigInteger; |
| 16 | +import java.nio.charset.StandardCharsets; | ||
| 14 | import java.util.Base64; | 17 | import java.util.Base64; |
| 15 | 18 | ||
| 16 | 19 | ||
| @@ -20,6 +23,7 @@ public class AESUtil { | @@ -20,6 +23,7 @@ public class AESUtil { | ||
| 20 | 23 | ||
| 21 | /** | 24 | /** |
| 22 | * 获取随机key | 25 | * 获取随机key |
| 26 | + * | ||
| 23 | * @return | 27 | * @return |
| 24 | */ | 28 | */ |
| 25 | public static String getKey() { | 29 | public static String getKey() { |
| @@ -29,39 +33,43 @@ public class AESUtil { | @@ -29,39 +33,43 @@ public class AESUtil { | ||
| 29 | 33 | ||
| 30 | /** | 34 | /** |
| 31 | * 将byte[]转为各种进制的字符串 | 35 | * 将byte[]转为各种进制的字符串 |
| 36 | + * | ||
| 32 | * @param bytes byte[] | 37 | * @param bytes byte[] |
| 33 | * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 | 38 | * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 |
| 34 | * @return 转换后的字符串 | 39 | * @return 转换后的字符串 |
| 35 | */ | 40 | */ |
| 36 | - public static String binary(byte[] bytes, int radix){ | 41 | + public static String binary(byte[] bytes, int radix) { |
| 37 | return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 | 42 | return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 |
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | /** | 45 | /** |
| 41 | * base 64 encode | 46 | * base 64 encode |
| 47 | + * | ||
| 42 | * @param bytes 待编码的byte[] | 48 | * @param bytes 待编码的byte[] |
| 43 | * @return 编码后的base 64 code | 49 | * @return 编码后的base 64 code |
| 44 | */ | 50 | */ |
| 45 | - public static String base64Encode(byte[] bytes){ | 51 | + public static String base64Encode(byte[] bytes) { |
| 46 | //return Base64.encodeBase64String(bytes); | 52 | //return Base64.encodeBase64String(bytes); |
| 47 | return Base64.getEncoder().encodeToString(bytes); | 53 | return Base64.getEncoder().encodeToString(bytes); |
| 48 | } | 54 | } |
| 49 | 55 | ||
| 50 | /** | 56 | /** |
| 51 | * base 64 decode | 57 | * base 64 decode |
| 58 | + * | ||
| 52 | * @param base64Code 待解码的base 64 code | 59 | * @param base64Code 待解码的base 64 code |
| 53 | * @return 解码后的byte[] | 60 | * @return 解码后的byte[] |
| 54 | * @throws Exception | 61 | * @throws Exception |
| 55 | */ | 62 | */ |
| 56 | - public static byte[] base64Decode(String base64Code) throws Exception{ | 63 | + public static byte[] base64Decode(String base64Code) throws Exception { |
| 57 | Base64.Decoder decoder = Base64.getDecoder(); | 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 | * AES加密 | 70 | * AES加密 |
| 64 | - * @param content 待加密的内容 | 71 | + * |
| 72 | + * @param content 待加密的内容 | ||
| 65 | * @param encryptKey 加密密钥 | 73 | * @param encryptKey 加密密钥 |
| 66 | * @return 加密后的byte[] | 74 | * @return 加密后的byte[] |
| 67 | * @throws Exception | 75 | * @throws Exception |
| @@ -72,19 +80,20 @@ public class AESUtil { | @@ -72,19 +80,20 @@ public class AESUtil { | ||
| 72 | Cipher cipher = Cipher.getInstance(ALGORITHMSTR); | 80 | Cipher cipher = Cipher.getInstance(ALGORITHMSTR); |
| 73 | cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES")); | 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 | * AES加密为base 64 code | 88 | * AES加密为base 64 code |
| 81 | - * @param content 待加密的内容 | 89 | + * |
| 90 | + * @param content 待加密的内容 | ||
| 82 | * @param encryptKey 加密密钥 | 91 | * @param encryptKey 加密密钥 |
| 83 | * @return 加密后的base 64 code | 92 | * @return 加密后的base 64 code |
| 84 | * @throws Exception | 93 | * @throws Exception |
| 85 | */ | 94 | */ |
| 86 | public static String aesEncrypt(String content, String encryptKey) throws Exception { | 95 | public static String aesEncrypt(String content, String encryptKey) throws Exception { |
| 87 | - if (StringUtils.isBlank(encryptKey)) { | 96 | + if (StrUtil.isBlank(encryptKey)) { |
| 88 | return content; | 97 | return content; |
| 89 | } | 98 | } |
| 90 | return base64Encode(aesEncryptToBytes(content, encryptKey)); | 99 | return base64Encode(aesEncryptToBytes(content, encryptKey)); |
| @@ -92,8 +101,9 @@ public class AESUtil { | @@ -92,8 +101,9 @@ public class AESUtil { | ||
| 92 | 101 | ||
| 93 | /** | 102 | /** |
| 94 | * AES解密 | 103 | * AES解密 |
| 104 | + * | ||
| 95 | * @param encryptBytes 待解密的byte[] | 105 | * @param encryptBytes 待解密的byte[] |
| 96 | - * @param decryptKey 解密密钥 | 106 | + * @param decryptKey 解密密钥 |
| 97 | * @return 解密后的String | 107 | * @return 解密后的String |
| 98 | * @throws Exception | 108 | * @throws Exception |
| 99 | */ | 109 | */ |
| @@ -110,16 +120,17 @@ public class AESUtil { | @@ -110,16 +120,17 @@ public class AESUtil { | ||
| 110 | 120 | ||
| 111 | /** | 121 | /** |
| 112 | * 将base 64 code AES解密 | 122 | * 将base 64 code AES解密 |
| 123 | + * | ||
| 113 | * @param encryptStr 待解密的base 64 code | 124 | * @param encryptStr 待解密的base 64 code |
| 114 | * @param decryptKey 解密密钥 | 125 | * @param decryptKey 解密密钥 |
| 115 | * @return 解密后的string | 126 | * @return 解密后的string |
| 116 | * @throws Exception | 127 | * @throws Exception |
| 117 | */ | 128 | */ |
| 118 | public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { | 129 | public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { |
| 119 | - if (StringUtils.isBlank(decryptKey)) { | 130 | + if (StrUtil.isBlank(decryptKey)) { |
| 120 | return encryptStr; | 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,8 +24,9 @@ public final class CacheUtil { | ||
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * 初始化 | 26 | * 初始化 |
| 27 | + * | ||
| 27 | * @param cacheMaxNumber 缓存最大个数 | 28 | * @param cacheMaxNumber 缓存最大个数 |
| 28 | - * @param second 定时任务 秒执行清除过期缓存 | 29 | + * @param second 定时任务 秒执行清除过期缓存 |
| 29 | */ | 30 | */ |
| 30 | public static void init(int cacheMaxNumber, long second) { | 31 | public static void init(int cacheMaxNumber, long second) { |
| 31 | CACHE_MAX_NUMBER = cacheMaxNumber; | 32 | CACHE_MAX_NUMBER = cacheMaxNumber; |
| @@ -37,27 +38,25 @@ public final class CacheUtil { | @@ -37,27 +38,25 @@ public final class CacheUtil { | ||
| 37 | refresh(); | 38 | refresh(); |
| 38 | } | 39 | } |
| 39 | }, 0, second * 1000);*/ | 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 | scheduledExecutor.scheduleAtFixedRate(new Runnable() { | 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 | logger.debug("local缓存刷新,清除过期数据"); | 60 | logger.debug("local缓存刷新,清除过期数据"); |
| 62 | for (String key : CACHE_MAP.keySet()) { | 61 | for (String key : CACHE_MAP.keySet()) { |
| 63 | exists(key); | 62 | exists(key); |
| @@ -65,24 +64,24 @@ public final class CacheUtil { | @@ -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 | //设置阈值,达到即clear缓存 | 68 | //设置阈值,达到即clear缓存 |
| 70 | if (CACHE_MAP.size() > CACHE_MAX_NUMBER * 2) { | 69 | if (CACHE_MAP.size() > CACHE_MAX_NUMBER * 2) { |
| 71 | logger.info("CACHE_MAP达到阈值,clear map"); | 70 | logger.info("CACHE_MAP达到阈值,clear map"); |
| 72 | clear(); | 71 | clear(); |
| 73 | } | 72 | } |
| 74 | CACHE_MAP.put(key, value); | 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 | CACHE_MAP.remove(key); | 80 | CACHE_MAP.remove(key); |
| 82 | CACHE_MAP.remove(key + "_HoldTime"); | 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 | Long cacheHoldTime = (Long) CACHE_MAP.get(key + "_HoldTime"); | 85 | Long cacheHoldTime = (Long) CACHE_MAP.get(key + "_HoldTime"); |
| 87 | if (cacheHoldTime == null || cacheHoldTime == 0L) { | 86 | if (cacheHoldTime == null || cacheHoldTime == 0L) { |
| 88 | return false; | 87 | return false; |
| @@ -95,9 +94,9 @@ public final class CacheUtil { | @@ -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 | if (exists(key)) { | 98 | if (exists(key)) { |
| 100 | - return (String)CACHE_MAP.get(key); | 99 | + return (String) CACHE_MAP.get(key); |
| 101 | } | 100 | } |
| 102 | return null; | 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,7 +18,7 @@ public abstract class FileCopyUtils { | ||
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | public static void copy(byte[] in, File out) throws IOException { | 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 | public static byte[] copyToByteArray(File in) throws IOException { | 24 | public static byte[] copyToByteArray(File in) throws IOException { |
| @@ -63,7 +63,7 @@ public abstract class FileCopyUtils { | @@ -63,7 +63,7 @@ public abstract class FileCopyUtils { | ||
| 63 | return new byte[0]; | 63 | return new byte[0]; |
| 64 | } else { | 64 | } else { |
| 65 | ByteArrayOutputStream out = new ByteArrayOutputStream(4096); | 65 | ByteArrayOutputStream out = new ByteArrayOutputStream(4096); |
| 66 | - copy((InputStream)in, (OutputStream)out); | 66 | + copy((InputStream) in, (OutputStream) out); |
| 67 | return out.toByteArray(); | 67 | return out.toByteArray(); |
| 68 | } | 68 | } |
| 69 | } | 69 | } |
| @@ -74,13 +74,12 @@ public abstract class FileCopyUtils { | @@ -74,13 +74,12 @@ public abstract class FileCopyUtils { | ||
| 74 | char[] buffer = new char[4096]; | 74 | char[] buffer = new char[4096]; |
| 75 | 75 | ||
| 76 | int bytesRead; | 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 | out.write(buffer, 0, bytesRead); | 78 | out.write(buffer, 0, bytesRead); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | out.flush(); | 81 | out.flush(); |
| 82 | - int var5 = byteCount; | ||
| 83 | - return var5; | 82 | + return byteCount; |
| 84 | } finally { | 83 | } finally { |
| 85 | try { | 84 | try { |
| 86 | in.close(); | 85 | in.close(); |
| @@ -113,7 +112,7 @@ public abstract class FileCopyUtils { | @@ -113,7 +112,7 @@ public abstract class FileCopyUtils { | ||
| 113 | return ""; | 112 | return ""; |
| 114 | } else { | 113 | } else { |
| 115 | StringWriter out = new StringWriter(); | 114 | StringWriter out = new StringWriter(); |
| 116 | - copy((Reader)in, (Writer)out); | 115 | + copy((Reader) in, (Writer) out); |
| 117 | return out.toString(); | 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,9 +6,10 @@ | ||
| 6 | */ | 6 | */ |
| 7 | package com.anji.captcha.util; | 7 | package com.anji.captcha.util; |
| 8 | 8 | ||
| 9 | +import cn.hutool.core.util.StrUtil; | ||
| 9 | import com.anji.captcha.model.common.CaptchaBaseMapEnum; | 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 | import javax.imageio.ImageIO; | 14 | import javax.imageio.ImageIO; |
| 14 | import java.awt.image.BufferedImage; | 15 | import java.awt.image.BufferedImage; |
| @@ -19,9 +20,8 @@ import java.util.HashMap; | @@ -19,9 +20,8 @@ import java.util.HashMap; | ||
| 19 | import java.util.Map; | 20 | import java.util.Map; |
| 20 | import java.util.concurrent.ConcurrentHashMap; | 21 | import java.util.concurrent.ConcurrentHashMap; |
| 21 | 22 | ||
| 22 | - | 23 | +@Slf4j |
| 23 | public class ImageUtils { | 24 | public class ImageUtils { |
| 24 | - private static Logger logger = LoggerFactory.getLogger(ImageUtils.class); | ||
| 25 | private static Map<String, String> originalCacheMap = new ConcurrentHashMap(); //滑块底图 | 25 | private static Map<String, String> originalCacheMap = new ConcurrentHashMap(); //滑块底图 |
| 26 | private static Map<String, String> slidingBlockCacheMap = new ConcurrentHashMap(); //滑块 | 26 | private static Map<String, String> slidingBlockCacheMap = new ConcurrentHashMap(); //滑块 |
| 27 | private static Map<String, String> picClickCacheMap = new ConcurrentHashMap(); //点选文字 | 27 | private static Map<String, String> picClickCacheMap = new ConcurrentHashMap(); //点选文字 |
| @@ -29,7 +29,7 @@ public class ImageUtils { | @@ -29,7 +29,7 @@ public class ImageUtils { | ||
| 29 | 29 | ||
| 30 | public static void cacheImage(String captchaOriginalPathJigsaw, String captchaOriginalPathClick) { | 30 | public static void cacheImage(String captchaOriginalPathJigsaw, String captchaOriginalPathClick) { |
| 31 | //滑动拼图 | 31 | //滑动拼图 |
| 32 | - if (StringUtils.isBlank(captchaOriginalPathJigsaw)) { | 32 | + if (StrUtil.isBlank(captchaOriginalPathJigsaw)) { |
| 33 | originalCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/original")); | 33 | originalCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/original")); |
| 34 | slidingBlockCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/slidingBlock")); | 34 | slidingBlockCacheMap.putAll(getResourcesImagesFile("defaultImages/jigsaw/slidingBlock")); |
| 35 | } else { | 35 | } else { |
| @@ -37,7 +37,7 @@ public class ImageUtils { | @@ -37,7 +37,7 @@ public class ImageUtils { | ||
| 37 | slidingBlockCacheMap.putAll(getImagesFile(captchaOriginalPathJigsaw + File.separator + "slidingBlock")); | 37 | slidingBlockCacheMap.putAll(getImagesFile(captchaOriginalPathJigsaw + File.separator + "slidingBlock")); |
| 38 | } | 38 | } |
| 39 | //点选文字 | 39 | //点选文字 |
| 40 | - if (StringUtils.isBlank(captchaOriginalPathClick)) { | 40 | + if (StrUtil.isBlank(captchaOriginalPathClick)) { |
| 41 | picClickCacheMap.putAll(getResourcesImagesFile("defaultImages/pic-click")); | 41 | picClickCacheMap.putAll(getResourcesImagesFile("defaultImages/pic-click")); |
| 42 | } else { | 42 | } else { |
| 43 | picClickCacheMap.putAll(getImagesFile(captchaOriginalPathClick)); | 43 | picClickCacheMap.putAll(getImagesFile(captchaOriginalPathClick)); |
| @@ -45,7 +45,7 @@ public class ImageUtils { | @@ -45,7 +45,7 @@ public class ImageUtils { | ||
| 45 | fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); | 45 | fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); |
| 46 | fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); | 46 | fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); |
| 47 | fileNameMap.put(CaptchaBaseMapEnum.PIC_CLICK.getCodeValue(), picClickCacheMap.keySet().toArray(new String[0])); | 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 | public static void cacheBootImage(Map<String, String> originalMap, Map<String, String> slidingBlockMap, Map<String, String> picClickMap) { | 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,7 +55,7 @@ public class ImageUtils { | ||
| 55 | fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); | 55 | fileNameMap.put(CaptchaBaseMapEnum.ORIGINAL.getCodeValue(), originalCacheMap.keySet().toArray(new String[0])); |
| 56 | fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); | 56 | fileNameMap.put(CaptchaBaseMapEnum.SLIDING_BLOCK.getCodeValue(), slidingBlockCacheMap.keySet().toArray(new String[0])); |
| 57 | fileNameMap.put(CaptchaBaseMapEnum.PIC_CLICK.getCodeValue(), picClickCacheMap.keySet().toArray(new String[0])); | 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,8 +75,7 @@ public class ImageUtils { | ||
| 75 | return null; | 75 | return null; |
| 76 | } | 76 | } |
| 77 | Integer randomInt = RandomUtils.getRandomInt(0, strings.length); | 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 | public static BufferedImage getPicClick() { | 81 | public static BufferedImage getPicClick() { |
| @@ -160,8 +159,6 @@ public class ImageUtils { | @@ -160,8 +159,6 @@ public class ImageUtils { | ||
| 160 | byte[] bytes = FileCopyUtils.copyToByteArray(fileInputStream); | 159 | byte[] bytes = FileCopyUtils.copyToByteArray(fileInputStream); |
| 161 | String string = Base64Utils.encodeToString(bytes); | 160 | String string = Base64Utils.encodeToString(bytes); |
| 162 | imgMap.put(item.getName(), string); | 161 | imgMap.put(item.getName(), string); |
| 163 | - } catch (FileNotFoundException e) { | ||
| 164 | - e.printStackTrace(); | ||
| 165 | } catch (IOException e) { | 162 | } catch (IOException e) { |
| 166 | e.printStackTrace(); | 163 | e.printStackTrace(); |
| 167 | } | 164 | } |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/com/anji/captcha/util/JsonUtil.java
| 1 | package com.anji.captcha.util; | 1 | package com.anji.captcha.util; |
| 2 | 2 | ||
| 3 | import com.anji.captcha.model.vo.PointVO; | 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 | import java.util.ArrayList; | 6 | import java.util.ArrayList; |
| 8 | import java.util.List; | 7 | import java.util.List; |
| @@ -12,63 +11,63 @@ import java.util.Map; | @@ -12,63 +11,63 @@ import java.util.Map; | ||
| 12 | * 替换掉fastjson,自定义实现相关方法 | 11 | * 替换掉fastjson,自定义实现相关方法 |
| 13 | * note: 该实现不具有通用性,仅用于本项目。 | 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 | public class JsonUtil { | 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 | /*if(!clazz.isAssignableFrom(PointVO.class)) { | 37 | /*if(!clazz.isAssignableFrom(PointVO.class)) { |
| 39 | throw new UnsupportedOperationException("不支持的输入类型:" | 38 | throw new UnsupportedOperationException("不支持的输入类型:" |
| 40 | + clazz.getSimpleName()); | 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 | package com.anji.captcha.util; | 1 | package com.anji.captcha.util; |
| 2 | 2 | ||
| 3 | +import java.nio.charset.StandardCharsets; | ||
| 3 | import java.security.MessageDigest; | 4 | import java.security.MessageDigest; |
| 4 | 5 | ||
| 5 | /** | 6 | /** |
| @@ -8,17 +9,18 @@ import java.security.MessageDigest; | @@ -8,17 +9,18 @@ import java.security.MessageDigest; | ||
| 8 | public abstract class MD5Util { | 9 | public abstract class MD5Util { |
| 9 | /** | 10 | /** |
| 10 | * 获取指定字符串的md5值 | 11 | * 获取指定字符串的md5值 |
| 12 | + * | ||
| 11 | * @param dataStr 明文 | 13 | * @param dataStr 明文 |
| 12 | * @return String | 14 | * @return String |
| 13 | */ | 15 | */ |
| 14 | public static String md5(String dataStr) { | 16 | public static String md5(String dataStr) { |
| 15 | try { | 17 | try { |
| 16 | MessageDigest m = MessageDigest.getInstance("MD5"); | 18 | MessageDigest m = MessageDigest.getInstance("MD5"); |
| 17 | - m.update(dataStr.getBytes("UTF8")); | 19 | + m.update(dataStr.getBytes(StandardCharsets.UTF_8)); |
| 18 | byte[] s = m.digest(); | 20 | byte[] s = m.digest(); |
| 19 | StringBuilder result = new StringBuilder(); | 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 | return result.toString(); | 25 | return result.toString(); |
| 24 | } catch (Exception e) { | 26 | } catch (Exception e) { |
| @@ -29,10 +31,11 @@ public abstract class MD5Util { | @@ -29,10 +31,11 @@ public abstract class MD5Util { | ||
| 29 | 31 | ||
| 30 | /** | 32 | /** |
| 31 | * 获取指定字符串的md5值, md5(str+salt) | 33 | * 获取指定字符串的md5值, md5(str+salt) |
| 34 | + * | ||
| 32 | * @param dataStr 明文 | 35 | * @param dataStr 明文 |
| 33 | * @return String | 36 | * @return String |
| 34 | */ | 37 | */ |
| 35 | - public static String md5WithSalt(String dataStr,String salt) { | 38 | + public static String md5WithSalt(String dataStr, String salt) { |
| 36 | return md5(dataStr + salt); | 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,11 +31,10 @@ public class RandomUtils { | ||
| 31 | * @return | 31 | * @return |
| 32 | */ | 32 | */ |
| 33 | public static String getRandomHan(String hanZi) { | 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 | return ThreadLocalRandom.current().nextInt(bound); | 38 | return ThreadLocalRandom.current().nextInt(bound); |
| 40 | } | 39 | } |
| 41 | 40 | ||
| @@ -68,25 +67,27 @@ public class RandomUtils { | @@ -68,25 +67,27 @@ public class RandomUtils { | ||
| 68 | 67 | ||
| 69 | /** | 68 | /** |
| 70 | * 随机范围内数字 | 69 | * 随机范围内数字 |
| 70 | + * | ||
| 71 | * @param startNum | 71 | * @param startNum |
| 72 | * @param endNum | 72 | * @param endNum |
| 73 | * @return | 73 | * @return |
| 74 | */ | 74 | */ |
| 75 | public static Integer getRandomInt(int startNum, int endNum) { | 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 | * @param length | 82 | * @param length |
| 82 | * @return | 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 | sb.append(str.charAt(number)); | 91 | sb.append(str.charAt(number)); |
| 91 | } | 92 | } |
| 92 | return sb.toString(); | 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,7 +19,7 @@ public abstract class StreamUtils { | ||
| 19 | return new byte[0]; | 19 | return new byte[0]; |
| 20 | } else { | 20 | } else { |
| 21 | ByteArrayOutputStream out = new ByteArrayOutputStream(4096); | 21 | ByteArrayOutputStream out = new ByteArrayOutputStream(4096); |
| 22 | - copy((InputStream)in, out); | 22 | + copy((InputStream) in, out); |
| 23 | return out.toByteArray(); | 23 | return out.toByteArray(); |
| 24 | } | 24 | } |
| 25 | } | 25 | } |
| @@ -31,10 +31,9 @@ public abstract class StreamUtils { | @@ -31,10 +31,9 @@ public abstract class StreamUtils { | ||
| 31 | StringBuilder out = new StringBuilder(); | 31 | StringBuilder out = new StringBuilder(); |
| 32 | InputStreamReader reader = new InputStreamReader(in, charset); | 32 | InputStreamReader reader = new InputStreamReader(in, charset); |
| 33 | char[] buffer = new char[4096]; | 33 | char[] buffer = new char[4096]; |
| 34 | - boolean var5 = true; | ||
| 35 | 34 | ||
| 36 | int bytesRead; | 35 | int bytesRead; |
| 37 | - while((bytesRead = reader.read(buffer)) != -1) { | 36 | + while ((bytesRead = reader.read(buffer)) != -1) { |
| 38 | out.append(buffer, 0, bytesRead); | 37 | out.append(buffer, 0, bytesRead); |
| 39 | } | 38 | } |
| 40 | 39 | ||
| @@ -57,7 +56,7 @@ public abstract class StreamUtils { | @@ -57,7 +56,7 @@ public abstract class StreamUtils { | ||
| 57 | byte[] buffer = new byte[4096]; | 56 | byte[] buffer = new byte[4096]; |
| 58 | 57 | ||
| 59 | int bytesRead; | 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 | out.write(buffer, 0, bytesRead); | 60 | out.write(buffer, 0, bytesRead); |
| 62 | } | 61 | } |
| 63 | 62 | ||
| @@ -73,17 +72,17 @@ public abstract class StreamUtils { | @@ -73,17 +72,17 @@ public abstract class StreamUtils { | ||
| 73 | long bytesToCopy = end - start + 1L; | 72 | long bytesToCopy = end - start + 1L; |
| 74 | byte[] buffer = new byte[4096]; | 73 | byte[] buffer = new byte[4096]; |
| 75 | 74 | ||
| 76 | - while(bytesToCopy > 0L) { | 75 | + while (bytesToCopy > 0L) { |
| 77 | int bytesRead = in.read(buffer); | 76 | int bytesRead = in.read(buffer); |
| 78 | if (bytesRead == -1) { | 77 | if (bytesRead == -1) { |
| 79 | break; | 78 | break; |
| 80 | } | 79 | } |
| 81 | 80 | ||
| 82 | - if ((long)bytesRead <= bytesToCopy) { | 81 | + if ((long) bytesRead <= bytesToCopy) { |
| 83 | out.write(buffer, 0, bytesRead); | 82 | out.write(buffer, 0, bytesRead); |
| 84 | - bytesToCopy -= (long)bytesRead; | 83 | + bytesToCopy -= (long) bytesRead; |
| 85 | } else { | 84 | } else { |
| 86 | - out.write(buffer, 0, (int)bytesToCopy); | 85 | + out.write(buffer, 0, (int) bytesToCopy); |
| 87 | bytesToCopy = 0L; | 86 | bytesToCopy = 0L; |
| 88 | } | 87 | } |
| 89 | } | 88 | } |
| @@ -96,7 +95,7 @@ public abstract class StreamUtils { | @@ -96,7 +95,7 @@ public abstract class StreamUtils { | ||
| 96 | byte[] buffer = new byte[4096]; | 95 | byte[] buffer = new byte[4096]; |
| 97 | int byteCount; | 96 | int byteCount; |
| 98 | int bytesRead; | 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 | return byteCount; | 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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.system.controller.admin.captcha; | 1 | package cn.iocoder.yudao.module.system.controller.admin.captcha; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 3 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | 4 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 4 | import com.anji.captcha.model.common.ResponseModel; | 5 | import com.anji.captcha.model.common.ResponseModel; |
| 5 | import com.anji.captcha.model.vo.CaptchaVO; | 6 | import com.anji.captcha.model.vo.CaptchaVO; |
| 7 | +import com.anji.captcha.service.CaptchaService; | ||
| 6 | import io.swagger.annotations.Api; | 8 | import io.swagger.annotations.Api; |
| 7 | import io.swagger.annotations.ApiOperation; | 9 | import io.swagger.annotations.ApiOperation; |
| 8 | import org.springframework.web.bind.annotation.PostMapping; | 10 | import org.springframework.web.bind.annotation.PostMapping; |
| @@ -10,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody; | @@ -10,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody; | ||
| 10 | import org.springframework.web.bind.annotation.RequestMapping; | 12 | import org.springframework.web.bind.annotation.RequestMapping; |
| 11 | import org.springframework.web.bind.annotation.RestController; | 13 | import org.springframework.web.bind.annotation.RestController; |
| 12 | 14 | ||
| 15 | +import javax.annotation.Resource; | ||
| 13 | import javax.annotation.security.PermitAll; | 16 | import javax.annotation.security.PermitAll; |
| 14 | import javax.servlet.http.HttpServletRequest; | 17 | import javax.servlet.http.HttpServletRequest; |
| 15 | 18 | ||
| @@ -24,24 +27,46 @@ import javax.servlet.http.HttpServletRequest; | @@ -24,24 +27,46 @@ import javax.servlet.http.HttpServletRequest; | ||
| 24 | @Api(tags = "管理后台 - 验证码") | 27 | @Api(tags = "管理后台 - 验证码") |
| 25 | @RestController("adminCaptchaController") | 28 | @RestController("adminCaptchaController") |
| 26 | @RequestMapping("/system/captcha") | 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 | @PostMapping({"/get"}) | 35 | @PostMapping({"/get"}) |
| 30 | @ApiOperation("获得验证码") | 36 | @ApiOperation("获得验证码") |
| 31 | @PermitAll | 37 | @PermitAll |
| 32 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 38 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 33 | - @Override | ||
| 34 | public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) { | 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 | @PostMapping("/check") | 45 | @PostMapping("/check") |
| 39 | @ApiOperation("校验验证码") | 46 | @ApiOperation("校验验证码") |
| 40 | @PermitAll | 47 | @PermitAll |
| 41 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 48 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 42 | - @Override | ||
| 43 | public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) { | 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 | } |