This commit is contained in:
2019-08-15 01:25:05 +08:00
parent 3c56288991
commit 7242f6d76c
74 changed files with 4375 additions and 126 deletions
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- maven可以继承父项目中的参数,所以可以删除子模块中相同定义 -->
<artifactId>zilean-common</artifactId>
<packaging>jar</packaging>
<name>zilean-common</name>
<description>独立常量模块</description>
<parent>
<groupId>cn.odboy</groupId>
<artifactId>zilean</artifactId>
<version>1.0.0</version>
<!-- lookup parent from repository -->
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<!-- maven可以继承父项目中的依赖,所以可以删除子模块中相同定义 -->
<!--lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<!-- HuTool工具箱-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies>
<!-- 如果其他包需要依赖这个模块那么就不要加这个 -->
<!--<build>-->
<!--<plugins>-->
<!--<plugin>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-maven-plugin</artifactId>-->
<!--</plugin>-->
<!--</plugins>-->
<!--</build>-->
</project>
@@ -0,0 +1,35 @@
package cn.odboy.zilean.common;
import cn.odboy.zilean.common.constant.GlobalConsts;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* @author: Odboy
* @version: Jdk 1.8
* @desc: TODO Ajax请求返回对象
* @time: 2019/8/7 8:43
* @blog: www.odboy.cn
*/
@Getter
@Setter
@ToString
public class HttpResult implements Serializable {
/**
* 业务处理成功与否
*/
private boolean success;
/**
* 提示信息
*/
private String message;
/**
* 数据体
*/
private Map<String, Object> body = new HashMap<>(GlobalConsts.DEFAULT_COLLECTIONS_SIZE);
}
@@ -0,0 +1,20 @@
package cn.odboy.zilean.common.constant;
/**
* @author 田俊
* @version 1.0.0
* @name: RegexConsts <br/>
* @description: TODO 常量:数据状态 <br/>
* @date: 2019/04/2019/4/1 <br/>
* @since JDK 1.8
*/
public final class DataStatusConsts {
/**
* 无效数据
*/
public static final byte DELETE = 1;
/**
* 有效数据
*/
public static final byte UNDELETE = 0;
}
@@ -0,0 +1,31 @@
package cn.odboy.zilean.common.constant;
/**
* @author 田俊
* @version 1.0.0
* @name: RegexConsts <br/>
* @description: TODO 常量:全局参数 <br/>
* @date: 2019/04/2019/4/1 <br/>
* @since JDK 1.8
*/
public final class GlobalConsts {
/**
* 默认集合对象大小
*/
public static final int DEFAULT_COLLECTIONS_SIZE = 3;
/**
* OPTION请求
*/
public static final String HTTP_OPTIONS = "OPTIONS";
/**
* page
*/
public static final String ATTR_PAGE = "page";
/**
* 默认的盐
*/
public static final String SALT = "Zilean201908010000";
public static final String MSG_USERNAME_OR_PASSWORD_ERROR = "用户名或者密码错误";
public static final String MSG_TOKEN_EXPIRE_RELOGIN = "Token过期,请重新登录";
}
@@ -0,0 +1,19 @@
package cn.odboy.zilean.common.constant;
/**
* @author: Odboy
* @version: Jdk 1.8
* @desc: TODO RedisKey前缀
* @time: 2019/7/21 3:31
* @blog: www.odboy.cn
*/
public final class RedisKeyConsts {
/**
* token令牌
*/
public static final String TOKEN = "zilean:token:{}";
/**
* 用户信息
*/
public static final String USER = "zilean:user:{}";
}
@@ -0,0 +1,158 @@
package cn.odboy.zilean.common.constant;
/**
* @author 田俊
* @version 1.0.0
* @name: RegexConsts <br/>
* @description: TODO 常量:正则表达式 <br/>
* @date: 2019/04/2019/4/1 <br/>
* @since JDK 1.8
*/
public final class RegexConsts {
/**
* 英文单词
*/
public static final String REGEX_WORD_EN = "^\\w+$";
/**
* 中文
*/
public static final String REGEX_WORD_CN = "[\u4E00-\u9FA5]+";
/**
* 6到30位 数字 + 字符 + _,常用于用户名注册
*/
public static final String REGEX_WORD_EN_6_30 = "^[a-zA-Z][a-zA-Z0-9_]{6,29}$";
/**
* 5到20位 数字 + 字符 + _,常用于用户名注册
*/
public static final String REGEX_WORD_EN_5_20 = "^[a-zA-Z][a-zA-Z0-9_]{5,19}$";
/**
* 数字 + 字符 + _,且必须已字母开头
*/
public static final String REGEX_CHAR_NUM_UL = "^[a-zA-Z][a-zA-Z0-9_]+$";
/**
* 数字 + 字母 组合
*/
public static final String REGEX_CHAR_NUM = "^[A-Za-z0-9]+$";
/**
* 字母组合
*/
public static final String REGEX_CHAR = "^[A-Za-z]+$";
/**
* 大写字母组合
*/
public static final String REGEX_CHAR_UC = "^[A-Z]+$";
/**
* 小写字母组合
*/
public static final String REGEX_CHAR_LC = "^[a-z]+$";
/**
* 双字节
*/
public static final String REGEX_DBCHAR = "[^x00-xff]+";
/**
* URL地址: 包括 http, ftp 等
*/
public static final String REGEX_URL = "[a-zA-z]+://[^s]*";
/**
* HTTP URL
*/
public static final String REGEX_URL_HTTP = "http(s)?://[^s]+";
/**
* Internet URL
*/
public static final String REGEX_URL_INTERNET = "^http(s)?://([\\w-]+.)+[\\w-]+(/[\\w-./?%&=]*)?$";
/**
* HTML 标签
*/
public static final String REGEX_HTML_TAG = "<(\\S*?)[^>]*>.*?|<.*? />";
/**
* IP 地址
*/
public static final String REGEX_IP = "((25[0-5])|(2[0-4]\\d)|(1\\d{2})|([1-9]\\d)|(\\d)).((25[0-5])|(2[0-4]\\d)|(1\\d{2})|([1-9]\\d)|(\\d)).((25[0-5])|(2[0-4]\\d)|(1\\d{2})|([1-9]\\d)|(\\d)).((25[0-5])|(2[0-4]\\d)|(1\\d{2})|([1-9]\\d)|(\\d))";
/**
* Email 地址
*/
public static final String REGEX_EMAIL = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*.\\w+([-.]\\w+)*";
/**
* 中国电话号码
*/
public static final String REGEX_PHONE_CHINA = "0\\d{2,3}-\\d{7,8}";
/**
* 中国移动电话
*/
public static final String REGEX_MOBILE_CHINA = "1[3|5|8][0-9]-\\d{8}";
/**
* 中国身份证号
*/
public static final String REGEX_IDCARD_CHINA = "\\d{17}[0-9|x|X]|\\d{15}";
/**
* 中国邮政编码
*/
public static final String REGEX_ZIPCODE_CHINA = "\\d{6}";
/**
* QQ号
*/
public static final String REGEX_QQ = "[1-9][0-9]{4,}";
/**
* 数字
*/
public static final String REGEX_CNUMBER = "^[0-9]+$";
/**
* 正数
*/
public static final String REGEX_INT_POSITIVE = "^[1-9]\\d*$";
/**
* 非正数
*/
public static final String REGEX_INT_NOT_POSITIVE = "^-[1-9]\\d*|0$";
/**
* 负数
*/
public static final String REGEX_INT_NEGATIVE = "^-[1-9]\\d*$";
/**
* 非负数
*/
public static final String REGEX_INT_NOT_NEGATIVE = "^[1-9]\\d*|0$";
/**
* 整数
*/
public static final String REGEX_CINT = "^-?[1-9]\\d*$";
/**
* 浮点数
*/
public static final String REGEX_CFLOAT = "^-?([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*|0?.0+|0)$";
/**
* 正浮点数
*/
public static final String REGEX_FLOAT_POSITIVE = "^[1-9]\\d*.\\d*|0.\\d*[1-9]\\d*$";
/**
* 非正浮点数
*/
public static final String REGEX_FLOAT_NOT_POSITIVE = "^(-([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*))|0?.0+|0$";
/**
* 负浮点数
*/
public static final String REGEX_FLOAT_NEGATIVE = "^-([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*)$";
/**
* 非负浮点数
*/
public static final String REGEX_FLOAT_NOT_NEGATIVE = "^[1-9]\\d*.\\d*|0.\\d*[1-9]\\d*|0?.0+|0$";
/**
* 空行
*/
public static final String REGEX_SPACE_LINE = "\n\\s*\r";
/**
* 空字符
*/
public static final String REGEX_SPACE_CHAR = "^\\s*|\\s*$";
/**
* 关键字标签正则:仅允许输入中文、英文(含大小写)、数字,输入内容必须以逗号隔开(含中英文逗号),但不能以逗号开头或结尾
* 正确格式示例:99,AB,示例,ss,呵呵
*/
public static final String REGEX_KEY_WORD_TAG = "^([a-zA-Z0-9\\u4e00-\\u9fa5]+[,|,])*[a-zA-Z0-9\\u4e00-\\u9fa5]+$";
/**
* 能输入有1~3位小数的正实数(包含0)
*/
public static final String REGEX_INT_ARITHMETIC_NUMBER = "^[0-9]+(\\.[0-9]{1,3})?$";
}
@@ -0,0 +1,20 @@
package cn.odboy.zilean.common.constant;
/**
* @author 田俊
* @version 1.0.0
* @name: SymbolConsts <br/>
* @description: TODO 常量:标点符号 <br/>
* @date: 2019/03/2019/3/30 <br/>
* @since JDK 1.8
*/
public final class SymbolConsts {
/**
* 空格
*/
public static final String SPACE = " ";
/**
* 逗号
*/
public static final String DOT = ",";
}
@@ -0,0 +1,45 @@
package cn.odboy.zilean.common.exception;
/**
* @author: Odboy
* @version: Jdk 1.8
* @desc: TODO 业务异常
* @time: 2019/8/8 10:40
* @blog: www.odboy.cn
*/
public class BusinessException extends RuntimeException {
/**
* 无参构造
*/
public BusinessException() {
super();
}
/**
* 含参构造
*
* @param message 异常信息
*/
public BusinessException(String message) {
super(message);
}
/**
* 含参构造
*
* @param message 异常信息
* @param cause 抛出异常
*/
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
/**
* 含参构造
*
* @param cause 抛出异常
*/
public BusinessException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,47 @@
package cn.odboy.zilean.common.util;
import cn.odboy.zilean.common.exception.BusinessException;
/**
* @author: Odboy
* @time: 2019/5/24 22:44
* @desc: TODO 断言工具类
*/
public final class AssertUtils {
/**
* 表达式结果真时判断
*
* @param expression Boolean
* @param msg 提示信息
*/
public static void isTrue(Boolean expression, String msg) {
if (expression) {
throw new BusinessException(msg);
}
}
/**
* 参数为空时
*
* @param object 断言对象
* @param msg 提示信息
*/
public static void isNull(Object object, String msg) {
if (object == null) {
throw new BusinessException(msg);
}
}
/**
* 参数不空时
*
* @param object 断言对象
* @param msg 提示信息
*/
public static void notNull(Object object, String msg) {
if (object != null) {
throw new BusinessException(msg);
}
}
}
@@ -0,0 +1,28 @@
package cn.odboy.zilean.common.util;
import cn.hutool.core.collection.CollUtil;
import java.util.List;
/**
* @author: Odboy
* @version: Jdk 1.8
* @desc: TODO 集合工具类
* @time: 2019/8/9 7:06
* @blog: www.odboy.cn
*/
public final class CollectionsUtils {
/**
* 获取集合中第一个对象
*
* @param list 对象集合
* @param <T> 参考对象
* @return 对象
*/
public static <T> T getOne(List<T> list) {
if (CollUtil.isNotEmpty(list)) {
return list.get(0);
}
return null;
}
}
@@ -0,0 +1,122 @@
package cn.odboy.zilean.common.util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 田俊
* @version 1.0.0
* @name: CookieUtils <br/>
* @description: TODO Cookie工具类 <br/>
* @date: 2019/03/2019/3/30 <br/>
* @since JDK 1.8
*/
public final class CookieUtils {
/**
* 读取cookie数组,之后迭代出各个cookie
*
* @param request HttpServletRequest
* @return Cookie[]
*/
public static Cookie[] getCookies(HttpServletRequest request) {
// 根据请求数据,找到cookie数组
return request.getCookies();
}
/**
* 读取cookie
*
* @param request HttpServletRequest
* @param cookieName cookie名称
* @return cookie值
*/
public static String getCookie(HttpServletRequest request, String cookieName) {
//根据请求数据,找到cookie数组
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (cookie != null && cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
}
return null;
}
/**
* 创建cookie,并将新cookie添加到“响应对象”response中。
*
* @param response HttpServletResponse
* @param cookieName cookie名称
* @param cookieValue cookie值
*/
public static void addCookie(HttpServletResponse response, String cookieName, String cookieValue) {
// 创建新cookie
Cookie cookie = new Cookie(cookieName, cookieValue);
// 设置存在时间为无限
cookie.setMaxAge(-1);
// 设置作用域
cookie.setPath("/");
// 将cookie添加到response的cookie数组中返回给客户端
response.addCookie(cookie);
}
/**
* 修改cookie,可以根据某个cookie的name修改它(不只是name要与被修改cookie一致,path、domain必须也要与被修改cookie一致)
*
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param cookieName cookie名称
* @param cookieValue cookie值
* @return 是否修改成功
*/
public static boolean editCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue) {
Cookie[] cookies = request.getCookies();
if (null == cookies) {
return false;
} else {
for (Cookie cookie : cookies) {
// 迭代时如果发现与指定cookieName相同的cookie,就修改相关数据
if (cookie.getName().equals(cookieName)) {
// 修改value
cookie.setValue(cookieValue);
cookie.setPath("/");
// 修改存活时间
cookie.setMaxAge(-1);
// 将修改过的cookie存入response,替换掉旧的同名cookie
response.addCookie(cookie);
break;
}
}
return true;
}
}
/**
* 删除cookie
*
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param cookieName cookie名称
* @return 是否删除成功
*/
public static boolean delCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
Cookie[] cookies = request.getCookies();
if (null == cookies) {
return false;
} else {
for (Cookie cookie : cookies) {
// 如果找到同名cookie,就将value设置为null,将存活时间设置为0,再替换掉原cookie,这样就相当于删除了。
if (cookie.getName().equals(cookieName)) {
cookie.setValue(null);
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
break;
}
}
return true;
}
}
}
@@ -0,0 +1,24 @@
package cn.odboy.zilean.common.util;
import javax.servlet.http.HttpServletRequest;
/**
* @author 田俊
* @version 1.0.0
* @name: HttpRequestUtils <br/>
* @description: TODO 请求处理 <br/>
* @date: 2019/04/2019/4/12 <br/>
* @since JDK 1.8
*/
public final class HttpRequestUtils {
/**
* 获取webapp请求路径
*
* @param request
* @return
*/
public static String getRequestUrl(HttpServletRequest request) {
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
}
}
@@ -0,0 +1,44 @@
package cn.odboy.zilean.common.util;
import javax.servlet.http.HttpServletRequest;
/**
* @author: Odboy
* @time: 2019/5/25 6:28
* @desc: TODO HttpServlet工具类
*/
public final class HttpServletUtils {
/**
* 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
* <p>
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
* <p>
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
* <p>
* 用户真实IP为: 192.168.1.110
*
* @param request HttpServletRequest
* @return 用户真实IP地址
*/
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
@@ -0,0 +1,44 @@
package cn.odboy.zilean.common.util;
import cn.hutool.core.util.ReflectUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.StringUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author 田俊
* @version 1.0.0
* @name: ListUtils <br/>
* @description: TODO 数组工具(基于jdk1.8) <br/>
* @date: 2019/04/2019/4/2 <br/>
* @since JDK 1.8
*/
@Log4j2
public final class ListUtils {
public static <K, V> Map<K, V> listToMap(List<V> list, Class clazz, String getKeyMethodName, String getValueMethodName) {
Map<K, V> result = new HashMap<>(6);
boolean isOk = list != null && list.size() > 0 && !StringUtils.isEmpty(getKeyMethodName)
&& !StringUtils.isEmpty(getValueMethodName);
if (isOk) {
for (Object obj : list) {
try {
Method getKeyMethod = ReflectUtil.getMethod(clazz, getKeyMethodName);
Object targetKey = getKeyMethod.invoke(obj);
Method getValueMethod = ReflectUtil.getMethod(clazz, getValueMethodName);
Object targetValue = getValueMethod.invoke(obj);
result.put((K) targetKey, ((V) targetValue));
} catch (IllegalAccessException e) {
log.error(e.getMessage());
} catch (InvocationTargetException e) {
log.error(e.getMessage());
}
}
}
return result;
}
}
@@ -0,0 +1,48 @@
package cn.odboy.zilean.common.util;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
/**
* @author: Odboy
* @version: Jdk 1.8
* @desc: TODO 密码工具类
* @time: 2019/7/21 18:23
* @blog: www.odboy.cn
*/
public final class PasswordUtils {
/**
* 生成加密密码(理论上可逆,但是当你忘记密码的时候,那就不可逆)
*
* @param username 用户名
* @param password 密码
* @return
*/
public static String encode(String username, String password) {
String content = HexUtil.encodeHexStr(username + ":" + password, CharsetUtil.CHARSET_UTF_8);
// 生成密钥
byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
// 构建
AES aes;
if (content.length() == 16) {
aes = new AES(Mode.CTS, Padding.PKCS5Padding, content.getBytes(), "20190506_Odboy".getBytes());
} else {
aes = new AES(Mode.CTS, Padding.PKCS5Padding, content.substring(0, 16).getBytes(), "20190506_OdboyHH".getBytes());
}
// 加密
byte[] encrypt = aes.encrypt(content);
// 解密
byte[] decrypt = aes.decrypt(encrypt);
return aes.encryptHex(content);
}
//
// public static void main(String[] args) {
// System.out.println(encode("tianjun", "123456"));
// System.out.println(encode("odboy", "123456"));
// }
}
@@ -0,0 +1,61 @@
package cn.odboy.zilean.common.util;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
/**
* @author: Odboy
* @time: 2019/7/4 21:39
* @desc: TODO 签名工具
*/
public final class SignUtils {
private static final Sign SIGN = SecureUtil.sign(SignAlgorithm.MD5withRSA);
/**
* 获取签名Code
*
* @param username 账号
* @param token token令牌
* @return String
*/
public static String signCode(String username, String token) {
byte[] data = (username + token).getBytes();
// 签名
byte[] signed = SIGN.sign(data);
// Base64编码
return Base64.encode(signed);
}
/**
* 验证签名
*
* @param username 账号
* @param token token令牌
* @param signCode 签名Code
* @return
*/
public static boolean verify(String username, String token, String signCode) {
byte[] data = (username + token).getBytes();
// 签名
byte[] signed = Base64.decode(signCode);
// 验证签名
return SIGN.verify(data, signed);
}
// public static void main(String[] args) {
// String sign = signCode("1943815081", "ebbddcc5317168b747afd89234ea275e");
// System.out.println(sign);
// boolean result = verify("1943815081", "ebbddcc5317168b747afd89234ea275e", sign);
// System.out.println(result);
//
// boolean a =
// verify(
// "1943815081",
// "ebbddcc5317168b747afd89234ea275e",
//
// "fVD69HcPaqxRGRYkdCFKPN4DYw8t1yVa/J2ALumUIpG+ag1y9fCZ038gIfpBw5pQoyJ9DLff0UgphsuO+AhU0PtxEykCLvXo8zwMHn6FGvFzwe1D3SBI9tD9MSDe4E2pH3qr+VpyLyLcsEUAZHos4g9uaaBw8hxAyk/8riVLFUE=");
// System.out.println(a);
// }
}