提交 a0e8ae4c 编写于 作者: 如梦技术's avatar 如梦技术 🐛

🔖 0.0.1-RC3

上级 f44ebd55
# 变更记录
## 发行版本
## [0.0.1-RC3] - 2019-03-05
- :loud_sound: 优化`请求日志`,避免并发下顺序错乱。
- :pushpin: 升级 `mica-auto`
- :zap: 优化UUID,采用 java9的方式,提高性能。
- :heavy_plus_sign: bom 添加 `mica-pro` 依赖。
- :loud_sound: 异常事件添加触发时间。
- :pencil2: fix spelling issue about black -> blank。 `感谢:` github @xkcoding
- :zap: 优化日志,`spring boot admin` 中显示 `info` 日志。
- :zap: 升级 gradle 版本到 `5.2.1`
## [0.0.1-RC2] - 2019-02-19
- 修复 `PathUtil` 导包问题。
- 优化 `mica props`
- 优化 `Bean copy` 逻辑。
## [0.0.1-RC1] - 2019-01-23
### 初始化项目
- `mica-bom` 依赖 bom。
......
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
......@@ -2,6 +2,7 @@ dependencies {
api project(":mica-core")
implementation "org.springframework.boot:spring-boot-autoconfigure"
compileOnly "org.springframework.cloud:spring-cloud-context"
compileOnly "io.springfox:springfox-swagger2:${swaggerVersion}"
annotationProcessor "net.dreamlu:mica-auto:${micaAutoVersion}"
testImplementation project(":mica-boot-test")
}
......@@ -16,15 +16,22 @@
package net.dreamlu.mica.captcha;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.Base64Util;
import net.dreamlu.mica.core.utils.StringUtil;
import org.springframework.cache.Cache;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.util.concurrent.ThreadLocalRandom;
/**
* BaseCaptcha
*
* @author L.cm
*/
@Slf4j
public abstract class BaseCaptcha {
protected static final String DEFAULT_COOKIE_NAME = "mica-captcha";
protected static final String DEFAULT_CHACHE_NAME = "micaCaptchaCache";
......@@ -59,6 +66,10 @@ public abstract class BaseCaptcha {
this.cookieName = cookieName;
}
/**
* 图片输出的头,避免验证码被缓存
* @return HttpHeaders
*/
protected HttpHeaders getResponseHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setPragma("no-cache");
......@@ -68,4 +79,46 @@ public abstract class BaseCaptcha {
return headers;
}
/**
* 生成验证码-Base64
*
* @return {String}
*/
public ResponseEntity<Captcha> generateBase64() {
ThreadLocalRandom random = ThreadLocalRandom.current();
// 转成大写重要
String captchaCode = CaptchaUtils.generateCode(random).toUpperCase();
// 生成验证码
byte[] imgBytes = CaptchaUtils.generate(random, captchaCode);
String base64 = Base64Util.encodeToString(imgBytes);
String uuid = StringUtil.randomUUID();
// 保存验证码缓存
captchaCache.put(uuid, captchaCode);
Captcha captcha = new Captcha(uuid, base64);
return ResponseEntity.ok(captcha);
}
/**
* 校验 Base64 验证码
* @param uuid uuid
* @param userInputCaptcha 用户输入的验证码
* @return 是否成功
*/
public boolean validateBase64(String uuid, String userInputCaptcha) {
if (log.isInfoEnabled()) {
log.info("validate captcha userInputCaptcha is {}", userInputCaptcha);
}
String captchaCode = captchaCache.get(uuid, String.class);
if (StringUtil.isBlank(captchaCode)) {
return false;
}
// 转成大写重要
userInputCaptcha = userInputCaptcha.toUpperCase();
boolean result = userInputCaptcha.equals(captchaCode);
if (result) {
// 校验成功删除缓存
captchaCache.evict(uuid);
}
return result;
}
}
/*
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.dreamlu.mica.captcha;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.Serializable;
/**
* 验证码对象封装,用于传递到前端
*
* @author L.cm
*/
@Getter
@ApiModel("验证码模型")
@AllArgsConstructor
public class Captcha implements Serializable {
/**
* 用于传给前端,校验时携带
*/
@ApiModelProperty("验证码唯一id")
private final String uuid;
/**
* 图片 base64
*/
@ApiModelProperty("验证码图片(base64)")
private final String base64;
}
......@@ -19,7 +19,6 @@ package net.dreamlu.mica.captcha.reactive;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.captcha.BaseCaptcha;
import net.dreamlu.mica.captcha.CaptchaUtils;
import net.dreamlu.mica.core.utils.Base64Util;
import net.dreamlu.mica.core.utils.StringPool;
import net.dreamlu.mica.core.utils.StringUtil;
import org.springframework.cache.Cache;
......@@ -61,17 +60,6 @@ public class MicaCaptchaReactive extends BaseCaptcha {
return new ResponseEntity<>(resource, this.getResponseHeaders(), HttpStatus.OK);
}
/**
* 生成验证码
*
* @param exchange ServerWebExchange
* @return {String}
*/
public String generateBase64(ServerWebExchange exchange) {
// 生成验证码
return Base64Util.encodeToString(generateByteArray(exchange));
}
/**
* 生成验证码 byte array
*
......@@ -121,7 +109,7 @@ public class MicaCaptchaReactive extends BaseCaptcha {
String cookieValue = Optional.of(request.getCookies())
.map(x -> x.getFirst(cookieName))
.map(HttpCookie::getValue)
.orElseGet(null);
.orElse(null);
if (StringUtil.isBlank(cookieValue)) {
return false;
}
......@@ -133,6 +121,7 @@ public class MicaCaptchaReactive extends BaseCaptcha {
userInputCaptcha = userInputCaptcha.toUpperCase();
boolean result = userInputCaptcha.equals(captchaCode);
if (result) {
// 校验成功删除缓存和cookie
captchaCache.evict(cookieValue);
ResponseCookie cookie = ResponseCookie.from(cookieName, StringPool.EMPTY)
.maxAge(0)
......
......@@ -19,7 +19,6 @@ package net.dreamlu.mica.captcha.servlet;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.captcha.BaseCaptcha;
import net.dreamlu.mica.captcha.CaptchaUtils;
import net.dreamlu.mica.core.utils.Base64Util;
import net.dreamlu.mica.core.utils.StringUtil;
import net.dreamlu.mica.core.utils.WebUtil;
import org.springframework.cache.Cache;
......@@ -55,16 +54,6 @@ public class MicaCaptchaServlet extends BaseCaptcha {
return new ResponseEntity<>(resource, this.getResponseHeaders(), HttpStatus.OK );
}
/**
* 生成验证码
* @param response HttpServletResponse
* @return {String}
*/
public String generateBase64(HttpServletResponse response) {
// 生成验证码
return Base64Util.encodeToString(generateByteArray(response));
}
/**
* 生成验证码 byte array
* @param response HttpServletResponse
......@@ -115,6 +104,7 @@ public class MicaCaptchaServlet extends BaseCaptcha {
userInputCaptcha = userInputCaptcha.toUpperCase();
boolean result = userInputCaptcha.equals(captchaCode);
if (result) {
// 校验成功删除缓存和cookie
captchaCache.evict(cookieValue);
WebUtil.removeCookie(response, cookieName);
}
......
......@@ -110,7 +110,7 @@ public class BeanUtilTest {
user1.setIdx(new long[]{1,2,3,4,5,6});
user1.setName("张三");
// BeanUtil.toMap(user1);
BeanUtil.toMap(user1);
User user = new User();
user.setXx("123123");
......@@ -128,46 +128,46 @@ public class BeanUtilTest {
BeanUtil.copyNonNull(user1, userxx);
System.out.println(userxx);
// User userx = BeanUtil.copyWithConvert(user1, User.class);
// System.out.println(userx);
//
// UserChain userChain = BeanUtil.copy(user, UserChain.class);
// System.out.println(userChain);
//
// Map<String, Object> data = new HashMap<>();
// data.put("id", 1);
// UserChain userChainx = BeanUtil.copy(data, UserChain.class);
// System.out.println(userChainx);
//
// Map<String, Object> data1 = new HashMap<>();
// data1.put("id", 1);
// data1.put("name", 1);
// data1.put("photo", 1);
// data1.put("xx", 1);
// UserChain userChainx1 = BeanUtil.copyWithConvert(data1, UserChain.class);
// System.out.println(userChainx1);
//
// Map<String, Object> data2 = new HashMap<>();
// data2.put("id", 1);
// data2.put("name", "1");
// data2.put("photo", "1");
// data2.put("xx", "1");
// data2.put("a", new int[]{1,2,3});
// data2.put("allowNull", null);
//
// UserChain userChainxxxx = BeanUtil.toBean(data2, UserChain.class);
// System.out.println(userChainxxxx);
// Map<String, Object> dataxxxx = BeanUtil.toMap(userChainxxxx);
// System.out.println(dataxxxx);
//
// UserChain userChainNull = new UserChain();
// userChainNull.setAllowNull(10000);
// BeanUtil.copyNonNull(data2, userChainNull);
// System.out.println(userChainNull);
//
// UserChain userChainNonNull = new UserChain();
// userChainNonNull.setAllowNull(10000);
// BeanUtil.copy(data2, userChainNonNull);
// System.out.println(userChainNonNull);
User userxxx = BeanUtil.copyWithConvert(user1, User.class);
System.out.println(userxxx);
UserChain userChain = BeanUtil.copy(user, UserChain.class);
System.out.println(userChain);
Map<String, Object> data = new HashMap<>();
data.put("id", 1);
UserChain userChainx = BeanUtil.copy(data, UserChain.class);
System.out.println(userChainx);
Map<String, Object> data1 = new HashMap<>();
data1.put("id", 1);
data1.put("name", 1);
data1.put("photo", 1);
data1.put("xx", 1);
UserChain userChainx1 = BeanUtil.copyWithConvert(data1, UserChain.class);
System.out.println(userChainx1);
Map<String, Object> data2 = new HashMap<>();
data2.put("id", 1);
data2.put("name", "1");
data2.put("photo", "1");
data2.put("xx", "1");
data2.put("a", new int[]{1,2,3});
data2.put("allowNull", null);
UserChain userChainxxxx = BeanUtil.toBean(data2, UserChain.class);
System.out.println(userChainxxxx);
Map<String, Object> dataxxxx = BeanUtil.toMap(userChainxxxx);
System.out.println(dataxxxx);
UserChain userChainNull = new UserChain();
userChainNull.setAllowNull(10000);
BeanUtil.copyNonNull(data2, userChainNull);
System.out.println(userChainNull);
UserChain userChainNonNull = new UserChain();
userChainNonNull.setAllowNull(10000);
BeanUtil.copy(data2, userChainNonNull);
System.out.println(userChainNonNull);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册