Commit 435fc48c authored by 朱劲松​'s avatar 朱劲松​

refactor: just code refactor.

parent 6e4b8416
......@@ -10,7 +10,7 @@ public enum IncomeEnum {
CASH_AND_PAY_CARD("混合");
private String desc;
private IncomeEnum(String desc){
private IncomeEnum(String desc) {
this.desc = desc;
}
}
\ No newline at end of file
......@@ -16,7 +16,7 @@ public enum IncomeRangeEnum {
private String desc;
private IncomeRangeEnum(String desc){
private IncomeRangeEnum(String desc) {
this.desc = desc;
}
......
......@@ -6,113 +6,161 @@ package cn.quantgroup.xyqb;
*/
public interface Constants {
// zero fill with 4 chars...
String ZERO_FILL_TEMPLATE = "%04d";
String PASSWORD_SALT = "_lkb";
String IMAGE_CAPTCHA_KEY = "img_captcha:";
String REDIS_CAPTCHA_KEY = "auth:";
String REDIS_PREFIX_VERIFICATION_CODE = "verificationCode_";
//新版短信验证码计数
String REDIS_SMS_IP_COUNT = "SMS_Ip_verification_code_count:";
String REDIS_SMS_CODE_COUNT = "SMS_Phone_verification_code_count:";
String REDIS_SMS_DEVICE_COUNT = "SMS_Device_verification_code_count:";
//新版语音验证码计数
String REDIS_VOICE_IP_COUNT = "Voice_Ip_verification_code_count:";
String REDIS_VOICE_CODE_COUNT = "Voice_Phone_verification_code_count:";
String REDIS_VOICE_DEVICE_COUNT = "Voice_Device_verification_code_count:";
// zero fill with 4 chars...
String ZERO_FILL_TEMPLATE = "%04d";
String PASSWORD_SALT = "_lkb";
String IMAGE_CAPTCHA_KEY = "img_captcha:";
String REDIS_CAPTCHA_KEY = "auth:";
String REDIS_PREFIX_VERIFICATION_CODE = "verificationCode_";
//新版短信验证码计数
String REDIS_SMS_IP_COUNT = "SMS_Ip_verification_code_count:";
String REDIS_SMS_CODE_COUNT = "SMS_Phone_verification_code_count:";
String REDIS_SMS_DEVICE_COUNT = "SMS_Device_verification_code_count:";
//新版语音验证码计数
String REDIS_VOICE_IP_COUNT = "Voice_Ip_verification_code_count:";
String REDIS_VOICE_CODE_COUNT = "Voice_Phone_verification_code_count:";
String REDIS_VOICE_DEVICE_COUNT = "Voice_Device_verification_code_count:";
String REDIS_VERIFICATION_COUNT = "verification_code_count:";
Long Image_Need_Count = 3L;
Long VERIFICATION_CODE_FINITE_COUNT = 3L;
String REDIS_VERIFICATION_COUNT = "verification_code_count:";
Long Image_Need_Count = 3L;
Long VERIFICATION_CODE_FINITE_COUNT = 3L;
String X_AUTH_TOKEN = "x-auth-token";
/** 登录账号/手机号参数名 */
String PHONE_NO = "phoneNo";
/** 微信标识参数名 */
String WECHAT_OPEN_ID = "wechat_open_id";
String X_AUTH_TOKEN = "x-auth-token";
/**
* 登录账号/手机号参数名
*/
String PHONE_NO = "phoneNo";
/**
* 微信标识参数名
*/
String WECHAT_OPEN_ID = "wechat_open_id";
// -- Start -- IPV4安全策略常量组
/** 账密不匹配错误 - 按账号计数 */
String REDIS_PASSWORD_ERROR_COUNT = "password_error_count:";
/** 账密不匹配错误 - 按IP计数 */
String REDIS_PASSWORD_ERROR_COUNT_FOR_IPV4 = "password_error_count_4_ipv4:";
/** 账密匹配成功 - 按IP计数 */
String REDIS_PASSWORD_SUCCESS_COUNT_FOR_IPV4 = "password_success_count_4_ipv4:";
/** 账密安全策略 - 白名单 */
String IPV4_LOCK_WHITE = "lock_ipv4:white:";
/** 账密安全策略 - 黑名单 */
String IPV4_LOCK_BLACK = "lock_ipv4:black:";
/** 账密安全策略 - 锁机制自定义参数 - 锁定分钟数 */
String IPV4_LOCK_MINUTES_REDIS = "lock_ipv4:minutes:";
/** 账密安全策略 - 锁机制自定义参数 - 锁开关阈值 */
String IPV4_LOCK_ON_COUNTS_REDIS = "lock_ipv4:on_counts:";
/** 账密安全策略 - 锁机制 - IPV4锁 */
String IPV4_LOCK = "lock_ipv4:";
/** 账密不匹配错误 - 锁机制默认参数 - 锁定分钟数 */
Long IPV4_FAILED_LOCK_MINUTES = 3 * 60L;
/** 账密不匹配错误 - 锁机制默认参数 - 计数周期 */
Long IPV4_FAILED_COUNT_MINUTES = 1L;
/** 账密不匹配错误 - 锁机制默认参数 - 锁开关阈值 */
Long IPV4_LOCK_ON_FAILED_COUNTS = 60L;
/** 账密匹配成功 - 锁机制默认参数 - 锁定分钟数 */
Long IPV4_SUCCESS_LOCK_MINUTES = 30L;
/** 账密匹配成功 - 锁机制默认参数 - 计数周期 */
Long IPV4_SUCCESS_COUNT_MINUTES = 1 * 60L;
/** 账密匹配成功 - 锁机制默认参数 - 锁开关阈值 */
Long IPV4_LOCK_ON_SUCCESS_COUNTS = 40L;
/** 危险期 - 起始时间(Hour) */
int DANGEROUS_TIME_START = 22;
/** 危险期 - 结束时间(Hour) */
int DANGEROUS_TIME_END = 6;
/** 安全策略参数设置 - 秘钥 - 口令 */
String CLEAR_LOCK_FOR_IPV4 = "x-clear-lock-11241842-y";
/** 安全策略参数设置 - 私钥 */
String CLEAR_LOCK_FOR_IPV4_KEY = "lhp.family.dwy.sjs.yym.cxy.cpg";
// -- End -- IPV4安全策略常量组
/**
* redis中token的key值前缀
*/
String SESSION_PREFIX = "spring:session:sessions:";
// -- Start -- IPV4安全策略常量组
/**
* 账密不匹配错误 - 按账号计数
*/
String REDIS_PASSWORD_ERROR_COUNT = "password_error_count:";
/**
* 账密不匹配错误 - 按IP计数
*/
String REDIS_PASSWORD_ERROR_COUNT_FOR_IPV4 = "password_error_count_4_ipv4:";
/**
* 账密匹配成功 - 按IP计数
*/
String REDIS_PASSWORD_SUCCESS_COUNT_FOR_IPV4 = "password_success_count_4_ipv4:";
/**
* 账密安全策略 - 白名单
*/
String IPV4_LOCK_WHITE = "lock_ipv4:white:";
/**
* 账密安全策略 - 黑名单
*/
String IPV4_LOCK_BLACK = "lock_ipv4:black:";
/**
* 账密安全策略 - 锁机制自定义参数 - 锁定分钟数
*/
String IPV4_LOCK_MINUTES_REDIS = "lock_ipv4:minutes:";
/**
* 账密安全策略 - 锁机制自定义参数 - 锁开关阈值
*/
String IPV4_LOCK_ON_COUNTS_REDIS = "lock_ipv4:on_counts:";
/**
* 账密安全策略 - 锁机制 - IPV4锁
*/
String IPV4_LOCK = "lock_ipv4:";
/**
* 账密不匹配错误 - 锁机制默认参数 - 锁定分钟数
*/
Long IPV4_FAILED_LOCK_MINUTES = 3 * 60L;
/**
* 账密不匹配错误 - 锁机制默认参数 - 计数周期
*/
Long IPV4_FAILED_COUNT_MINUTES = 1L;
/**
* 账密不匹配错误 - 锁机制默认参数 - 锁开关阈值
*/
Long IPV4_LOCK_ON_FAILED_COUNTS = 60L;
/**
* 账密匹配成功 - 锁机制默认参数 - 锁定分钟数
*/
Long IPV4_SUCCESS_LOCK_MINUTES = 30L;
/**
* 账密匹配成功 - 锁机制默认参数 - 计数周期
*/
Long IPV4_SUCCESS_COUNT_MINUTES = 1 * 60L;
/**
* 账密匹配成功 - 锁机制默认参数 - 锁开关阈值
*/
Long IPV4_LOCK_ON_SUCCESS_COUNTS = 40L;
/**
* 危险期 - 起始时间(Hour)
*/
int DANGEROUS_TIME_START = 22;
/**
* 危险期 - 结束时间(Hour)
*/
int DANGEROUS_TIME_END = 6;
/**
* 安全策略参数设置 - 秘钥 - 口令
*/
String CLEAR_LOCK_FOR_IPV4 = "x-clear-lock-11241842-y";
/**
* 安全策略参数设置 - 私钥
*/
String CLEAR_LOCK_FOR_IPV4_KEY = "lhp.family.dwy.sjs.yym.cxy.cpg";
// -- End -- IPV4安全策略常量组
/**
* redis中token的key值前缀
*/
String SESSION_PREFIX = "spring:session:sessions:";
/**
* 默认随机密码长度
*/
int RANDOM_PWD_LEN = 15;
/**
* 默认随机密码长度
*/
int RANDOM_PWD_LEN = 15;
interface Channel {
long BAITIAO = 222L;
String LKB_CODE = "0002"; // 量化派channnel_code
long WECHAT = 198L;
}
interface Channel {
long BAITIAO = 222L;
String LKB_CODE = "0002"; // 量化派channnel_code
long WECHAT = 198L;
}
interface Session {
String USER_SESSION_CACHE = "user:session:";
String USER_SESSION_ID_CACHE = "userid-sessionvalue:cache:";
String USER_SESSION_KEY_SET = "userid-keys:set:";
Long ONE_DAY = 24 * 60 * 60L;
}
interface Session {
String USER_SESSION_CACHE = "user:session:";
String USER_SESSION_ID_CACHE = "userid-sessionvalue:cache:";
String USER_SESSION_KEY_SET = "userid-keys:set:";
Long ONE_DAY = 24 * 60 * 60L;
}
interface UserAvatar {
String AVATAR_DEFAULT = "https://avatar.xyqb.com/default_avatar.png";
}
interface UserAvatar {
String AVATAR_DEFAULT = "https://avatar.xyqb.com/default_avatar.png";
}
String AES_KEY = "ScnmRBhuQpo9kBdn";
String AES_KEY = "ScnmRBhuQpo9kBdn";
// -- Start -- 验证码常量组
int GT_CAPTCHA_VALIDATE_SUCCESS =1;
String GT_UNIQUE_KEY = "uniqueKey";
String FN_GEETEST_CHALLENGE = "geetest_challenge";
String FN_GEETEST_VALIDATE = "geetest_validate";
String FN_GEETEST_SECCODE = "geetest_seccode";
String QG_CAPTCHA_ID = "captchaId";
String QG_CAPTCHA_VALUE = "captchaValue";
/** 客户端类型参数名 */
String CLIENT_TYPE = "clientType";
/** 验证类型请求参数名 */
String VERIFY_PARAM = "verifyType";
/** 验证类型 - 极验 */
String VERIFY_TYPE_GT = "gt";
/** 验证类型 - 量化派图形验证 */
String VERIFY_TYPE_QG = "qg";
// -- End -- 验证码常量组
// -- Start -- 验证码常量组
int GT_CAPTCHA_VALIDATE_SUCCESS = 1;
String GT_UNIQUE_KEY = "uniqueKey";
String FN_GEETEST_CHALLENGE = "geetest_challenge";
String FN_GEETEST_VALIDATE = "geetest_validate";
String FN_GEETEST_SECCODE = "geetest_seccode";
String QG_CAPTCHA_ID = "captchaId";
String QG_CAPTCHA_VALUE = "captchaValue";
/**
* 客户端类型参数名
*/
String CLIENT_TYPE = "clientType";
/**
* 验证类型请求参数名
*/
String VERIFY_PARAM = "verifyType";
/**
* 验证类型 - 极验
*/
String VERIFY_TYPE_GT = "gt";
/**
* 验证类型 - 量化派图形验证
*/
String VERIFY_TYPE_QG = "qg";
// -- End -- 验证码常量组
}
......@@ -31,11 +31,11 @@ public class IpValidateAdvisor {
@Around("whiteIpMatch()")
private Object doWhiteIpMatch(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 客户端IP
String clientIp = IPUtil.getRemoteIP(request);
// 白名单
if(IPUtil.whiteOf(clientIp)){
if (IPUtil.whiteOf(clientIp)) {
return pjp.proceed();
}
IPUtil.logIp(LOGGER, request);
......
......@@ -4,6 +4,7 @@ import java.lang.annotation.*;
/**
* 限次的图形验证码校验标记
*
* @author 任文超
* @version 1.0.0
* @since 2017-11-07
......
......@@ -6,7 +6,6 @@ import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.service.captcha.IGeetestCaptchaService;
import cn.quantgroup.xyqb.service.captcha.IQuantgroupCaptchaService;
import cn.quantgroup.xyqb.util.IPUtil;
import cn.quantgroup.xyqb.util.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
......@@ -39,7 +38,8 @@ public class CaptchaNewValidateAdvisor {
* 图形验证码切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator)")
private void needCaptchaValidate(){}
private void needCaptchaValidate() {
}
/**
* 在受图形验证码保护的接口方法执行前, 校验图形验证码
......@@ -53,12 +53,12 @@ public class CaptchaNewValidateAdvisor {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 验证码类别:gt - 极验,qg - 量化派图形验证
if (Objects.equals(Constants.VERIFY_TYPE_GT, request.getParameter(Constants.VERIFY_PARAM))) {
if(StringUtils.isBlank(request.getParameter(Constants.FN_GEETEST_CHALLENGE))){
if (StringUtils.isBlank(request.getParameter(Constants.FN_GEETEST_CHALLENGE))) {
return JsonResult.buildErrorStateResult("操作过快,请稍后重试", "");
}
if(gtValid(request)){
if (gtValid(request)) {
return pjp.proceed();
}else{
} else {
return JsonResult.buildErrorStateResult("验证码不正确", "");
}
} else {
......@@ -72,7 +72,8 @@ public class CaptchaNewValidateAdvisor {
/**
* 极验校验
* @param request
*
* @param request
* @return
* @throws Throwable
*/
......@@ -89,6 +90,7 @@ public class CaptchaNewValidateAdvisor {
/**
* 量化派图形码校验
*
* @param request
* @return
* @throws Throwable
......
......@@ -31,82 +31,82 @@ import java.util.UUID;
*
* @author 李宁
* @version 1.0.0
* 创建时间:15/11/17 14:49
* 修改人:
* 修改时间:15/11/17 14:49
* 修改备注:
* 创建时间:15/11/17 14:49
* 修改人:
* 修改时间:15/11/17 14:49
* 修改备注:
*/
@Aspect
@Component
public class CaptchaValidateAdvisor {
private static final Logger LOGGER = LoggerFactory.getLogger(CaptchaValidateAdvisor.class);
private static final String SUPER_CAPTCHA_ID = UUID.nameUUIDFromBytes("__QG_APPCLIENT_AGENT__".getBytes(Charset.forName("UTF-8"))).toString();
private static final String SUPER_CAPTCHA = "__SUPERQG__";
private static final Logger LOGGER = LoggerFactory.getLogger(CaptchaValidateAdvisor.class);
private static final String SUPER_CAPTCHA_ID = UUID.nameUUIDFromBytes("__QG_APPCLIENT_AGENT__".getBytes(Charset.forName("UTF-8"))).toString();
private static final String SUPER_CAPTCHA = "__SUPERQG__";
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@Autowired
@Qualifier("customCaptchaService")
private AbstractManageableImageCaptchaService imageCaptchaService;
@Autowired
@Qualifier("customCaptchaService")
private AbstractManageableImageCaptchaService imageCaptchaService;
/**
* 自动化测试忽略验证码
*/
@Value("${xyqb.auth.captcha.autotest.enable:false}")
private boolean autoTestCaptchaEnabled;
/**
* 自动化测试忽略验证码
*/
@Value("${xyqb.auth.captcha.autotest.enable:false}")
private boolean autoTestCaptchaEnabled;
/**
* 图形验证码切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.captcha.CaptchaValidator)")
private void needCaptchaValidate() {
}
/**
* 在受图形验证码保护的接口方法执行前, 执行图形验证码校验
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("needCaptchaValidate()")
private Object doCapchaValidate(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String registerFrom = Optional.ofNullable(request.getParameter("registerFrom")).orElse("");
String captchaId = Optional.ofNullable(request.getParameter(Constants.QG_CAPTCHA_ID)).orElse("");
String captchaValue = request.getParameter(Constants.QG_CAPTCHA_VALUE);
if (shouldSkipCaptchaValidate(registerFrom, captchaId, captchaValue)) {
LOGGER.info("使用超级图形验证码校验, registerFrom={}, clientIp={}", registerFrom, IPUtil.getRemoteIP(request));
return pjp.proceed();
/**
* 图形验证码切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.captcha.CaptchaValidator)")
private void needCaptchaValidate() {
}
JsonResult result = JsonResult.buildSuccessResult("验证码不正确", "");
result.setBusinessCode("0002");
if (StringUtils.isNotBlank(captchaValue)) {
// 忽略用户输入的大小写
String captcha = StringUtils.lowerCase(captchaValue);
// 验证码校验
Boolean validCaptcha = false;
try {
validCaptcha = imageCaptchaService.validateResponseForID(Constants.IMAGE_CAPTCHA_KEY + captchaId, captcha);
} catch (CaptchaServiceException ex) {
LOGGER.error("验证码校验异常, {}, {}", ex.getMessage(), ex);
}
if (validCaptcha) {
return pjp.proceed();
}
/**
* 在受图形验证码保护的接口方法执行前, 执行图形验证码校验
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("needCaptchaValidate()")
private Object doCapchaValidate(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String registerFrom = Optional.ofNullable(request.getParameter("registerFrom")).orElse("");
String captchaId = Optional.ofNullable(request.getParameter(Constants.QG_CAPTCHA_ID)).orElse("");
String captchaValue = request.getParameter(Constants.QG_CAPTCHA_VALUE);
if (shouldSkipCaptchaValidate(registerFrom, captchaId, captchaValue)) {
LOGGER.info("使用超级图形验证码校验, registerFrom={}, clientIp={}", registerFrom, IPUtil.getRemoteIP(request));
return pjp.proceed();
}
JsonResult result = JsonResult.buildSuccessResult("验证码不正确", "");
result.setBusinessCode("0002");
if (StringUtils.isNotBlank(captchaValue)) {
// 忽略用户输入的大小写
String captcha = StringUtils.lowerCase(captchaValue);
// 验证码校验
Boolean validCaptcha = false;
try {
validCaptcha = imageCaptchaService.validateResponseForID(Constants.IMAGE_CAPTCHA_KEY + captchaId, captcha);
} catch (CaptchaServiceException ex) {
LOGGER.error("验证码校验异常, {}, {}", ex.getMessage(), ex);
}
if (validCaptcha) {
return pjp.proceed();
}
}
return result;
}
return result;
}
private boolean shouldSkipCaptchaValidate(String registerFrom, String captchaId, Object captchaValue) {
// 如果启用了超级验证码功能, 检查超级验证码, 超级验证码区分大小写
if (autoTestCaptchaEnabled) {
return true;
private boolean shouldSkipCaptchaValidate(String registerFrom, String captchaId, Object captchaValue) {
// 如果启用了超级验证码功能, 检查超级验证码, 超级验证码区分大小写
if (autoTestCaptchaEnabled) {
return true;
}
return StringUtils.equals(SUPER_CAPTCHA_ID, String.valueOf(captchaId)) && StringUtils.equals(SUPER_CAPTCHA, String.valueOf(captchaValue));
}
return StringUtils.equals(SUPER_CAPTCHA_ID, String.valueOf(captchaId)) && StringUtils.equals(SUPER_CAPTCHA, String.valueOf(captchaValue));
}
}
......@@ -8,10 +8,10 @@ import java.lang.annotation.*;
*
* @author 李宁
* @version 1.0.0
* 创建时间:15/11/17 14:47
* 修改人:
* 修改时间:15/11/17 14:47
* 修改备注:
* 创建时间:15/11/17 14:47
* 修改人:
* 修改时间:15/11/17 14:47
* 修改备注:
*/
@Documented
@Target(ElementType.METHOD)
......
......@@ -10,7 +10,7 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface FPLock {
String uniqueName();
String uniqueName();
FPRestriction[] restrictions() default {};
FPRestriction[] restrictions() default {};
}
......@@ -10,15 +10,15 @@ import java.util.concurrent.TimeUnit;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FPRestriction {
// 持续时间
int duration() default 1;
// 持续时间
int duration() default 1;
// 持续时间单位
TimeUnit type() default TimeUnit.MINUTES;
// 持续时间单位
TimeUnit type() default TimeUnit.MINUTES;
// 限制值, -1表示不限制
int limit() default -1;
// 限制值, -1表示不限制
int limit() default -1;
// 使用可覆盖
boolean override() default true;
// 使用可覆盖
boolean override() default true;
}
......@@ -18,7 +18,8 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.Objects;
import java.util.Set;
/**
* 免密访问校验切面
......@@ -38,7 +39,8 @@ public class PasswordFreeAccessValidateAdvisor {
* 免密访问校验切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.limit.PasswordFreeAccessValidator)")
private void passwordFreeAccess() {}
private void passwordFreeAccess() {
}
/**
* 执行免密访问校验
......@@ -58,20 +60,21 @@ public class PasswordFreeAccessValidateAdvisor {
/**
* 校验免密访问
* 规则:token 与 身份标记(phoneNo、userId匹配)
*
* @return True or False
*/
private boolean tokenValid(HttpServletRequest request) {
Objects.requireNonNull(request, "无效请求");
String clientIp = IPUtil.getRemoteIP(request);
Set<String> paramKeys = request.getParameterMap().keySet();
if(!paramKeys.contains(Constants.PHONE_NO) && !paramKeys.contains(USER_ID)){
if (!paramKeys.contains(Constants.PHONE_NO) && !paramKeys.contains(USER_ID)) {
LOGGER.info("非法请求 - 缺少参数, paramKeys={}, clientIp={}", paramKeys, clientIp);
return false;
}
// 当前请求的phoneNo/userId
String phoneNo = request.getParameter(Constants.PHONE_NO);
String userId = request.getParameter(USER_ID);
if(StringUtils.isBlank(phoneNo) && StringUtils.isBlank(userId)){
if (StringUtils.isBlank(phoneNo) && StringUtils.isBlank(userId)) {
LOGGER.info("非法请求 - 缺少参数, phoneNo={}, userId={}, clientIp={}", phoneNo, userId, clientIp);
return false;
}
......@@ -83,20 +86,20 @@ public class PasswordFreeAccessValidateAdvisor {
}
// 当前session
SessionStruct session = XyqbSessionContextHolder.getXSessionFromRedis(token);
if (Objects.isNull(session) || Objects.isNull(session.getValues()) || Objects.isNull(session.getValues().getUser())){
if (Objects.isNull(session) || Objects.isNull(session.getValues()) || Objects.isNull(session.getValues().getUser())) {
LOGGER.info("非法请求 - 未登录, token={}, phoneNo={}, userId={}, clientIp={}", token, phoneNo, userId, clientIp);
return false;
}
// 当前用户
User user = session.getValues().getUser();
if(Objects.isNull(user.getId()) && StringUtils.isBlank(user.getPhoneNo())){
if (Objects.isNull(user.getId()) && StringUtils.isBlank(user.getPhoneNo())) {
LOGGER.info("非法请求 - 未登录, token={}, phoneNo={}, userId={}, clientIp={}", token, phoneNo, userId, clientIp);
return false;
}
// 校对用户信息是否匹配
boolean valid = (Objects.nonNull(user.getId()) && Objects.equals(userId, user.getId().toString()));
valid = valid || (StringUtils.isNotBlank(phoneNo) && Objects.equals(phoneNo, user.getPhoneNo()));
if(!valid) {
if (!valid) {
LOGGER.info("非法请求 - 身份不匹配, token={}, phoneNo=({},{}), userId=({},{}), clientIp={}", token, phoneNo, user.getPhoneNo(), userId, user.getId(), clientIp);
}
return valid;
......
......@@ -4,6 +4,7 @@ import java.lang.annotation.*;
/**
* 免密访问校验标记
*
* @author 任文超
* @version 1.0.0
* @since 2017-11-21
......
......@@ -23,6 +23,7 @@ import java.util.Objects;
/**
* 密码错误限次的校验
*
* @author 任文超
* @version 1.0.0
* @since 2017-11-23
......@@ -31,61 +32,61 @@ import java.util.Objects;
@Component
public class PasswordErrorFiniteValidateAdvisor {
private static final Logger LOGGER = LoggerFactory.getLogger(PasswordErrorFiniteValidateAdvisor.class);
private static final Logger LOGGER = LoggerFactory.getLogger(PasswordErrorFiniteValidateAdvisor.class);
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
/**
* 密码错误限次切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.lock.PasswordErrorFiniteValidator)")
private void passwordErrorFiniteValidate() {
}
/**
* 在受保护的接口方法执行前, 执行锁状态校验
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("passwordErrorFiniteValidate()")
private Object doFiniteValidate(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 客户端IP
String clientIp = IPUtil.getRemoteIP(request);
// 白名单
if(IPUtil.whiteOf(clientIp)){
return pjp.proceed();
}
// 补充白名单
if(redisTemplate.opsForSet().isMember(Constants.IPV4_LOCK_WHITE, clientIp)){
return pjp.proceed();
}
// 入口服务器IP
if(StringUtils.startsWith(clientIp, "139.198.")){
return pjp.proceed();
/**
* 密码错误限次切面
*/
@Pointcut("@annotation(cn.quantgroup.xyqb.aspect.lock.PasswordErrorFiniteValidator)")
private void passwordErrorFiniteValidate() {
}
// 黑名单
if(redisTemplate.opsForSet().isMember(Constants.IPV4_LOCK_BLACK, clientIp)){
IPUtil.logIp(LOGGER, request);
LOGGER.info("Lock_ipv4: black ip access:{}", clientIp);
return JsonResult.buildErrorStateResult("登录失败", null);
}
String lockIpv4Key = getLockIpv4Key(clientIp);
String lock = redisTemplate.opsForValue().get(lockIpv4Key);
if (Objects.equals(Boolean.TRUE.toString(), lock)){
IPUtil.logIp(LOGGER, request);
LOGGER.info("Lock_ipv4: locked ip access:{}", clientIp);
return JsonResult.buildErrorStateResult("登录失败", null);
/**
* 在受保护的接口方法执行前, 执行锁状态校验
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("passwordErrorFiniteValidate()")
private Object doFiniteValidate(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 客户端IP
String clientIp = IPUtil.getRemoteIP(request);
// 白名单
if (IPUtil.whiteOf(clientIp)) {
return pjp.proceed();
}
// 补充白名单
if (redisTemplate.opsForSet().isMember(Constants.IPV4_LOCK_WHITE, clientIp)) {
return pjp.proceed();
}
// 入口服务器IP
if (StringUtils.startsWith(clientIp, "139.198.")) {
return pjp.proceed();
}
// 黑名单
if (redisTemplate.opsForSet().isMember(Constants.IPV4_LOCK_BLACK, clientIp)) {
IPUtil.logIp(LOGGER, request);
LOGGER.info("Lock_ipv4: black ip access:{}", clientIp);
return JsonResult.buildErrorStateResult("登录失败", null);
}
String lockIpv4Key = getLockIpv4Key(clientIp);
String lock = redisTemplate.opsForValue().get(lockIpv4Key);
if (Objects.equals(Boolean.TRUE.toString(), lock)) {
IPUtil.logIp(LOGGER, request);
LOGGER.info("Lock_ipv4: locked ip access:{}", clientIp);
return JsonResult.buildErrorStateResult("登录失败", null);
}
return pjp.proceed();
}
return pjp.proceed();
}
private final static String getLockIpv4Key(String ipv4){
return Constants.IPV4_LOCK + ipv4;
}
private final static String getLockIpv4Key(String ipv4) {
return Constants.IPV4_LOCK + ipv4;
}
}
......@@ -4,6 +4,7 @@ import java.lang.annotation.*;
/**
* 密码错误限次的校验标记
*
* @author 任文超
* @version 1.0.0
* @since 2017-11-23
......
......@@ -37,14 +37,14 @@ public class LogCallHttpAspect {
public Object record(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(Objects.nonNull(attrs)){
if (Objects.nonNull(attrs)) {
try {
HttpServletRequest request = attrs.getRequest();
String remoteIP = IPUtil.getRemoteIP(request);
LogCallHttpAspect logCallHttpAspect = ApplicationContextHolder.getBean(LogCallHttpAspect.class);
// 异步记录日志
logCallHttpAspect.asyncRecordIt(pjp,result,remoteIP);
}catch (Exception e){
logCallHttpAspect.asyncRecordIt(pjp, result, remoteIP);
} catch (Exception e) {
LOGGER.error("打印http请求日志出错", e);
}
}
......@@ -53,16 +53,17 @@ public class LogCallHttpAspect {
/**
* 异步记录日志
*
* @param pjp
* @param result
* @param remoteIP
*/
@Async("logExecutor")
public void asyncRecordIt(ProceedingJoinPoint pjp, Object result, String remoteIP){
public void asyncRecordIt(ProceedingJoinPoint pjp, Object result, String remoteIP) {
Object[] args = pjp.getArgs();
String methodName = pjp.getSignature().getName();
String methodName = pjp.getSignature().getName();
String targetName = pjp.getTarget().getClass().getName();
LOGGER.info("http api is called,from IP:[{}],method :[{}],args:[{}],response:[{}]",remoteIP,targetName.concat(".").concat(methodName),args,result);
LOGGER.info("http api is called,from IP:[{}],method :[{}],args:[{}],response:[{}]", remoteIP, targetName.concat(".").concat(methodName), args, result);
}
}
......@@ -15,31 +15,31 @@ import org.springframework.data.redis.core.RedisTemplate;
*
* @author 李宁
* @version 1.0.0
* 创建时间:15/11/17 12:04
* 修改人:
* 修改时间:15/11/17 12:04
* 修改备注:
* 创建时间:15/11/17 12:04
* 修改人:
* 修改时间:15/11/17 12:04
* 修改备注:
*/
@Configuration
public class CaptchaConfig {
@Bean
public CaptchaEngine initCaptchaEngine() {
return new CustomJCaptchaEngine();
}
@Bean
public CaptchaEngine initCaptchaEngine() {
return new CustomJCaptchaEngine();
}
@Bean
@Autowired
@Qualifier("stringRedisTemplate")
public CaptchaStore initStringCaptchaStore(RedisTemplate<String, String> stringRedisTemplate) {
return new RedisCaptchaStore(stringRedisTemplate);
}
@Bean
@Autowired
@Qualifier("stringRedisTemplate")
public CaptchaStore initStringCaptchaStore(RedisTemplate<String, String> stringRedisTemplate) {
return new RedisCaptchaStore(stringRedisTemplate);
}
@Bean(name = "customCaptchaService")
@Autowired
public AbstractManageableImageCaptchaService initCaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine) {
return new CustomJCaptchaService(captchaStore, captchaEngine);
}
@Bean(name = "customCaptchaService")
@Autowired
public AbstractManageableImageCaptchaService initCaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine) {
return new CustomJCaptchaService(captchaStore, captchaEngine);
}
}
......@@ -28,51 +28,51 @@ import java.awt.image.ImageFilter;
*
* @author 李宁
* @version 1.0.0
* 创建时间:15/11/17 12:04
* 修改人:
* 修改时间:15/11/17 12:04
* 修改备注:
* 创建时间:15/11/17 12:04
* 修改人:
* 修改时间:15/11/17 12:04
* 修改备注:
*/
public class CustomJCaptchaEngine extends ListImageCaptchaEngine {
private static final int MIN_WORD_LEN = 4;
private static final int MAX_WORD_LEN = 4;
private static final int MIN_WORD_LEN = 4;
private static final int MAX_WORD_LEN = 4;
@Override
protected void buildInitialFactories() {
int minWordLength = 4;
int maxWordLength = 4;
int fontSize = 16;
int imageWidth = 80;
int imageHeight = 28;
WordGenerator wordGenerator = new RandomWordGenerator("1234567890");
SingleColorGenerator colorGenerator = new SingleColorGenerator(Color.WHITE);
@Override
protected void buildInitialFactories() {
int minWordLength = 4;
int maxWordLength = 4;
int fontSize = 16;
int imageWidth = 80;
int imageHeight = 28;
WordGenerator wordGenerator = new RandomWordGenerator("1234567890");
SingleColorGenerator colorGenerator = new SingleColorGenerator(Color.WHITE);
//文字干扰器--- 可以创建多个
BaffleTextDecorator baffleTextDecorator = new BaffleTextDecorator(1, colorGenerator, 1);//气泡干扰
//文字干扰器--- 可以创建多个
BaffleTextDecorator baffleTextDecorator = new BaffleTextDecorator(1, colorGenerator, 1);//气泡干扰
// LineTextDecorator lineTextDecorator = new LineTextDecorator(1,colorGenerator, 1);//曲线干扰
// TextDecorator[] textDecorators = new TextDecorator[]{baffleTextDecorator, lineTextDecorator};
TextDecorator[] textDecorators = new TextDecorator[]{baffleTextDecorator};
TextDecorator[] textDecorators = new TextDecorator[]{baffleTextDecorator};
TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
maxWordLength, new RandomListColorGenerator(new Color[]{
new Color(23, 170, 27), new Color(220, 34, 11),
new Color(23, 67, 172)}), textDecorators);
TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
maxWordLength, new RandomListColorGenerator(new Color[]{
new Color(23, 170, 27), new Color(220, 34, 11),
new Color(23, 67, 172)}), textDecorators);
BackgroundGenerator background = new UniColorBackgroundGenerator(imageWidth, imageHeight, colorGenerator);
FontGenerator font = new RandomFontGenerator(fontSize, fontSize,
new Font[]{new Font("nyala", Font.BOLD, fontSize),
new Font("Bell MT", Font.PLAIN, fontSize),
new Font("Credit valley", Font.BOLD, fontSize)});
BackgroundGenerator background = new UniColorBackgroundGenerator(imageWidth, imageHeight, colorGenerator);
FontGenerator font = new RandomFontGenerator(fontSize, fontSize,
new Font[]{new Font("nyala", Font.BOLD, fontSize),
new Font("Bell MT", Font.PLAIN, fontSize),
new Font("Credit valley", Font.BOLD, fontSize)});
ImageDeformation postDef = new ImageDeformationByFilters(new ImageFilter[]{});
ImageDeformation backDef = new ImageDeformationByFilters(new ImageFilter[]{});
ImageDeformation textDef = new ImageDeformationByFilters(new ImageFilter[]{});
ImageDeformation postDef = new ImageDeformationByFilters(new ImageFilter[]{});
ImageDeformation backDef = new ImageDeformationByFilters(new ImageFilter[]{});
ImageDeformation textDef = new ImageDeformationByFilters(new ImageFilter[]{});
WordToImage word2image = new DeformedComposedWordToImage(font,
background, randomPaster, backDef, textDef, postDef);
addFactory(new CustomGimpyFactory(wordGenerator, word2image));
}
WordToImage word2image = new DeformedComposedWordToImage(font,
background, randomPaster, backDef, textDef, postDef);
addFactory(new CustomGimpyFactory(wordGenerator, word2image));
}
}
......@@ -17,91 +17,91 @@ import java.util.Locale;
*
* @author 李宁
* @version 1.0.0
* 创建时间:15/11/17 19:41
* 修改人:
* 修改时间:15/11/17 19:41
* 修改备注:
* 创建时间:15/11/17 19:41
* 修改人:
* 修改时间:15/11/17 19:41
* 修改备注:
*/
public class CustomJCaptchaService extends AbstractManageableImageCaptchaService {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomJCaptchaService.class);
private static final Logger LOGGER = LoggerFactory.getLogger(CustomJCaptchaService.class);
/*
* 验证码管理策略:
* 1, 生成验证码时, 会进行配额检查, 当达到配额时, 进行垃圾验证码清理
* 2, 一个验证码校验完成后, 不管成功失败, 都会直接失效, 删除?
* */
private static final Integer MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS = 120; // 默认值, 执行垃圾清理时, 存活超过180s的验证码都会被清除
private static final Integer MAX_CAPTCHA_STORE_SIZE = 70000; // 最大容量, 默认值是10w
private static final Integer CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION = 52500; // 配额, 超过此配额时执行一次垃圾清除, 默认值是:75000
/*
* 验证码管理策略:
* 1, 生成验证码时, 会进行配额检查, 当达到配额时, 进行垃圾验证码清理
* 2, 一个验证码校验完成后, 不管成功失败, 都会直接失效, 删除?
* */
private static final Integer MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS = 120; // 默认值, 执行垃圾清理时, 存活超过180s的验证码都会被清除
private static final Integer MAX_CAPTCHA_STORE_SIZE = 70000; // 最大容量, 默认值是10w
private static final Integer CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION = 52500; // 配额, 超过此配额时执行一次垃圾清除, 默认值是:75000
public CustomJCaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine) {
this(captchaStore, captchaEngine, MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS, MAX_CAPTCHA_STORE_SIZE, CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION);
}
protected CustomJCaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine, int minGuarantedStorageDelayInSeconds, int maxCaptchaStoreSize, int captchaStoreLoadBeforeGarbageCollection) {
super(captchaStore, captchaEngine, minGuarantedStorageDelayInSeconds, maxCaptchaStoreSize, captchaStoreLoadBeforeGarbageCollection);
}
public CustomJCaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine) {
this(captchaStore, captchaEngine, MIN_GUARANTED_STORAGE_DELAY_IN_SECONDS, MAX_CAPTCHA_STORE_SIZE, CAPTCHA_STORE_LOAD_BEFORE_GARBAGE_COLLECTION);
}
@Override
public long getCustomStoreSize() {
return this.store.getSize();
}
/**
* 重写校验, 需要将原来的 key 失效
*
* @param id
* @param response
* @return
* @throws CaptchaServiceException
*/
@Override
public Boolean validateResponseForID(String id, Object response) throws CaptchaServiceException {
if (StringUtils.isBlank(id)) {
return false;
}
boolean valid;
try {
Captcha captcha = this.store.getCaptcha(id);
if (null == captcha || captcha.hasGetChalengeBeenCalled()) {
return false;
}
valid = captcha.validateResponse(response);
} catch (Exception ex) {
LOGGER.warn("can not get captcha from redis");
valid = false;
protected CustomJCaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine, int minGuarantedStorageDelayInSeconds, int maxCaptchaStoreSize, int captchaStoreLoadBeforeGarbageCollection) {
super(captchaStore, captchaEngine, minGuarantedStorageDelayInSeconds, maxCaptchaStoreSize, captchaStoreLoadBeforeGarbageCollection);
}
this.getTimes().remove(id);
if (valid) {
addNumberOfCorrectResponse(1);
} else {
addNumberOfUncorrectResponse(1);
@Override
public long getCustomStoreSize() {
return this.store.getSize();
}
return valid;
}
/**
* 重写校验, 需要将原来的 key 失效
*
* @param id
* @param response
* @return
* @throws CaptchaServiceException
*/
@Override
public Boolean validateResponseForID(String id, Object response) throws CaptchaServiceException {
if (StringUtils.isBlank(id)) {
return false;
}
boolean valid;
try {
Captcha captcha = this.store.getCaptcha(id);
if (null == captcha || captcha.hasGetChalengeBeenCalled()) {
return false;
}
valid = captcha.validateResponse(response);
} catch (Exception ex) {
LOGGER.warn("can not get captcha from redis");
valid = false;
}
/**
* 请求新的图形验证码
*
* @param ID
* @param locale
* @return
* @throws CaptchaServiceException
*/
public Object getChallengeForID(String ID, Locale locale) throws CaptchaServiceException {
Captcha captcha = this.generateAndStoreCaptcha(locale, ID);
Object challenge = this.getChallengeClone(captcha);
captcha.disposeChallenge();
return challenge;
}
this.getTimes().remove(id);
if (valid) {
addNumberOfCorrectResponse(1);
} else {
addNumberOfUncorrectResponse(1);
}
@Override
public void garbageCollectCaptchaStore() {
super.garbageCollectCaptchaStore();
}
return valid;
}
/**
* 请求新的图形验证码
*
* @param ID
* @param locale
* @return
* @throws CaptchaServiceException
*/
public Object getChallengeForID(String ID, Locale locale) throws CaptchaServiceException {
Captcha captcha = this.generateAndStoreCaptcha(locale, ID);
Object challenge = this.getChallengeClone(captcha);
captcha.disposeChallenge();
return challenge;
}
@Override
public void garbageCollectCaptchaStore() {
super.garbageCollectCaptchaStore();
}
}
......@@ -20,96 +20,96 @@ import java.util.concurrent.TimeUnit;
*
* @author 李宁
* @version 1.0.0
* 创建时间:15/12/17 06:39
* 修改人:
* 修改时间:15/12/17 06:39
* 修改备注:
* 创建时间:15/12/17 06:39
* 修改人:
* 修改时间:15/12/17 06:39
* 修改备注:
*/
public class RedisCaptchaStore implements CaptchaStore {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisCaptchaStore.class);
private static final long DEFAULT_EXPIRED_IN = 120L;
private static final TimeUnit DEFAULT_EXPIRED_TIMEUNIT = TimeUnit.SECONDS;
protected RedisTemplate<String, String> stringRedisTemplate;
public RedisCaptchaStore(RedisTemplate<String, String> stringRedisTemplate) {
super();
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public boolean hasCaptcha(String captchaId) {
return stringRedisTemplate.hasKey(buildCaptcharKey(captchaId));
}
@Override
public void storeCaptcha(String s, Captcha captcha) throws CaptchaServiceException {
stringRedisTemplate.opsForValue().set(buildCaptcharKey(s), ((SimpleCaptcha) captcha).getResponse(), DEFAULT_EXPIRED_IN, DEFAULT_EXPIRED_TIMEUNIT);
}
@Override
public void storeCaptcha(String s, Captcha captcha, Locale locale) throws CaptchaServiceException {
stringRedisTemplate.opsForValue().set(buildCaptcharKey(s), ((SimpleCaptcha) captcha).getResponse(), DEFAULT_EXPIRED_IN, DEFAULT_EXPIRED_TIMEUNIT);
}
@Override
public boolean removeCaptcha(String captchaId) {
stringRedisTemplate.delete(buildCaptcharKey(captchaId));
return true;
}
@Override
public Captcha getCaptcha(String captchaId) throws CaptchaServiceException {
return getFromRedisThenDel(captchaId);
}
@Override
public Locale getLocale(String captchaId) throws CaptchaServiceException {
return Locale.CHINA;
}
@Override
public int getSize() {
return 0;
}
@Override
public Collection getKeys() {
return Collections.emptyList();
}
@Override
public void empty() {
}
@Override
public void initAndStart() {
}
@Override
public void cleanAndShutdown() {
}
private Captcha getFromRedis(String captchaId) {
Object value = stringRedisTemplate.opsForValue().get(buildCaptcharKey(captchaId));
return value != null ? new SimpleCaptcha(captchaId, String.valueOf(value)) : null;
}
private Captcha getFromRedisThenDel(String captchaId) {
String captcharKey = buildCaptcharKey(captchaId);
Long expire = stringRedisTemplate.getExpire(captcharKey, TimeUnit.SECONDS);
Object value = stringRedisTemplate.opsForValue().get(captcharKey);
LOGGER.info("captchaId={},captchaCode={},expire={}秒", captcharKey, value, expire);
stringRedisTemplate.delete(captcharKey);
return value != null ? new SimpleCaptcha(captchaId, String.valueOf(value)) : null;
}
protected String buildCaptcharKey(String captchaId) {
return Constants.REDIS_CAPTCHA_KEY + captchaId;
}
private static final Logger LOGGER = LoggerFactory.getLogger(RedisCaptchaStore.class);
private static final long DEFAULT_EXPIRED_IN = 120L;
private static final TimeUnit DEFAULT_EXPIRED_TIMEUNIT = TimeUnit.SECONDS;
protected RedisTemplate<String, String> stringRedisTemplate;
public RedisCaptchaStore(RedisTemplate<String, String> stringRedisTemplate) {
super();
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public boolean hasCaptcha(String captchaId) {
return stringRedisTemplate.hasKey(buildCaptcharKey(captchaId));
}
@Override
public void storeCaptcha(String s, Captcha captcha) throws CaptchaServiceException {
stringRedisTemplate.opsForValue().set(buildCaptcharKey(s), ((SimpleCaptcha) captcha).getResponse(), DEFAULT_EXPIRED_IN, DEFAULT_EXPIRED_TIMEUNIT);
}
@Override
public void storeCaptcha(String s, Captcha captcha, Locale locale) throws CaptchaServiceException {
stringRedisTemplate.opsForValue().set(buildCaptcharKey(s), ((SimpleCaptcha) captcha).getResponse(), DEFAULT_EXPIRED_IN, DEFAULT_EXPIRED_TIMEUNIT);
}
@Override
public boolean removeCaptcha(String captchaId) {
stringRedisTemplate.delete(buildCaptcharKey(captchaId));
return true;
}
@Override
public Captcha getCaptcha(String captchaId) throws CaptchaServiceException {
return getFromRedisThenDel(captchaId);
}
@Override
public Locale getLocale(String captchaId) throws CaptchaServiceException {
return Locale.CHINA;
}
@Override
public int getSize() {
return 0;
}
@Override
public Collection getKeys() {
return Collections.emptyList();
}
@Override
public void empty() {
}
@Override
public void initAndStart() {
}
@Override
public void cleanAndShutdown() {
}
private Captcha getFromRedis(String captchaId) {
Object value = stringRedisTemplate.opsForValue().get(buildCaptcharKey(captchaId));
return value != null ? new SimpleCaptcha(captchaId, String.valueOf(value)) : null;
}
private Captcha getFromRedisThenDel(String captchaId) {
String captcharKey = buildCaptcharKey(captchaId);
Long expire = stringRedisTemplate.getExpire(captcharKey, TimeUnit.SECONDS);
Object value = stringRedisTemplate.opsForValue().get(captcharKey);
LOGGER.info("captchaId={},captchaCode={},expire={}秒", captcharKey, value, expire);
stringRedisTemplate.delete(captcharKey);
return value != null ? new SimpleCaptcha(captchaId, String.valueOf(value)) : null;
}
protected String buildCaptcharKey(String captchaId) {
return Constants.REDIS_CAPTCHA_KEY + captchaId;
}
}
......@@ -4,7 +4,6 @@ package cn.quantgroup.xyqb.config.data;
* Created by Miraculous on 2016/11/16.
*/
import cn.quantgroup.xyqb.util.ApplicationContextHolder;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Value;
......@@ -32,65 +31,65 @@ import java.util.Properties;
@EnableTransactionManagement
public class JpaConfig {
@Value("${xyqb.data.mysql.jdbc-url}")
private String xyqbJdbcUrl;
@Value("${xyqb.data.mysql.password}")
private String password;
@Value("${xyqb.data.mysql.user}")
private String user;
@Value("${xyqb.data.mysql.max-pool-size}")
private Integer maxPoolSize;
@Bean
@DependsOn(value = "dataSource")
public EntityManagerFactory entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setDataSource(dataSource);
entityManager.setPackagesToScan("cn.quantgroup.xyqb");
entityManager.setPersistenceUnitName("dataSource");
Properties properties = new Properties();
properties.put("hibernate.jdbc.batch_size", 30);
properties.put("hibernate.order_inserts", true);
properties.put("hibernate.order_updates", true);
entityManager.setJpaProperties(properties);
entityManager.setJpaVendorAdapter(jpaVendorAdapter());
entityManager.afterPropertiesSet();
return entityManager.getObject();
}
@Bean(name = "dataSource")
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(xyqbJdbcUrl);
config.setPassword(password);
config.setUsername(user);
config.setMaximumPoolSize(maxPoolSize);
config.setMinimumIdle(20);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
private JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(false);
hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Value("${xyqb.data.mysql.jdbc-url}")
private String xyqbJdbcUrl;
@Value("${xyqb.data.mysql.password}")
private String password;
@Value("${xyqb.data.mysql.user}")
private String user;
@Value("${xyqb.data.mysql.max-pool-size}")
private Integer maxPoolSize;
@Bean
@DependsOn(value = "dataSource")
public EntityManagerFactory entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setDataSource(dataSource);
entityManager.setPackagesToScan("cn.quantgroup.xyqb");
entityManager.setPersistenceUnitName("dataSource");
Properties properties = new Properties();
properties.put("hibernate.jdbc.batch_size", 30);
properties.put("hibernate.order_inserts", true);
properties.put("hibernate.order_updates", true);
entityManager.setJpaProperties(properties);
entityManager.setJpaVendorAdapter(jpaVendorAdapter());
entityManager.afterPropertiesSet();
return entityManager.getObject();
}
@Bean(name = "dataSource")
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(xyqbJdbcUrl);
config.setPassword(password);
config.setUsername(user);
config.setMaximumPoolSize(maxPoolSize);
config.setMinimumIdle(20);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
private JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(false);
hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
......@@ -25,118 +25,118 @@ import java.util.Set;
@Configuration
public class RedisConfig {
@Value("${xyqb.redis.defaultExpiration}")
private Long defaultExpiration;
@Value("${xyqb.redis.master.host}")
private String masterHost;
@Value("${xyqb.redis.master.port}")
private int masterPort;
@Value("${xyqb.redis.master.name}")
private String masterName;
@Value("${xyqb.redis.sentinel1.host}")
private String sentinel1Host;
@Value("${xyqb.redis.sentinel1.port}")
private int sentinel1port;
@Value("${xyqb.redis.sentinel2.host}")
private String sentinel2Host;
@Value("${xyqb.redis.sentinel2.port}")
private int sentinel2port;
@Value("${xyqb.redis.sentinel3.host}")
private String sentinel3Host;
@Value("${xyqb.redis.sentinel3.port}")
private int sentinel3port;
@Value("${xyqb.redis.defaultExpiration}")
private Long defaultExpiration;
@Value("${xyqb.redis.master.host}")
private String masterHost;
@Value("${xyqb.redis.master.port}")
private int masterPort;
@Value("${xyqb.redis.master.name}")
private String masterName;
@Value("${xyqb.redis.sentinel1.host}")
private String sentinel1Host;
@Value("${xyqb.redis.sentinel1.port}")
private int sentinel1port;
@Value("${xyqb.redis.sentinel2.host}")
private String sentinel2Host;
@Value("${xyqb.redis.sentinel2.port}")
private int sentinel2port;
@Value("${xyqb.redis.sentinel3.host}")
private String sentinel3Host;
@Value("${xyqb.redis.sentinel3.port}")
private int sentinel3port;
private RedisConnectionFactory generateDevConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
JedisPoolConfig poolConfig = generatePoolConfig();
factory.setPoolConfig(poolConfig);
factory.afterPropertiesSet();
return factory;
}
private RedisConnectionFactory generateDevConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
JedisPoolConfig poolConfig = generatePoolConfig();
factory.setPoolConfig(poolConfig);
factory.afterPropertiesSet();
return factory;
}
private RedisConnectionFactory generateReleaseConnectionFactory() {
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
RedisNode master = new RedisNode(masterHost, masterPort);
master.setName(masterName);
Set<RedisNode> sentinels = new HashSet<>();
RedisNode sentinel1 = new RedisNode(sentinel1Host, sentinel1port);
RedisNode sentinel2 = new RedisNode(sentinel2Host, sentinel2port);
RedisNode sentinel3 = new RedisNode(sentinel3Host, sentinel3port);
sentinels.add(sentinel1);
sentinels.add(sentinel2);
sentinels.add(sentinel3);
sentinelConfiguration.setMaster(master);
sentinelConfiguration.setSentinels(sentinels);
JedisPoolConfig poolConfig = generatePoolConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(sentinelConfiguration, poolConfig);
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setTimeout(5000);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
factory.afterPropertiesSet();
return factory;
}
private RedisConnectionFactory generateReleaseConnectionFactory() {
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
RedisNode master = new RedisNode(masterHost, masterPort);
master.setName(masterName);
Set<RedisNode> sentinels = new HashSet<>();
RedisNode sentinel1 = new RedisNode(sentinel1Host, sentinel1port);
RedisNode sentinel2 = new RedisNode(sentinel2Host, sentinel2port);
RedisNode sentinel3 = new RedisNode(sentinel3Host, sentinel3port);
sentinels.add(sentinel1);
sentinels.add(sentinel2);
sentinels.add(sentinel3);
sentinelConfiguration.setMaster(master);
sentinelConfiguration.setSentinels(sentinels);
JedisPoolConfig poolConfig = generatePoolConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(sentinelConfiguration, poolConfig);
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setTimeout(5000);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
factory.afterPropertiesSet();
return factory;
}
private JedisPoolConfig generatePoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(20);
poolConfig.setMaxTotal(300);
poolConfig.setMaxWaitMillis(5000);
poolConfig.setTestOnBorrow(true);
return poolConfig;
}
private JedisPoolConfig generatePoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(20);
poolConfig.setMaxTotal(300);
poolConfig.setMaxWaitMillis(5000);
poolConfig.setTestOnBorrow(true);
return poolConfig;
}
@Bean(name = "redisConnectionFactory")
RedisConnectionFactory factory() {
if (StringUtils.isEmpty(masterName)) {
return generateDevConnectionFactory();
} else {
return generateReleaseConnectionFactory();
@Bean(name = "redisConnectionFactory")
RedisConnectionFactory factory() {
if (StringUtils.isEmpty(masterName)) {
return generateDevConnectionFactory();
} else {
return generateReleaseConnectionFactory();
}
}
}
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, Object> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
template.setEnableTransactionSupport(false);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jdkSerializationRedisSerializer);
template.setDefaultSerializer(jdkSerializationRedisSerializer);
template.setConnectionFactory(factory);
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, Object> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
template.setEnableTransactionSupport(false);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jdkSerializationRedisSerializer);
template.setDefaultSerializer(jdkSerializationRedisSerializer);
template.setConnectionFactory(factory);
XyqbSessionContextHolder.redisTemplate = stringRedisTemplate(factory);
return template;
}
XyqbSessionContextHolder.redisTemplate = stringRedisTemplate(factory);
return template;
}
@Bean(name = "stringRedisTemplate")
public RedisTemplate<String, String> stringRedisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, String> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
template.setEnableTransactionSupport(true);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jdkSerializationRedisSerializer);
template.setDefaultSerializer(jdkSerializationRedisSerializer);
template.setConnectionFactory(factory);
return template;
}
@Bean(name = "stringRedisTemplate")
public RedisTemplate<String, String> stringRedisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, String> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
template.setEnableTransactionSupport(true);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jdkSerializationRedisSerializer);
template.setDefaultSerializer(jdkSerializationRedisSerializer);
template.setConnectionFactory(factory);
return template;
}
@Bean(name = "cacheManager")
public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(defaultExpiration);
cacheManager.setUsePrefix(true);
return cacheManager;
}
@Bean(name = "cacheManager")
public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(defaultExpiration);
cacheManager.setUsePrefix(true);
return cacheManager;
}
}
......@@ -47,99 +47,100 @@ import java.text.SimpleDateFormat;
@Configuration
public class HttpConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
registrationBean.setFilter(characterEncodingFilter);
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
registrationBean.setOrder(Integer.MIN_VALUE);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
/**
* 该方法主要对对象json序列化产生影响,其功能如下:
* 1. 禁用缩进输出
* 2. 日期格式排版
* 3. null被过滤掉
* 4. 将enum转为其ordinal
*
* @return Jackson2ObjectMapperBuilder
*/
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(false)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
.defaultViewInclusion(false)
.serializationInclusion(JsonInclude.Include.NON_NULL)
.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_INDEX,
DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);
return builder;
}
@Bean
public ConverterRegistry defaultConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
addFormatters(conversionService);
return conversionService;
}
@Bean
public ConverterRegistry integrationConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
addFormatters(conversionService);
return conversionService;
}
private void addFormatters(FormattingConversionService conversionService) {
IntegerToEnumConverterFactory factory = new IntegerToEnumConverterFactory();
conversionService.removeConvertible(String.class,Enum.class);
conversionService.addConverterFactory(factory);
}
@Bean(name = "httpClient")
public CloseableHttpClient httpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// socket factory
ConnectionSocketFactory plainSocketFactory = new PlainConnectionSocketFactory();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(
null, (x509Certificates, authType) -> true).build();
LayeredConnectionSocketFactory sslSocketFactory =
new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainSocketFactory)
.register("https", sslSocketFactory).build();
// cookie specification
Registry<CookieSpecProvider> cookieSpecProviderRegistry = RegistryBuilder.<CookieSpecProvider>create()
.register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory())
.register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory())
.register("easy", httpContext -> new BrowserCompatSpec() {
@Override
public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException {
}
}).build();
// connection manager
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connectionManager.setMaxTotal(20000);
connectionManager.setDefaultMaxPerRoute(2000);
// retry handler
HttpRequestRetryHandler retryHandler = new StandardHttpRequestRetryHandler(3, false);
// keep alive strategy
ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy();
// httpclient
return HttpClients.custom()
.setConnectionManager(connectionManager)
.setRetryHandler(retryHandler)
.setKeepAliveStrategy(keepAliveStrategy)
.setDefaultCookieSpecRegistry(cookieSpecProviderRegistry).build();
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
registrationBean.setFilter(characterEncodingFilter);
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
registrationBean.setOrder(Integer.MIN_VALUE);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
/**
* 该方法主要对对象json序列化产生影响,其功能如下:
* 1. 禁用缩进输出
* 2. 日期格式排版
* 3. null被过滤掉
* 4. 将enum转为其ordinal
*
* @return Jackson2ObjectMapperBuilder
*/
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(false)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
.defaultViewInclusion(false)
.serializationInclusion(JsonInclude.Include.NON_NULL)
.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_INDEX,
DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);
return builder;
}
@Bean
public ConverterRegistry defaultConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
addFormatters(conversionService);
return conversionService;
}
@Bean
public ConverterRegistry integrationConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
addFormatters(conversionService);
return conversionService;
}
private void addFormatters(FormattingConversionService conversionService) {
IntegerToEnumConverterFactory factory = new IntegerToEnumConverterFactory();
conversionService.removeConvertible(String.class, Enum.class);
conversionService.addConverterFactory(factory);
}
@Bean(name = "httpClient")
public CloseableHttpClient httpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// socket factory
ConnectionSocketFactory plainSocketFactory = new PlainConnectionSocketFactory();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(
null, (x509Certificates, authType) -> true).build();
LayeredConnectionSocketFactory sslSocketFactory =
new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainSocketFactory)
.register("https", sslSocketFactory).build();
// cookie specification
Registry<CookieSpecProvider> cookieSpecProviderRegistry = RegistryBuilder.<CookieSpecProvider>create()
.register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory())
.register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory())
.register("easy", httpContext -> new BrowserCompatSpec() {
@Override
public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException {
}
}).build();
// connection manager
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connectionManager.setMaxTotal(20000);
connectionManager.setDefaultMaxPerRoute(2000);
// retry handler
HttpRequestRetryHandler retryHandler = new StandardHttpRequestRetryHandler(3, false);
// keep alive strategy
ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy();
// httpclient
return HttpClients.custom()
.setConnectionManager(connectionManager)
.setRetryHandler(retryHandler)
.setKeepAliveStrategy(keepAliveStrategy)
.setDefaultCookieSpecRegistry(cookieSpecProviderRegistry).build();
}
}
......@@ -7,33 +7,33 @@ import org.springframework.core.convert.converter.ConverterFactory;
* Created by Miraculous on 15/7/12.
*/
final class IntegerToEnumConverterFactory implements ConverterFactory<String, Enum> {
IntegerToEnumConverterFactory() {
}
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
Class<?> enumType = targetType;
while (enumType != null && !enumType.isEnum()) {
enumType = enumType.getSuperclass();
IntegerToEnumConverterFactory() {
}
if (enumType == null) {
throw new IllegalArgumentException("The target type " + targetType.getName() + " does not refer to an enum");
} else {
return new IntegerToEnumConverterFactory.IntegerToEnum(enumType);
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
Class<?> enumType = targetType;
while (enumType != null && !enumType.isEnum()) {
enumType = enumType.getSuperclass();
}
if (enumType == null) {
throw new IllegalArgumentException("The target type " + targetType.getName() + " does not refer to an enum");
} else {
return new IntegerToEnumConverterFactory.IntegerToEnum(enumType);
}
}
}
private class IntegerToEnum<T extends Enum> implements Converter<String, T> {
private final Class<T> enumType;
private class IntegerToEnum<T extends Enum> implements Converter<String, T> {
private final Class<T> enumType;
public IntegerToEnum(Class<T> enumType) {
this.enumType = enumType;
}
public IntegerToEnum(Class<T> enumType) {
this.enumType = enumType;
}
public T convert(String source) {
T[] ts = enumType.getEnumConstants();
int ordinal = Integer.parseInt(source);
return ordinal < ts.length && ordinal >= 0 ? ts[ordinal] : null;
public T convert(String source) {
T[] ts = enumType.getEnumConstants();
int ordinal = Integer.parseInt(source);
return ordinal < ts.length && ordinal >= 0 ? ts[ordinal] : null;
}
}
}
}
\ No newline at end of file
......@@ -7,10 +7,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@Component
public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.removeConvertible(String.class,Enum.class);
registry.addConverterFactory(new IntegerToEnumConverterFactory());
}
@Override
public void addFormatters(FormatterRegistry registry) {
registry.removeConvertible(String.class, Enum.class);
registry.addConverterFactory(new IntegerToEnumConverterFactory());
}
}
\ No newline at end of file
......@@ -11,15 +11,15 @@ import java.sql.Timestamp;
* Created by Miraculous on 2016/12/29.
*/
public class Timestamp2LongConverter implements ObjectSerializer {
;
;
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
Timestamp time = (Timestamp) object;
if (time == null) {
serializer.write(String.valueOf(0L));
} else {
serializer.write(String.valueOf(time.getTime()));
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
Timestamp time = (Timestamp) object;
if (time == null) {
serializer.write(String.valueOf(0L));
} else {
serializer.write(String.valueOf(time.getTime()));
}
}
}
}
......@@ -14,50 +14,50 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class MotanConfig {
@Bean
public AnnotationBean motanAnnotationBean() {
AnnotationBean motanAnnotationBean = new AnnotationBean();
motanAnnotationBean.setPackage("cn.quantgroup.xyqb.controller.external.motan");
return motanAnnotationBean;
}
@Bean
public AnnotationBean motanAnnotationBean() {
AnnotationBean motanAnnotationBean = new AnnotationBean();
motanAnnotationBean.setPackage("cn.quantgroup.xyqb.controller.external.motan");
return motanAnnotationBean;
}
@Bean(name = "userMotan")
public ProtocolConfigBean protocolConfig1(
@Value("${protocol.isDefault}") Boolean isDefault, @Value("${protocol.name}") String name,
@Value("${protocol.contentLength}") int contentLength) {
ProtocolConfigBean config = new ProtocolConfigBean();
config.setDefault(isDefault);
config.setName(name);
config.setMaxContentLength(contentLength);
config.setMaxServerConnection(1000);
return config;
}
@Bean(name = "userMotan")
public ProtocolConfigBean protocolConfig1(
@Value("${protocol.isDefault}") Boolean isDefault, @Value("${protocol.name}") String name,
@Value("${protocol.contentLength}") int contentLength) {
ProtocolConfigBean config = new ProtocolConfigBean();
config.setDefault(isDefault);
config.setName(name);
config.setMaxContentLength(contentLength);
config.setMaxServerConnection(1000);
return config;
}
@Bean(name = "registryConfig")
public RegistryConfigBean registryConfig(@Value("${registry.protocol}") String registryProtocol,
@Value("${registry.address}") String registryAddress
) {
RegistryConfigBean config = new RegistryConfigBean();
config.setRegProtocol(registryProtocol);
config.setAddress(registryAddress);
return config;
}
@Bean(name = "registryConfig")
public RegistryConfigBean registryConfig(@Value("${registry.protocol}") String registryProtocol,
@Value("${registry.address}") String registryAddress
) {
RegistryConfigBean config = new RegistryConfigBean();
config.setRegProtocol(registryProtocol);
config.setAddress(registryAddress);
return config;
}
@Bean
public BasicServiceConfigBean baseServiceConfig(@Value("${motan.port}") int motanPort,
@Value("${motan.user.group}") String userGroup,
@Value("${motan.user.module}") String userModule,
@Value("${motan.application:xyqbUserMotan}") String applicationName) {
BasicServiceConfigBean config = new BasicServiceConfigBean();
config.setExport("userMotan:" + motanPort);
config.setGroup(userGroup);
config.setVersion("1.0");
config.setAccessLog(true);
config.setShareChannel(true);
config.setModule(userModule);
config.setApplication(applicationName);
config.setRegistry("registryConfig");
return config;
}
@Bean
public BasicServiceConfigBean baseServiceConfig(@Value("${motan.port}") int motanPort,
@Value("${motan.user.group}") String userGroup,
@Value("${motan.user.module}") String userModule,
@Value("${motan.application:xyqbUserMotan}") String applicationName) {
BasicServiceConfigBean config = new BasicServiceConfigBean();
config.setExport("userMotan:" + motanPort);
config.setGroup(userGroup);
config.setVersion("1.0");
config.setAccessLog(true);
config.setShareChannel(true);
config.setModule(userModule);
config.setApplication(applicationName);
config.setRegistry("registryConfig");
return config;
}
}
package cn.quantgroup.xyqb.config.mq;
import cn.quantgroup.xyqb.service.mq.IVestService;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
......@@ -58,28 +50,33 @@ public class LoanVestMQConfig {
connectionFactory.setPublisherConfirms(false);
return connectionFactory;
}
@Primary
@Bean(name= "loanVestAmqpAdmin")
@Bean(name = "loanVestAmqpAdmin")
public AmqpAdmin loanVestAdmin(@Qualifier("vestFactory") ConnectionFactory vestFactory) {
return new RabbitAdmin(vestFactory);
}
@Primary
@Bean(name = "loanVestExchange")
public FanoutExchange loanVestExchange() {
return new FanoutExchange(loanVestExchange);
}
@Primary
@Bean(name = "loanVestQueue")
public Queue loanVestQueue() {
return new Queue(queueName);
}
@Primary
@Bean(name = "loanVestBinding")
public Binding bindingLoanVest(@Qualifier("loanVestAmqpAdmin")AmqpAdmin loanVestAdmin, @Qualifier("loanVestQueue")Queue loanVestQueue, @Qualifier("loanVestExchange")FanoutExchange loanVestExchange) {
public Binding bindingLoanVest(@Qualifier("loanVestAmqpAdmin") AmqpAdmin loanVestAdmin, @Qualifier("loanVestQueue") Queue loanVestQueue, @Qualifier("loanVestExchange") FanoutExchange loanVestExchange) {
Binding binding = BindingBuilder.bind(loanVestQueue).to(loanVestExchange);
loanVestAdmin.declareBinding(binding);
return binding;
}
@Primary
@Bean(name = "rabbitTemplate")
public RabbitTemplate loanVestTemplate(@Qualifier("vestFactory") ConnectionFactory vestFactory) {
......
package cn.quantgroup.xyqb.config.mq;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
......@@ -13,104 +9,102 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* Created by xuran on 2017/9/7.
*/
@Configuration
public class RegisterMqConfig {
@Value("${register.rabbitmq.queue}")
private String queueName;
@Value("${register.rabbitmq.exchange}")
private String registerMqExchange;
@Value("${register.rabbitmq.queue.qq_gdt}")
private String queueName4Gdt;
@Value("${register.rabbitmq.routing_key.qq_gdt}")
private String routingKey4Gdt;
@Value("${register.rabbitmq.exchange.qq_gdt}")
private String exchange4Gdt;
@Value("${register.rabbitmq.connection.host}")
private String host;
@Value("${register.rabbitmq.connection.port}")
private Integer port;
@Value("${register.rabbitmq.connection.user}")
private String user;
@Value("${register.rabbitmq.connection.password}")
private String password;
@Value("${register.rabbitmq.connection.virtual-host}")
private String virtualHost;
@Bean(name = "registerMqFactory")
public ConnectionFactory registerMqFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
connectionFactory.setChannelCacheSize(1024);
connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CONNECTION);
connectionFactory.setChannelCacheSize(180 * 1000);
connectionFactory.setConnectionCacheSize(1024);
connectionFactory.setUsername(user);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setPublisherReturns(false);
connectionFactory.setPublisherConfirms(false);
return connectionFactory;
}
@Bean(name= "registerMqAmqpAdmin")
public AmqpAdmin registerMqAmqpAdmin(@Qualifier("registerMqFactory") ConnectionFactory registerMqFactory) {
return new RabbitAdmin(registerMqFactory);
}
@Bean(name = "registerMqExchange")
public FanoutExchange registerMqExchange() {
return new FanoutExchange(registerMqExchange);
}
@Bean(name = "registerMqQueue")
public Queue registerMqQueue() {
return new Queue(queueName);
}
@Bean(name = "registerMqBinding")
public Binding registerMqBinding(@Qualifier("registerMqAmqpAdmin")AmqpAdmin registerMqAmqpAdmin, @Qualifier("registerMqQueue")Queue registerMqQueue, @Qualifier("registerMqExchange")FanoutExchange registerMqExchange) {
Binding binding = BindingBuilder.bind(registerMqQueue).to(registerMqExchange);
registerMqAmqpAdmin.declareBinding(binding);
return binding;
}
@Bean(name = "registerRabbitTemplate")
public RabbitTemplate registerTemplate(@Qualifier("registerMqFactory") ConnectionFactory registerMqFactory) {
RabbitTemplate template = new RabbitTemplate(registerMqFactory);
template.setExchange(registerMqExchange);
return template;
}
@Bean(name = "registerMqExchange4Gdt")
public FanoutExchange registerMqExchange4Gdt() {
return new FanoutExchange(exchange4Gdt);
}
@Bean(name = "registerMqQueue4Gdt")
public Queue registerMqQueue4Gdt() {
return new Queue(queueName4Gdt);
}
@Bean(name = "registerMqBinding4Gdt")
public Binding registerMqBinding4Gdt(@Qualifier("registerMqAmqpAdmin")AmqpAdmin registerMqAmqpAdmin, @Qualifier("registerMqQueue4Gdt")Queue registerMqQueue4Gdt, @Qualifier("registerMqExchange4Gdt")FanoutExchange registerMqExchange4Gdt) {
Binding binding = BindingBuilder.bind(registerMqQueue4Gdt).to(registerMqExchange4Gdt);
registerMqAmqpAdmin.declareBinding(binding);
return binding;
}
@Bean(name = "registerRabbitTemplate4Gdt")
public RabbitTemplate registerTemplate4Gdt(@Qualifier("registerMqFactory") ConnectionFactory registerMqFactory) {
RabbitTemplate template = new RabbitTemplate(registerMqFactory);
template.setExchange(exchange4Gdt);
return template;
}
@Value("${register.rabbitmq.queue}")
private String queueName;
@Value("${register.rabbitmq.exchange}")
private String registerMqExchange;
@Value("${register.rabbitmq.queue.qq_gdt}")
private String queueName4Gdt;
@Value("${register.rabbitmq.routing_key.qq_gdt}")
private String routingKey4Gdt;
@Value("${register.rabbitmq.exchange.qq_gdt}")
private String exchange4Gdt;
@Value("${register.rabbitmq.connection.host}")
private String host;
@Value("${register.rabbitmq.connection.port}")
private Integer port;
@Value("${register.rabbitmq.connection.user}")
private String user;
@Value("${register.rabbitmq.connection.password}")
private String password;
@Value("${register.rabbitmq.connection.virtual-host}")
private String virtualHost;
@Bean(name = "registerMqFactory")
public ConnectionFactory registerMqFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
connectionFactory.setChannelCacheSize(1024);
connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CONNECTION);
connectionFactory.setChannelCacheSize(180 * 1000);
connectionFactory.setConnectionCacheSize(1024);
connectionFactory.setUsername(user);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setPublisherReturns(false);
connectionFactory.setPublisherConfirms(false);
return connectionFactory;
}
@Bean(name = "registerMqAmqpAdmin")
public AmqpAdmin registerMqAmqpAdmin(@Qualifier("registerMqFactory") ConnectionFactory registerMqFactory) {
return new RabbitAdmin(registerMqFactory);
}
@Bean(name = "registerMqExchange")
public FanoutExchange registerMqExchange() {
return new FanoutExchange(registerMqExchange);
}
@Bean(name = "registerMqQueue")
public Queue registerMqQueue() {
return new Queue(queueName);
}
@Bean(name = "registerMqBinding")
public Binding registerMqBinding(@Qualifier("registerMqAmqpAdmin") AmqpAdmin registerMqAmqpAdmin, @Qualifier("registerMqQueue") Queue registerMqQueue, @Qualifier("registerMqExchange") FanoutExchange registerMqExchange) {
Binding binding = BindingBuilder.bind(registerMqQueue).to(registerMqExchange);
registerMqAmqpAdmin.declareBinding(binding);
return binding;
}
@Bean(name = "registerRabbitTemplate")
public RabbitTemplate registerTemplate(@Qualifier("registerMqFactory") ConnectionFactory registerMqFactory) {
RabbitTemplate template = new RabbitTemplate(registerMqFactory);
template.setExchange(registerMqExchange);
return template;
}
@Bean(name = "registerMqExchange4Gdt")
public FanoutExchange registerMqExchange4Gdt() {
return new FanoutExchange(exchange4Gdt);
}
@Bean(name = "registerMqQueue4Gdt")
public Queue registerMqQueue4Gdt() {
return new Queue(queueName4Gdt);
}
@Bean(name = "registerMqBinding4Gdt")
public Binding registerMqBinding4Gdt(@Qualifier("registerMqAmqpAdmin") AmqpAdmin registerMqAmqpAdmin, @Qualifier("registerMqQueue4Gdt") Queue registerMqQueue4Gdt, @Qualifier("registerMqExchange4Gdt") FanoutExchange registerMqExchange4Gdt) {
Binding binding = BindingBuilder.bind(registerMqQueue4Gdt).to(registerMqExchange4Gdt);
registerMqAmqpAdmin.declareBinding(binding);
return binding;
}
@Bean(name = "registerRabbitTemplate4Gdt")
public RabbitTemplate registerTemplate4Gdt(@Qualifier("registerMqFactory") ConnectionFactory registerMqFactory) {
RabbitTemplate template = new RabbitTemplate(registerMqFactory);
template.setExchange(exchange4Gdt);
return template;
}
}
......@@ -18,6 +18,7 @@ public class AsyncConfig {
/**
* 生成线程池
*
* @param corePoolSize
* @param maxPoolSize
* @param queueCapacity
......@@ -28,7 +29,7 @@ public class AsyncConfig {
private ThreadPoolTaskExecutor generateThreadPoolTaskExecutor(int corePoolSize, int maxPoolSize, int queueCapacity,
boolean waitForCompleteOnShutdown, int keepAliveSeconds,
boolean allowCoreThreadTimeOut, String prefix) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
......@@ -37,14 +38,16 @@ public class AsyncConfig {
executor.setWaitForTasksToCompleteOnShutdown(waitForCompleteOnShutdown);
executor.setThreadNamePrefix(prefix);
executor.initialize();
return executor ;
return executor;
}
/**
* 日志线程池
*
* @return
*/
@Bean(name = "logExecutor")
public Executor loanMqExecutor(){
public Executor loanMqExecutor() {
return generateThreadPoolTaskExecutor(100, 2000, 2000, true, 30, true, "loanMqExecutor-");
}
}
package cn.quantgroup.xyqb.constant;
public class UserConstant {
public static final String USER_ERROR_OR_PASSWORD_ERROR = "帐号或密码错误";
public static final String USER_ERROR_OR_PASSWORD_ERROR = "帐号或密码错误";
}
......@@ -24,69 +24,72 @@ import javax.servlet.http.HttpServletRequest;
@RestController
public class ExceptionHandlingController implements IBaseController {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandlingController.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandlingController.class);
private static final JsonResult EXCEPTION_RESULT = new JsonResult("internal error", 500L, "");
private static final JsonResult EXCEPTION_RESULT = new JsonResult("internal error", 500L, "");
/**
* 密码错误次数达到上限异常
*
* @param vce
* @return
*/
@ExceptionHandler(PasswordErrorLimitException.class)
public JsonResult passwordErrorLimitException(PasswordErrorLimitException vce) {
LOGGER.info("throw PasswordErrorLimitException,msg={},businessCode={}, clientIp={}", vce.getMessage(), 2L, IPUtil.getRemoteIP(getRequest()));
return JsonResult.buildErrorStateResult(vce.getMessage(), null, 2L);
}
/**
* 密码错误次数达到上限异常
*
* @param vce
* @return
*/
@ExceptionHandler(PasswordErrorLimitException.class)
public JsonResult passwordErrorLimitException(PasswordErrorLimitException vce) {
LOGGER.info("throw PasswordErrorLimitException,msg={},businessCode={}, clientIp={}", vce.getMessage(), 2L, IPUtil.getRemoteIP(getRequest()));
return JsonResult.buildErrorStateResult(vce.getMessage(), null, 2L);
}
/**
* 短信验证码错误或失效异常
*
* @param vce
* @return
*/
@ExceptionHandler(VerificationCodeErrorException.class)
public JsonResult verificationCodeErrorException(VerificationCodeErrorException vce) {
LOGGER.info("throw VerificationCodeErrorException,msg={},businessCode={}, clientIp={}", vce.getMessage(), 1L, IPUtil.getRemoteIP(getRequest()));
return JsonResult.buildErrorStateResult(vce.getMessage(), null, 1L);
}
/**
* 短信验证码错误或失效异常
*
* @param vce
* @return
*/
@ExceptionHandler(VerificationCodeErrorException.class)
public JsonResult verificationCodeErrorException(VerificationCodeErrorException vce) {
LOGGER.info("throw VerificationCodeErrorException,msg={},businessCode={}, clientIp={}", vce.getMessage(), 1L, IPUtil.getRemoteIP(getRequest()));
return JsonResult.buildErrorStateResult(vce.getMessage(), null, 1L);
}
/**
* 用户不存在异常
* @param unee
* @return
*/
@ExceptionHandler(UserNotExistException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public JsonResult userNotExistException(UserNotExistException unee) {
LOGGER.info("throw UserNotExistException,msg={},businessCode={},code={}", unee.getMessage(), 1L, 401L);
return new JsonResult(unee.getMessage(), 401L, null);
}
/**
* 用户不存在异常
*
* @param unee
* @return
*/
@ExceptionHandler(UserNotExistException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public JsonResult userNotExistException(UserNotExistException unee) {
LOGGER.info("throw UserNotExistException,msg={},businessCode={},code={}", unee.getMessage(), 1L, 401L);
return new JsonResult(unee.getMessage(), 401L, null);
}
/**
* 微信关联异常
* @param wrue
* @return
*/
@ExceptionHandler(WechatRelateUserException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public JsonResult wechatRelateUserException(WechatRelateUserException wrue) {
LOGGER.info("throw WechatRelateUserException,msg={},businessCode={},code={}", wrue.getMessage(), 1L, 401L);
return new JsonResult(wrue.getMessage(), 401L, null);
}
/**
* 微信关联异常
*
* @param wrue
* @return
*/
@ExceptionHandler(WechatRelateUserException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public JsonResult wechatRelateUserException(WechatRelateUserException wrue) {
LOGGER.info("throw WechatRelateUserException,msg={},businessCode={},code={}", wrue.getMessage(), 1L, 401L);
return new JsonResult(wrue.getMessage(), 401L, null);
}
/**
* 其他全局异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public JsonResult exceptionOccurs(Exception e) {
HttpServletRequest request = getRequest();
String uri = request.getRequestURI();
String registerFrom = request.getParameter("registerFrom");
LOGGER.error("[exception][global_exception]接口异常 URI:{}, registerFrom:{},error={}", uri, registerFrom, e);
return EXCEPTION_RESULT;
}
/**
* 其他全局异常
*
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public JsonResult exceptionOccurs(Exception e) {
HttpServletRequest request = getRequest();
String uri = request.getRequestURI();
String registerFrom = request.getParameter("registerFrom");
LOGGER.error("[exception][global_exception]接口异常 URI:{}, registerFrom:{},error={}", uri, registerFrom, e);
return EXCEPTION_RESULT;
}
}
......@@ -8,7 +8,6 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
......@@ -16,63 +15,64 @@ import java.util.Objects;
import static cn.quantgroup.xyqb.session.XyqbSessionContextHolder.getXSession;
import static cn.quantgroup.xyqb.session.XyqbSessionContextHolder.getXSessionFromRedis;
/**
* Created by Miraculous on 15/7/5.
*/
public interface IBaseController {
@Deprecated
default User getCurrentUser() {
SessionStruct session = getXSession();
if (session == null) {
return null;
@Deprecated
default User getCurrentUser() {
SessionStruct session = getXSession();
if (session == null) {
return null;
}
return getXSession().getValues().getUser();
}
return getXSession().getValues().getUser();
}
@Deprecated
default SessionStruct getSessionStruct() {
return getXSession();
}
@Deprecated
default SessionStruct getSessionStruct() {
return getXSession();
}
default User getCurrentUserFromRedis() {
SessionStruct session = getXSessionFromRedis();
if (session == null) {
return null;
default User getCurrentUserFromRedis() {
SessionStruct session = getXSessionFromRedis();
if (session == null) {
return null;
}
return session.getValues().getUser();
}
return session.getValues().getUser();
}
default SessionStruct getCurrentSessionFromRedis(){
return getXSessionFromRedis();
}
default SessionStruct getCurrentSessionFromRedis() {
return getXSessionFromRedis();
}
default HttpServletRequest getRequest() {
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
return attrs.getRequest();
}
default HttpServletRequest getRequest() {
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
return attrs.getRequest();
}
default String getIp() {
HttpServletRequest request = getRequest();
return IPUtil.getRemoteIP(request);
}
default String getIp() {
HttpServletRequest request = getRequest();
return IPUtil.getRemoteIP(request);
}
default String getProtocol() {
return StringUtils.startsWith(getRequest().getHeader("x-forwarded-proto"), "https") ? "https:" : "http:";
}
default String getProtocol() {
return StringUtils.startsWith(getRequest().getHeader("x-forwarded-proto"), "https") ? "https:" : "http:";
}
default Map<String, String> getRequestHeaderMap(HttpServletRequest request) {
Enumeration<String> headerNames = request.getHeaderNames();
HashMap<String, String> map = new HashMap<>();
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
if(Objects.equals("authorization", key)){
continue;
}
map.put(key, request.getHeader(key));
default Map<String, String> getRequestHeaderMap(HttpServletRequest request) {
Enumeration<String> headerNames = request.getHeaderNames();
HashMap<String, String> map = new HashMap<>();
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
if (Objects.equals("authorization", key)) {
continue;
}
map.put(key, request.getHeader(key));
}
return map;
}
return map;
}
}
......@@ -4,8 +4,6 @@ import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.captcha.CaptchaValidator;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService;
import java.util.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
......@@ -17,6 +15,9 @@ import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 类名称:ImgCaptchaController
......@@ -29,43 +30,44 @@ import java.io.IOException;
@RequestMapping("/api")
public class ImageCaptchaController {
private static final String IMAGE_FORMAT_PNG = "png";
private static final String IMG_BASE64_PATTREN = "data:image/" + IMAGE_FORMAT_PNG + ";base64,%s";
private static final String IMAGE_FORMAT_PNG = "png";
private static final String IMG_BASE64_PATTREN = "data:image/" + IMAGE_FORMAT_PNG + ";base64,%s";
@Autowired
@Qualifier("customCaptchaService")
private AbstractManageableImageCaptchaService imageCaptchaService;
@Autowired
@Qualifier("customCaptchaService")
private AbstractManageableImageCaptchaService imageCaptchaService;
/**
* 获取验证码
* 默认匹配 GET /captcha, 提供4位数字和字母混合图片验证码
*/
@RequestMapping(value = "/captcha")
public JsonResult fetchCaptcha(HttpServletRequest request) {
String imageId = UUID.randomUUID().toString();
BufferedImage challenge = imageCaptchaService.getImageChallengeForID(Constants.IMAGE_CAPTCHA_KEY + imageId, request.getLocale());
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
boolean write = ImageIO.write(challenge, IMAGE_FORMAT_PNG, jpegOutputStream);
} catch (IOException e) {
e.printStackTrace();
return JsonResult.buildErrorStateResult("", "fail");
}
/**
* 获取验证码
* 默认匹配 GET /captcha, 提供4位数字和字母混合图片验证码
*/
@RequestMapping(value = "/captcha")
public JsonResult fetchCaptcha(HttpServletRequest request) {
String imageId = UUID.randomUUID().toString();
BufferedImage challenge = imageCaptchaService.getImageChallengeForID(Constants.IMAGE_CAPTCHA_KEY + imageId, request.getLocale());
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
boolean write = ImageIO.write(challenge, IMAGE_FORMAT_PNG, jpegOutputStream);
} catch (IOException e) {
e.printStackTrace();
return JsonResult.buildErrorStateResult("", "fail");
}
String imageBase64 = Base64.encodeBase64String(jpegOutputStream.toByteArray());
String imageBase64 = Base64.encodeBase64String(jpegOutputStream.toByteArray());
Map<String, String> data = new HashMap<>();
data.put("imageId", imageId);
data.put("image", String.format(IMG_BASE64_PATTREN, imageBase64));
return JsonResult.buildSuccessResult("", data);
}
/**
* 图片验证码验证
* 注意:本方法有中间层在用,用于QG图形验证码检验
*/
@CaptchaValidator
@RequestMapping("/verification_image_code")
public JsonResult verificationImageCode() {
return JsonResult.buildSuccessResult("", null);
}
Map<String, String> data = new HashMap<>();
data.put("imageId", imageId);
data.put("image", String.format(IMG_BASE64_PATTREN, imageBase64));
return JsonResult.buildSuccessResult("", data);
}
/**
* 图片验证码验证
* 注意:本方法有中间层在用,用于QG图形验证码检验
*/
@CaptchaValidator
@RequestMapping("/verification_image_code")
public JsonResult verificationImageCode() {
return JsonResult.buildSuccessResult("", null);
}
}
package cn.quantgroup.xyqb.controller.external.captcha;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator;
import cn.quantgroup.xyqb.aspect.logcaller.LogHttpCaller;
import cn.quantgroup.xyqb.model.ClientType;
import cn.quantgroup.xyqb.model.JsonResult;
......@@ -18,7 +17,10 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* @author xufei on 2018/1/30.
......@@ -52,17 +54,17 @@ public class NewCaptchaController {
Map<String, String> data = new HashMap<String, String>();
Map<String, String> imgMap = null;
// 优先获取极验
if(!Boolean.valueOf(geetestClose)){
if (!Boolean.valueOf(geetestClose)) {
imgMap = geetestCaptchaService.fetchGeetestCaptcha(keyMd5, remoteIp, ClientType.valueByName(clientType));
data.put(Constants.VERIFY_PARAM, Constants.VERIFY_TYPE_GT);
}
// 备选方案:量化派图形验证码
if(Objects.isNull(imgMap) || imgMap.isEmpty()){
if (Objects.isNull(imgMap) || imgMap.isEmpty()) {
imgMap = quantgroupCaptchaService.fetchQuantgroupCaptcha(request.getLocale());
data.put(Constants.VERIFY_PARAM, Constants.VERIFY_TYPE_QG);
}
// 返回结果
if(Objects.isNull(imgMap) || imgMap.isEmpty()){
if (Objects.isNull(imgMap) || imgMap.isEmpty()) {
return JsonResult.buildErrorStateResult("获取验证码失败", "");
}
// 填充数据并返回
......
......@@ -14,12 +14,12 @@ import javax.servlet.http.HttpServletRequest;
@Slf4j
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/hello")
public String hello(HttpServletRequest request) {
String ip = IPUtil.getRemoteIP(request);
if(ip.startsWith("192.168.12.")){
log.error("测试:", new Exception("Sentry捕获异常"));
@RequestMapping("/hello")
public String hello(HttpServletRequest request) {
String ip = IPUtil.getRemoteIP(request);
if (ip.startsWith("192.168.12.")) {
log.error("测试:", new Exception("Sentry捕获异常"));
}
return "ok";
}
return "ok";
}
}
......@@ -12,21 +12,21 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/motan")
public class MotanController {
@RequestMapping("/enable/{key}")
public JsonResult reload(@PathVariable String key) {
if (StringUtils.equals(key, "b5140fb2-2c85-4b5a-abcf-3e97528014db")) {
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);
return JsonResult.buildSuccessResult("加载成功", null);
@RequestMapping("/enable/{key}")
public JsonResult reload(@PathVariable String key) {
if (StringUtils.equals(key, "b5140fb2-2c85-4b5a-abcf-3e97528014db")) {
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);
return JsonResult.buildSuccessResult("加载成功", null);
}
return JsonResult.buildErrorStateResult("无效", null);
}
return JsonResult.buildErrorStateResult("无效", null);
}
@RequestMapping("/disable/{key}")
public JsonResult disable(@PathVariable String key) {
if (StringUtils.equals(key, "b5140fb2-2c85-4b5a-abcf-3e97528014db")) {
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false);
return JsonResult.buildSuccessResult("加载成功", null);
@RequestMapping("/disable/{key}")
public JsonResult disable(@PathVariable String key) {
if (StringUtils.equals(key, "b5140fb2-2c85-4b5a-abcf-3e97528014db")) {
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false);
return JsonResult.buildSuccessResult("加载成功", null);
}
return JsonResult.buildErrorStateResult("无效", null);
}
return JsonResult.buildErrorStateResult("无效", null);
}
}
......@@ -28,103 +28,103 @@ import java.util.Objects;
@RestController
@RequestMapping("/api/sync")
public class SyncUserController {
private static final Logger LOGGER = LoggerFactory.getLogger(SyncUserController.class);
private static final Logger LOGGER = LoggerFactory.getLogger(SyncUserController.class);
@Autowired
private IUserService userService;
@Autowired
private IUserDetailService userDetailService;
@Autowired
private IIdCardService idCardService;
@Autowired
private IUserService userService;
@Autowired
private IUserDetailService userDetailService;
@Autowired
private IIdCardService idCardService;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@RequestMapping("/user")
public JsonResult fetchUser(String key, String phoneNo) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key)) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.isEmpty(phoneNo)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByPhoneInDb(phoneNo);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
UserDetail detail = userDetailService.findByUserId(user.getId());
if (null == detail) {
// FIXME: 16/4/15 前期不对身份证强制要求.后期对修改
@RequestMapping("/user")
public JsonResult fetchUser(String key, String phoneNo) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key)) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.isEmpty(phoneNo)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByPhoneInDb(phoneNo);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
UserDetail detail = userDetailService.findByUserId(user.getId());
if (null == detail) {
// FIXME: 16/4/15 前期不对身份证强制要求.后期对修改
// return JsonResult.buildErrorStateResult(null, null);
}
UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel);
}
UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel);
}
@RequestMapping("/save_detail")
public JsonResult saveUserDetail(String key, UserDetail userDetail) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key) || Objects.isNull(userDetail) || StringUtils.isBlank(userDetail.getPhoneNo())) {
return JsonResult.buildErrorStateResult(null, null);
}
if (!ValidationUtil.validateChinese(userDetail.getName())) {
return JsonResult.buildErrorStateResult("姓名错误", null);
}
IdCardInfo info = null;
try {
info = idCardService.getIdCardInfo(userDetail.getIdNo());
} catch (ParseException ex) {
LOGGER.error("身份证号错误, idNo: {}", userDetail.getIdNo());
return JsonResult.buildErrorStateResult("身份证号码错误", null);
}
if (Objects.isNull(info) || !info.isValid()) {
return JsonResult.buildErrorStateResult("身份证号码错误", null);
}
String phoneNo = userDetail.getPhoneNo();
User user = userService.findByPhoneWithCache(phoneNo);
if(Objects.isNull(user)){
return JsonResult.buildErrorStateResult(null, null);
}
userDetail.setUserId(user.getId());
@RequestMapping("/save_detail")
public JsonResult saveUserDetail(String key, UserDetail userDetail) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key) || Objects.isNull(userDetail) || StringUtils.isBlank(userDetail.getPhoneNo())) {
return JsonResult.buildErrorStateResult(null, null);
}
if (!ValidationUtil.validateChinese(userDetail.getName())) {
return JsonResult.buildErrorStateResult("姓名错误", null);
}
IdCardInfo info = null;
try {
info = idCardService.getIdCardInfo(userDetail.getIdNo());
} catch (ParseException ex) {
LOGGER.error("身份证号错误, idNo: {}", userDetail.getIdNo());
return JsonResult.buildErrorStateResult("身份证号码错误", null);
}
if (Objects.isNull(info) || !info.isValid()) {
return JsonResult.buildErrorStateResult("身份证号码错误", null);
}
String phoneNo = userDetail.getPhoneNo();
User user = userService.findByPhoneWithCache(phoneNo);
if (Objects.isNull(user)) {
return JsonResult.buildErrorStateResult(null, null);
}
userDetail.setUserId(user.getId());
/*
* 如果已存在记录,则更新
*/
UserDetail theUserDetail = userDetailService.findByUserId(user.getId());
if(Objects.isNull(theUserDetail)){
theUserDetail = userDetailService.findByPhoneNo(phoneNo);
// 按手机号查出记录,如果userId非空,说明是存疑数据或是其他用户的信息,停止修改操作,返回失败
if(Objects.nonNull(theUserDetail) && Objects.nonNull(theUserDetail.getUserId())){
return JsonResult.buildErrorStateResult("手机号已使用.", null);
}
}
if(Objects.isNull(theUserDetail)){
userDetail.setId(null);
}else {
userDetail.setId(theUserDetail.getId());
UserDetail theUserDetail = userDetailService.findByUserId(user.getId());
if (Objects.isNull(theUserDetail)) {
theUserDetail = userDetailService.findByPhoneNo(phoneNo);
// 按手机号查出记录,如果userId非空,说明是存疑数据或是其他用户的信息,停止修改操作,返回失败
if (Objects.nonNull(theUserDetail) && Objects.nonNull(theUserDetail.getUserId())) {
return JsonResult.buildErrorStateResult("手机号已使用.", null);
}
}
if (Objects.isNull(theUserDetail)) {
userDetail.setId(null);
} else {
userDetail.setId(theUserDetail.getId());
}
userDetailService.saveUserDetail(userDetail);
return JsonResult.buildSuccessResult(null, null);
}
userDetailService.saveUserDetail(userDetail);
return JsonResult.buildSuccessResult(null, null);
}
@RequestMapping("/user_uuid")
public JsonResult fetchUserByUuid(String key, String uuid) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key)) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.isEmpty(uuid)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByUuidWithCache(uuid);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
UserDetail detail = userDetailService.findByUserId(user.getId());
if (null == detail) {
// FIXME: 16/4/15 前期不对身份证强制要求.后期对修改
@RequestMapping("/user_uuid")
public JsonResult fetchUserByUuid(String key, String uuid) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key)) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.isEmpty(uuid)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByUuidWithCache(uuid);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
UserDetail detail = userDetailService.findByUserId(user.getId());
if (null == detail) {
// FIXME: 16/4/15 前期不对身份证强制要求.后期对修改
// return JsonResult.buildErrorStateResult(null, null);
}
UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel);
}
UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel);
}
}
......@@ -30,95 +30,95 @@ import java.util.Objects;
@RequestMapping("/api")
public class UserApiController {
@Resource
private IUserService userService;
@Resource
private IUserApiService userApiService;
@Resource
private ISessionService sessionService;
@Resource
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@Resource
private IUserService userService;
@Resource
private IUserApiService userApiService;
@Resource
private ISessionService sessionService;
@Resource
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@RequestMapping("/user/check")
public JsonResult userImportCheck(String phoneNo, String registerFrom) {
if ("244".equals(registerFrom)) {
log.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("用户导入检查拒绝", false);
}
if (StringUtils.isEmpty(phoneNo) || StringUtils.isEmpty(registerFrom)) {
log.error("[user_import_check]检查传入的参数,参数不全。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("检查传入的参数,参数不全。", null);
}
boolean checkPassed = userApiService.userImportCheck(phoneNo);
if (checkPassed) {
log.info("[user_import_check]用户可以导入。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildSuccessResult("用户可以导入", checkPassed);
@RequestMapping("/user/check")
public JsonResult userImportCheck(String phoneNo, String registerFrom) {
if ("244".equals(registerFrom)) {
log.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("用户导入检查拒绝", false);
}
if (StringUtils.isEmpty(phoneNo) || StringUtils.isEmpty(registerFrom)) {
log.error("[user_import_check]检查传入的参数,参数不全。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("检查传入的参数,参数不全。", null);
}
boolean checkPassed = userApiService.userImportCheck(phoneNo);
if (checkPassed) {
log.info("[user_import_check]用户可以导入。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildSuccessResult("用户可以导入", checkPassed);
}
log.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("用户导入检查拒绝", checkPassed);
}
log.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("用户导入检查拒绝", checkPassed);
}
@RequestMapping("/user/is_passwd_set")
public JsonResult isPasswordSet(String key, String phoneNo) {
if (!"abc1234".equals(key) || StringUtils.isEmpty(phoneNo)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByPhoneWithCache(phoneNo);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.length(user.getPassword()) == 32) {
return JsonResult.buildSuccessResult(null, null);
@RequestMapping("/user/is_passwd_set")
public JsonResult isPasswordSet(String key, String phoneNo) {
if (!"abc1234".equals(key) || StringUtils.isEmpty(phoneNo)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByPhoneWithCache(phoneNo);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.length(user.getPassword()) == 32) {
return JsonResult.buildSuccessResult(null, null);
}
return JsonResult.buildErrorStateResult(null, null, 2L);
}
return JsonResult.buildErrorStateResult(null, null, 2L);
}
/**
* 检查token是否有效
* 如果有效,可选择是否延续生命期(延续后有效期24Hour)
*
* @param token - sid,session的id
* @param prolong - 是否延续生命期,可选参数,默认为: false - 不延续
* @return
*/
@ApiOperation(notes = "检查token是否有效,如果有效,可选择是否延续生命期(延续后有效期24Hour)", value = "Check token and then prolong session", nickname = "checkToken")
@LogHttpCaller
@IpValidator
@RequestMapping(value = "/valid/{token}", method = RequestMethod.POST)
public JsonResult checkToken(@ApiParam(value = "sid,session的id", required = true) @PathVariable("token") String token,
@ApiParam(value = "是否延续生命期,可选参数,默认为: false - 不延续", required = false) @RequestParam(name = "prolong", required = false, defaultValue = "false") Boolean prolong) {
if(Objects.isNull(token) || !ValidationUtil.validateToken(token)){
return JsonResult.buildErrorStateResult("token invalid", token);
}
String tokenKey = Constants.SESSION_PREFIX + token;
String tokenKey2 = Constants.Session.USER_SESSION_CACHE + token;
// 判断token是否存在
boolean exist = stringRedisTemplate.hasKey(tokenKey)||stringRedisTemplate.hasKey(tokenKey2);
log.info("检查token:[{}]有效性[{}],延续生命期[{}]", token, exist, prolong);
/**
* 检查token是否有效
* 如果有效,可选择是否延续生命期(延续后有效期24Hour)
*
* @param token - sid,session的id
* @param prolong - 是否延续生命期,可选参数,默认为: false - 不延续
* @return
*/
@ApiOperation(notes = "检查token是否有效,如果有效,可选择是否延续生命期(延续后有效期24Hour)", value = "Check token and then prolong session", nickname = "checkToken")
@LogHttpCaller
@IpValidator
@RequestMapping(value = "/valid/{token}", method = RequestMethod.POST)
public JsonResult checkToken(@ApiParam(value = "sid,session的id", required = true) @PathVariable("token") String token,
@ApiParam(value = "是否延续生命期,可选参数,默认为: false - 不延续", required = false) @RequestParam(name = "prolong", required = false, defaultValue = "false") Boolean prolong) {
if (Objects.isNull(token) || !ValidationUtil.validateToken(token)) {
return JsonResult.buildErrorStateResult("token invalid", token);
}
String tokenKey = Constants.SESSION_PREFIX + token;
String tokenKey2 = Constants.Session.USER_SESSION_CACHE + token;
// 判断token是否存在
boolean exist = stringRedisTemplate.hasKey(tokenKey) || stringRedisTemplate.hasKey(tokenKey2);
log.info("检查token:[{}]有效性[{}],延续生命期[{}]", token, exist, prolong);
/* token存在且需要延续时,进一步判断session是否有效,有效时,自动续期 */
if(Boolean.logicalAnd(exist, prolong)){
// 获取session信息
SessionStruct sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis(token);
if(Objects.isNull(sessionStruct)) {
log.info("延续token:[{}]生命期,result:[{}],SessionStruct:{}", token, false, sessionStruct);
if (Boolean.logicalAnd(exist, prolong)) {
// 获取session信息
SessionStruct sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis(token);
if (Objects.isNull(sessionStruct)) {
log.info("延续token:[{}]生命期,result:[{}],SessionStruct:{}", token, false, sessionStruct);
/* 如果没有获取到session信息则返回错误信息 */
return JsonResult.buildErrorStateResult("session invalid", token);
}else{
return JsonResult.buildErrorStateResult("session invalid", token);
} else {
/* 延续session生命期 */
try {
sessionService.persistSession(sessionStruct.getSid(), sessionStruct.getValues());
log.info("延续token:[{}]生命期,result:[{}]", token, true);
} finally {
XyqbSessionContextHolder.releaseSession();
try {
sessionService.persistSession(sessionStruct.getSid(), sessionStruct.getValues());
log.info("延续token:[{}]生命期,result:[{}]", token, true);
} finally {
XyqbSessionContextHolder.releaseSession();
}
}
}
if (exist) {
return JsonResult.buildSuccessResult("token valid", token);
} else {
return JsonResult.buildErrorStateResult("token invalid", token);
}
}
}
if(exist){
return JsonResult.buildSuccessResult("token valid", token);
}else{
return JsonResult.buildErrorStateResult("token invalid", token);
}
}
}
......@@ -13,11 +13,11 @@ import java.io.PrintWriter;
@RequestMapping("/")
public class WechatVerifyController {
@RequestMapping("/MP_verify_AWiagUn4kZiwmTt0.txt")
public void verifyWechat(HttpServletResponse response) throws Exception {
response.setContentType("plain/text");
PrintWriter writer = response.getWriter();
writer.print("AWiagUn4kZiwmTt0");
writer.close();
}
@RequestMapping("/MP_verify_AWiagUn4kZiwmTt0.txt")
public void verifyWechat(HttpServletResponse response) throws Exception {
response.setContentType("plain/text");
PrintWriter writer = response.getWriter();
writer.print("AWiagUn4kZiwmTt0");
writer.close();
}
}
......@@ -6,13 +6,9 @@ import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.UserRet;
import cn.quantgroup.xyqb.model.session.LoginInfo;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.service.http.IHttpService;
import cn.quantgroup.xyqb.service.user.IUserBtRegisterService;
import cn.quantgroup.xyqb.service.user.IUserService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
......@@ -28,27 +24,27 @@ import javax.servlet.http.HttpServletRequest;
public class AuthInfoController implements IBaseController {
@LogHttpCaller
@RequestMapping("/info/login")
public JsonResult loginInfo(HttpServletRequest request) {
SessionStruct sessionStruct = getCurrentSessionFromRedis();
if(null != sessionStruct) {
log.info("从用户中心获取到了用户登录信息:phone:[{}]", sessionStruct.getValues().getUser().getPhoneNo());
LoginInfo loginInfo = new LoginInfo();
loginInfo.setUser(new UserRet(sessionStruct.getValues().getUser()));
loginInfo.setToken(sessionStruct.getSid());
LoginInfo.LoginContext context = new LoginInfo.LoginContext();
context.setChannelId(sessionStruct.getValues().getLoginProperties().getChannelId());
context.setCreatedFrom(sessionStruct.getValues().getLoginProperties().getCreatedFrom());
context.setAppChannel(sessionStruct.getValues().getLoginProperties().getAppChannel());
context.setBtMerchantId(sessionStruct.getValues().getLoginProperties().getBtMerchantId());
//有ThreadLocal不释放的问题,不可再使用原来方式了
loginInfo.setLoginContext(context);
log.info("[/auth/info/login] SessionStruct数据:{}, LoginInfo数据:{}", JSONObject.toJSONString(sessionStruct), JSONObject.toJSONString(loginInfo));
return JsonResult.buildSuccessResult("", loginInfo);
@LogHttpCaller
@RequestMapping("/info/login")
public JsonResult loginInfo(HttpServletRequest request) {
SessionStruct sessionStruct = getCurrentSessionFromRedis();
if (null != sessionStruct) {
log.info("从用户中心获取到了用户登录信息:phone:[{}]", sessionStruct.getValues().getUser().getPhoneNo());
LoginInfo loginInfo = new LoginInfo();
loginInfo.setUser(new UserRet(sessionStruct.getValues().getUser()));
loginInfo.setToken(sessionStruct.getSid());
LoginInfo.LoginContext context = new LoginInfo.LoginContext();
context.setChannelId(sessionStruct.getValues().getLoginProperties().getChannelId());
context.setCreatedFrom(sessionStruct.getValues().getLoginProperties().getCreatedFrom());
context.setAppChannel(sessionStruct.getValues().getLoginProperties().getAppChannel());
context.setBtMerchantId(sessionStruct.getValues().getLoginProperties().getBtMerchantId());
//有ThreadLocal不释放的问题,不可再使用原来方式了
loginInfo.setLoginContext(context);
log.info("[/auth/info/login] SessionStruct数据:{}, LoginInfo数据:{}", JSONObject.toJSONString(sessionStruct), JSONObject.toJSONString(loginInfo));
return JsonResult.buildSuccessResult("", loginInfo);
}
log.info("[/auth/info/login] 未查到用户登录信息, request-Header:{}", JSON.toJSONString(getRequestHeaderMap(request)));
return JsonResult.buildErrorStateResult("用户未登录", null);
}
log.info("[/auth/info/login] 未查到用户登录信息, request-Header:{}", JSON.toJSONString(getRequestHeaderMap(request)));
return JsonResult.buildErrorStateResult("用户未登录",null);
}
}
......@@ -4,18 +4,13 @@ import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.entity.Merchant;
import cn.quantgroup.xyqb.entity.MerchantConfig;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.Tuple;
import cn.quantgroup.xyqb.service.merchant.IMerchantService;
import cn.quantgroup.xyqb.service.page.IPageService;
import cn.quantgroup.xyqb.service.page.bean.PageType;
import cn.quantgroup.xyqb.service.user.IUserDetailService;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
......@@ -28,54 +23,54 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/platform/api")
public class PlatformAPIController implements IBaseController {
@Autowired
private IPageService pageService;
@Autowired
private IMerchantService merchantService;
@Autowired
private IUserDetailService userDetailService;
@Autowired
private IPageService pageService;
@Autowired
private IMerchantService merchantService;
@Autowired
private IUserDetailService userDetailService;
@RequestMapping("/page/return_url")
public JsonResult returnUrl(String key) {
Merchant merchant = merchantService.findMerchantByName(key);
if (null == merchant) {
return JsonResult.buildErrorStateResult("", null);
@RequestMapping("/page/return_url")
public JsonResult returnUrl(String key) {
Merchant merchant = merchantService.findMerchantByName(key);
if (null == merchant) {
return JsonResult.buildErrorStateResult("", null);
}
MerchantConfig config = merchantService.findConfigByMerchantIdAndConfigName(merchant.getId(), "returnUrl");
if (null == config) {
return JsonResult.buildSuccessResult("", null);
}
return JsonResult.buildSuccessResult("", config.getConfigValue());
}
MerchantConfig config = merchantService.findConfigByMerchantIdAndConfigName(merchant.getId(), "returnUrl");
if (null == config) {
return JsonResult.buildSuccessResult("", null);
}
return JsonResult.buildSuccessResult("", config.getConfigValue());
}
@RequestMapping("/page/next")
public JsonResult nextPage(String key, String target, @RequestParam(required = false, defaultValue = "") String currentPage) {
User user = getCurrentUserFromRedis();
if (null == user) {
return JsonResult.buildErrorStateResult("未找到用户", null);
}
Tuple<String, Boolean> nextPageTuple = pageService.nextPage(user, target, currentPage);
Boolean isFinal = nextPageTuple.getValue();
String nextPage = nextPageTuple.getKey();
if("xyqb".equals(key)){
MerchantConfig merchantConfig = merchantService.findConfigByMerchantIdAndConfigName(4L, "returnUrl");
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "external", "transition", merchantConfig.getConfigValue()));
}
if (isFinal) {
Merchant merchant = merchantService.findMerchantByName(key);
if (merchant == null) {
return JsonResult.buildSuccessResult("", null);
}
MerchantConfig merchantConfig = merchantService.findConfigByMerchantIdAndConfigName(merchant.getId(), "returnUrl");
if (merchantConfig == null) {
return JsonResult.buildSuccessResult("", null);
}
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "external", "transition", merchantConfig.getConfigValue()));
}
if (StringUtils.isEmpty(nextPage)) {
return JsonResult.buildErrorStateResult("", null);
@RequestMapping("/page/next")
public JsonResult nextPage(String key, String target, @RequestParam(required = false, defaultValue = "") String currentPage) {
User user = getCurrentUserFromRedis();
if (null == user) {
return JsonResult.buildErrorStateResult("未找到用户", null);
}
Tuple<String, Boolean> nextPageTuple = pageService.nextPage(user, target, currentPage);
Boolean isFinal = nextPageTuple.getValue();
String nextPage = nextPageTuple.getKey();
if ("xyqb".equals(key)) {
MerchantConfig merchantConfig = merchantService.findConfigByMerchantIdAndConfigName(4L, "returnUrl");
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "external", "transition", merchantConfig.getConfigValue()));
}
if (isFinal) {
Merchant merchant = merchantService.findMerchantByName(key);
if (merchant == null) {
return JsonResult.buildSuccessResult("", null);
}
MerchantConfig merchantConfig = merchantService.findConfigByMerchantIdAndConfigName(merchant.getId(), "returnUrl");
if (merchantConfig == null) {
return JsonResult.buildSuccessResult("", null);
}
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "external", "transition", merchantConfig.getConfigValue()));
}
if (StringUtils.isEmpty(nextPage)) {
return JsonResult.buildErrorStateResult("", null);
}
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "user", "transition", nextPage));
}
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "user", "transition", nextPage));
}
}
......@@ -15,39 +15,39 @@ import java.sql.Timestamp;
@Table(name = "address", uniqueConstraints = @UniqueConstraint(columnNames = "user_id"))
public class Address implements Serializable {
private static final long serialVersionUID = -1L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id")
private Long userId;
@Column(name = "province_code")
private Long provinceCode;
@Column(name = "province")
private String province;
@Column(name = "city_code")
private Long cityCode;
@Column(name = "city")
private String city;
@Column(name = "district_code")
private Long districtCode;
@Column(name = "district")
private String district;
@Column(name = "address")
private String address;
@Column(name = "created_at")
private Timestamp createdAt;
@Column(name = "updated_at")
private Timestamp updateAt;
@PreUpdate
public void preUpdate(){
this.updateAt = new Timestamp(System.currentTimeMillis());
}
public String toString(){
return province+"(省)"+city+"(市)"+district+"(区/县)"+address;
}
private static final long serialVersionUID = -1L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id")
private Long userId;
@Column(name = "province_code")
private Long provinceCode;
@Column(name = "province")
private String province;
@Column(name = "city_code")
private Long cityCode;
@Column(name = "city")
private String city;
@Column(name = "district_code")
private Long districtCode;
@Column(name = "district")
private String district;
@Column(name = "address")
private String address;
@Column(name = "created_at")
private Timestamp createdAt;
@Column(name = "updated_at")
private Timestamp updateAt;
@PreUpdate
public void preUpdate() {
this.updateAt = new Timestamp(System.currentTimeMillis());
}
public String toString() {
return province + "(省)" + city + "(市)" + district + "(区/县)" + address;
}
}
......@@ -17,16 +17,16 @@ import java.sql.Timestamp;
@Table(name = "merchant")
public class Merchant implements Serializable {
private static final long serialVersionUID = -1L;
@Id
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "enable")
private boolean enable;
@Column(name = "created_at")
private Timestamp createAt;
@Column(name = "updated_at")
private Timestamp updateAt;
private static final long serialVersionUID = -1L;
@Id
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "enable")
private boolean enable;
@Column(name = "created_at")
private Timestamp createAt;
@Column(name = "updated_at")
private Timestamp updateAt;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment