This commit is contained in:
2024-11-28 15:10:09 +08:00
commit 901691aaea
90 changed files with 4919 additions and 0 deletions

View File

@ -0,0 +1,108 @@
package com.ycwl.basic.utils;
/**
* Api常量定义类
*
* @version 1.0.0
*/
public class ApiConst {
/**
* 返回CODE码定义, 按照httpstatus的code码定义, 系统自定义的为四位数
*
* @version 1.0.0
*/
public static enum Code {
/**
* 成功返回码
*/
CODE_SUCCESS_ZERO(0),
/**
* 成功返回码
*/
CODE_SUCCESS(200),
/**
* 返回内容为空
*/
CODE_CONTENT_EMPTY(204),
/**
* 访问被拒绝
*/
CODE_REJECT(403),
/**
* 无权限访问
*/
CODE_NO_AUTH(401),
/**
* 请求方法错误
*/
CODE_NOT_EXIST(404),
/**
* 请求版本错误
*/
CODE_VERSION_ERROR(406),
/**
* 获取锁错误
*/
CODE_GET_LOCK_ERROR(423),
/**
* 请求参数错误
*/
CODE_PARAM_ERROR(4001),
/**
* 服务器错误
*/
CODE_SERVER_ERROR(500),
/**
* 其他业务码定义
*/
CODE_COMMON_ERROR(5001),
/**
* 自动完成登录状态
*/
CODE_LOGIN_RETRY(5002),
/**
* 用户过期或处在无登录状态
*/
CODE_NO_SESSION(5003),
/**
* 请求第三方错误
*/
CODE_THIRDPARTY_ERROR(5004),
/**
* 检查异常
*/
CODE_CHECK_ERROR(5005),
/**
* 缺少TOKEN异常
*/
CODE_MISS_TOKEN_ERROR(5006);
private Code(int intCode) {
this.intCode = intCode;
}
private int intCode;
public int code() {
return intCode;
}
}
}

View File

@ -0,0 +1,193 @@
package com.ycwl.basic.utils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ycwl.basic.enums.BizCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
/**
* 所有接口返回数据的携带对象
*
* @param <T>
* @version 1.0.0
*/
@ApiModel(value = "通用返回数据对象")
public class ApiResponse<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 返回CODE码,详见{@link ApiConst.Code}中常量定义
*/
@ApiModelProperty(value = "状态码")
private int code;
/**
* 返回message
*/
@ApiModelProperty(value = "数据描述")
private String msg;
/**
* 成功返回数据
*/
@ApiModelProperty(value = "数据")
private T data;
public ApiResponse() {
}
/**
* 构建成功返回数据对象
*
* @param data 返回数据内容
* @return
*/
public static <T> ApiResponse<T> buildSuccessResponse(T data) {
ApiResponse<T> response = new ApiResponse<T>();
response.setCode(ApiConst.Code.CODE_SUCCESS.code());
response.setData(data);
return response;
}
/**
* 构建空返回对象
*
* @return
*/
public static <T> ApiResponse<T> buildEmptyResponse() {
ApiResponse<T> response = new ApiResponse<T>();
response.setCode(ApiConst.Code.CODE_CONTENT_EMPTY.code());
return response;
}
/**
* 构建常规错误返回对象
*
* @param msg
* @return
*/
public static <T> ApiResponse<T> buildCommonErrorResponse(String msg) {
return buildResponse(ApiConst.Code.CODE_COMMON_ERROR, msg);
}
/**
* 构建自定义CODE码对象
*
* @param code
* @param data
* @param msg
* @return
*/
public static <T> ApiResponse<T> buildResponse(int code, T data, String msg) {
ApiResponse<T> response = new ApiResponse<T>();
response.setCode(code);
response.setData(data);
response.setMsg(msg);
return response;
}
/**
* 根据返回值构建结果
*
* @param flag
* @param <T>
* @return
*/
public static <T> ApiResponse<T> buildFlagResponse(boolean flag, T data) {
ApiResponse<T> response = new ApiResponse<T>();
if (flag) {
response.setCode(ApiConst.Code.CODE_SUCCESS.code());
response.setData(data);
response.setMsg("成功");
return response;
}
response.setCode(ApiConst.Code.CODE_COMMON_ERROR.code());
response.setData(data);
response.setMsg("失败");
return response;
}
/**
* 构建CODE码和提示信息对象
*
* @param code
* @param msg
* @return
*/
public static <T> ApiResponse<T> buildResponse(ApiConst.Code code, String msg) {
ApiResponse<T> response = new ApiResponse<T>();
response.setCode(code.code());
response.setMsg(msg);
return response;
}
/**
* 构建用户自定义CODE码和提示信息对象
*
* @param code
* @param msg
* @return
*/
public static <T> ApiResponse<T> buildResponse(int code, String msg) {
ApiResponse<T> response = new ApiResponse<T>();
response.setCode(code);
response.setMsg(msg);
return response;
}
public static <T> ApiResponse<T> buildResult(BizCodeEnum bizCodeEnum) {
ApiResponse<T> apiResponse = new ApiResponse();
apiResponse.setCode(bizCodeEnum.code);
apiResponse.setMsg(bizCodeEnum.message);
return apiResponse;
}
/**
* 是否执行成功
*
* @return
*/
@JsonIgnore
public boolean isSuccess() {
return ApiConst.Code.CODE_SUCCESS.code() == this.code;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("[code=").append(code).append(", msg=").append(msg).append(", data=").append(data)
.append("]");
return builder.toString();
}
}

View File

@ -0,0 +1,44 @@
package com.ycwl.basic.utils;
import org.springframework.cglib.beans.BeanCopier;
import java.util.HashMap;
import java.util.Map;
/**
* @date 2022年03月09日 9:04
* @author wenshijia
* BeanCopier工具类
*/
public class BeanCopierUtils {
public static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<>();
/**
*
* 将soruce对象的属性转换给target对象
* @date 2022/3/9 9:11
* @param source 需要转换的对象
* @param target 目标对象
*/
public static void copyProperties(Object source, Object target) {
BeanCopier beanCopier;
String cacheKey = source.getClass().toString() + target.getClass().toString();
if (!beanCopierCacheMap.containsKey(cacheKey)) {
synchronized (BeanCopierUtils.class) {
if (!beanCopierCacheMap.containsKey(cacheKey)) {
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierCacheMap.put(cacheKey, beanCopier);
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
}
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
beanCopier.copy(source, target, null);
}
}

View File

@ -0,0 +1,137 @@
//package com.ycwl.smartPark.utils;
//
//import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
//import com.baomidou.mybatisplus.core.toolkit.StringPool;
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
//import com.baomidou.mybatisplus.generator.AutoGenerator;
//import com.baomidou.mybatisplus.generator.InjectionConfig;
//import com.baomidou.mybatisplus.generator.config.*;
//import com.baomidou.mybatisplus.generator.config.po.TableInfo;
//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
//import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Scanner;
//
///**
// * 执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
// *
// * @author songmingsong
// * @since 1.0.0
// */
//
//public class CodeGenerator {
//
// /**
// * <p>
// * 读取控制台内容
// * </p>
// */
// public static String scanner(String tip) {
// Scanner scanner = new Scanner(System.in);
// StringBuilder help = new StringBuilder();
// help.append("请输入" + tip + ":");
// System.out.println(help.toString());
// if (scanner.hasNext()) {
// String ipt = scanner.next();
// if (StringUtils.isNotEmpty(ipt)) {
// return ipt;
// }
// }
// throw new MybatisPlusException("请输入正确的" + tip + "!");
// }
//
// public static void main(String[] args) {
// // 代码生成器
// AutoGenerator mpg = new AutoGenerator();
//
// // 全局配置
// GlobalConfig gc = new GlobalConfig();
// String projectPath = System.getProperty("user.dir");
// // 生成到那个模块下
// gc.setOutputDir(projectPath + "/src/main/java");
// //作者
// gc.setAuthor("songmingsong");
// //打开输出目录
// gc.setOpen(false);
// //xml开启 BaseResultMap
// gc.setBaseResultMap(true);
// //xml 开启BaseColumnList
// gc.setBaseColumnList(true);
// // 实体属性 Swagger2 注解
// gc.setSwagger2(true);
// mpg.setGlobalConfig(gc);
//
// // 数据源配置
// DataSourceConfig dsc = new DataSourceConfig();
// dsc.setUrl("jdbc:mysql://49.4.2.89:3306/smart_park?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia" +
// "/Shanghai");
// dsc.setDriverName("com.mysql.cj.jdbc.Driver");
// dsc.setUsername("root");
// dsc.setPassword("yckj@2017");
// mpg.setDataSource(dsc);
//
// // 包配置
// PackageConfig pc = new PackageConfig();
// pc.setParent("com.ycwl.smartPark")
// .setEntity("model.app.notice.entity")
// .setMapper("mapper.app")
// .setService("service.app")
// .setServiceImpl("service.impl.app")
// .setController("controller.app");
// mpg.setPackageInfo(pc);
//
// // 自定义配置
// InjectionConfig cfg = new InjectionConfig() {
// @Override
// public void initMap() {
// // to do nothing
// }
// };
//
// // 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// // 如果模板引擎是 velocity
// // String templatePath = "/templates/mapper.xml.vm";
//
// // 自定义输出配置
// List<FileOutConfig> focList = new ArrayList<>();
// // 自定义配置会被优先输出
// focList.add(new FileOutConfig(templatePath) {
// @Override
// public String outputFile(TableInfo tableInfo) {
// // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
// return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper"
// + StringPool.DOT_XML;
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 配置模板
// TemplateConfig templateConfig = new TemplateConfig();
//
// templateConfig.setXml(null);
// mpg.setTemplate(templateConfig);
//
// // 策略配置
// StrategyConfig strategy = new StrategyConfig();
// //数据库表映射到实体的命名策略
// strategy.setNaming(NamingStrategy.underline_to_camel);
// //数据库表字段映射到实体的命名策略
// strategy.setColumnNaming(NamingStrategy.no_change);
// //lombok模型
// strategy.setEntityLombokModel(true);
// //生成 @RestController 控制器
// strategy.setRestControllerStyle(true);
// strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
// strategy.setControllerMappingHyphenStyle(true);
// //表前缀
// strategy.setTablePrefix("t_");
// mpg.setStrategy(strategy);
// mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// mpg.execute();
// }
//
//}

View File

@ -0,0 +1,186 @@
package com.ycwl.basic.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author wenshijia
* @date 2021年05月26日 23:02
*/
@Slf4j
public class CommonUtil {
/**
* 生成指定长度随机字母和数字
*/
private static final String ALL_CHAR_NUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static SecureRandom random;
static {
try {
random = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 获取ip
*
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = null;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if ("127.0.0.1".equals(ipAddress)) {
// 根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) {
// "***.***.***.***".length()
// = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
}
/**
* md5加密
*
* @param data 需要加密的字符串
* @return java.lang.String
* @author wenshijia
* @date 2021/5/26 23:02
*/
public static String MD5(String data) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
} catch (Exception exception) {
}
return null;
}
/**
* 生成随机数
*
* @param length 生成的随机数的长度
* @return java.lang.String
* @author wenshijia
* @date 2021/5/27 16:38
*/
public static String getRandomCode(int length) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < length; i++) {
stringBuilder.append(random.nextInt(10));
}
return stringBuilder.toString();
}
/**
* 获取当前时间的时间戳
*
* @return long
* @author wenshijia
* @date 2021/5/27 22:02
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis();
}
/**
* UUID生成
*
* @return java.lang.String
* @author wenshijia
* @date 2021/5/30 21:16
*/
public static String generateUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 生成指定长度随机字母和数字
*
* @param length 需要生成的字符串长度
* @return java.lang.String
* @author wenshijia
* @date 2021/5/31 16:43
*/
public static String getStringNumRandom(int length) {
ThreadLocalRandom random = ThreadLocalRandom.current();
//生成随机数字和字母,
StringBuilder saltString = new StringBuilder(length);
for (int i = 1; i <= length; ++i) {
saltString.append(ALL_CHAR_NUM.charAt(random.nextInt(ALL_CHAR_NUM.length())));
}
return saltString.toString();
}
/**
* @param response 返回response
* @param obj 返回的数据
* @author wenshijia
* @date 2021/6/2 21:11
*/
public static void sendJsonMessage(HttpServletResponse response, Object obj) {
ObjectMapper objectMapper = new ObjectMapper();
response.setContentType("application/json; charset=utf-8");
try (PrintWriter writer = response.getWriter()) {
writer.print(objectMapper.writeValueAsString(obj));
response.flushBuffer();
} catch (IOException e) {
log.warn("响应json数据给前端异常 -> {}", e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,202 @@
package com.ycwl.basic.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* @date 2022年06月02日 13:40
* 自定义的BigDecimal计算工具类
*/
public class CustomBigDecimalUtils {
public static final BigDecimal HUNDRED_BIG_DECIMAL = new BigDecimal("100");
/**
* 除法
*
* @param divisor 除数
* @param dividend 被除数
* @param scale 保留的小数位数
* @param roundingMode 舍入模式:比如四舍五入
* @return java.math.BigDecimal
* @date 2022/6/2 13:43
*/
public static BigDecimal divide(BigDecimal divisor,
BigDecimal dividend,
int scale,
RoundingMode roundingMode) {
if (divisor == null || dividend == null) {
throw new NullPointerException("传入的数据不能为空");
}
if (Double.compare(divisor.doubleValue(), BigDecimal.ZERO.doubleValue()) == 0 ||
Double.compare(dividend.doubleValue(), BigDecimal.ZERO.doubleValue()) == 0) {
return BigDecimal.ZERO;
}
return divisor.divide(dividend, scale, roundingMode);
}
/**
* 除法
*
* @param divisor 除数
* @param dividend 被除数
* @param scale 保留的小数位数
* @param roundingMode 舍入模式:比如四舍五入
* @return java.math.BigDecimal
* @date 2022/6/2 13:43
*/
public static BigDecimal divide(Integer divisor,
Integer dividend,
int scale,
RoundingMode roundingMode) {
if (divisor == null || dividend == null) {
throw new NullPointerException("传入的数据不能为空");
}
if (divisor == 0 || dividend == 0) {
return BigDecimal.ZERO;
}
return new BigDecimal(divisor).divide(new BigDecimal(dividend), scale, roundingMode);
}
/**
* 除法
*
* @param divisor 除数
* @param dividend 被除数
* @param scale 保留的小数位数
* @param roundingMode 舍入模式:比如四舍五入
* @return java.math.BigDecimal
* @date 2022/6/2 13:43
*/
public static BigDecimal divide(Double divisor,
Double dividend,
int scale,
RoundingMode roundingMode) {
if (divisor == null || dividend == null) {
throw new NullPointerException("传入的数据不能为空");
}
if (Double.compare(divisor, BigDecimal.ZERO.doubleValue()) == 0 ||
Double.compare(dividend, BigDecimal.ZERO.doubleValue()) == 0) {
return BigDecimal.ZERO;
}
return new BigDecimal(String.valueOf(divisor)).divide(new BigDecimal(String.valueOf(dividend)),
scale, roundingMode);
}
/**
* 除法
*
* @param divisor 除数
* @param dividend 被除数
* @param scale 保留的小数位数
* @param roundingMode 舍入模式:比如四舍五入
* @return java.math.BigDecimal
* @date 2022/6/2 13:43
*/
public static BigDecimal divide(Double divisor,
Integer dividend,
int scale,
RoundingMode roundingMode) {
if (divisor == null || dividend == null) {
throw new NullPointerException("传入的数据不能为空");
}
if (Double.compare(divisor, BigDecimal.ZERO.doubleValue()) == 0 ||
Double.compare(dividend, BigDecimal.ZERO.doubleValue()) == 0) {
return BigDecimal.ZERO;
}
return new BigDecimal(String.valueOf(divisor)).divide(new BigDecimal(String.valueOf(dividend)),
scale, roundingMode);
}
/**
* 减法
*
* @param subtraction 减数
* @param minuend 被减数
* @return java.math.BigDecimal
* @date 2022/6/2 13:53
*/
public static BigDecimal subtract(BigDecimal subtraction,
BigDecimal minuend) {
if (subtraction == null || minuend == null) {
throw new NullPointerException("传入的数据不能为空");
}
return subtraction.subtract(minuend);
}
/**
* 减法
*
* @param subtraction 减数
* @param minuend 被减数
* @return java.math.BigDecimal
* @date 2022/6/2 13:53
*/
public static BigDecimal subtract(Double subtraction,
Double minuend) {
if (subtraction == null || minuend == null) {
throw new NullPointerException("传入的数据不能为空");
}
return new BigDecimal(String.valueOf(subtraction)).subtract(new BigDecimal(String.valueOf(minuend)));
}
/**
* 减法
*
* @param subtraction 减数
* @param minuend 被减数
* @return java.math.BigDecimal
* @date 2022/6/2 13:53
*/
public static BigDecimal subtract(BigDecimal subtraction,
Double minuend) {
if (subtraction == null || minuend == null) {
throw new NullPointerException("传入的数据不能为空");
}
return subtraction.subtract(new BigDecimal(minuend));
}
/**
* 加法
* @date 2022/6/7 17:31
* @param addend 加数
* @param summand 被加数
* @return java.lang.Double
*/
public static Double add(Double addend,
Double summand) {
if (addend == null || summand == null) {
throw new NullPointerException("传入的数据不能为空");
}
return new BigDecimal(addend.toString()).add(new BigDecimal(summand.toString())).doubleValue();
}
/**
* 加法
* @date 2022/6/7 17:31
* @param addend 加数
* @param summand 被加数
* @return java.lang.Double
*/
public static Double add(BigDecimal addend,
BigDecimal summand) {
if (addend == null || summand == null) {
throw new NullPointerException("传入的数据不能为空");
}
return addend.add(summand).doubleValue();
}
}

View File

@ -0,0 +1,82 @@
package com.ycwl.basic.utils;
import com.ycwl.basic.model.jwt.JwtInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Iterator;
import java.util.Map;
/**
* @author yangchen
*/
public class JwtAnalysisUtil {
/**
* 生成 Token
*
* @param jwtInfo
* @param priKey
* @param expireTime
* @return
* @throws Exception
*/
public static String generateToken(JwtInfo jwtInfo, byte[] priKey, LocalDateTime expireTime) throws Exception {
JwtBuilder builder = Jwts.builder().setSubject(jwtInfo.getAccount())
.claim("userId", jwtInfo.getUserId())
.claim("roleId", jwtInfo.getRoleId())
.claim("phone", jwtInfo.getPhone())
.claim("name", jwtInfo.getName())
// 返回从1970 00:00:00 到现在的毫秒差(实际的过期时间)
.claim("expire", expireTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
return builder.signWith(SignatureAlgorithm.RS256, RsaKeyUtil.getPrivateKey(priKey)).compact();
}
/**
* 解析 Token
*
* @param token
* @param pubKey
* @return
* @throws Exception
*/
public static JwtInfo getInfoFromToken(String token, byte[] pubKey) throws Exception {
Claims body = (Claims) RsaKeyUtil.parserToken(token, pubKey).getBody();
Iterator var3 = body.entrySet().iterator();
while (var3.hasNext()) {
Map.Entry entry = (Map.Entry) var3.next();
if (!"sub".equals(entry.getKey())
&& !"userId".equals(entry.getKey())
&& !"phone".equals(entry.getKey())
&& !"roleId".equals(entry.getKey())
&& !"account".equals(entry.getKey())
&& !"name".equals(entry.getKey())
&& !"roleName".equals(entry.getKey())
&& !"expire".equals(entry.getKey()));
}
// convert
LocalDateTime expireTime = null;
try {
// expire time
Object expire = body.get("expire");
if (expire != null) {
expireTime = LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) expire), ZoneId.systemDefault());
}
} catch (Exception e) {
e.printStackTrace();
}
return new JwtInfo(StringUtil.a(body.get("name")),
StringUtil.a(body.get("userId")),
StringUtil.a(body.get("roleId")),
body.getSubject(),
StringUtil.a(body.get("phone")),
expireTime);
}
}

View File

@ -0,0 +1,114 @@
package com.ycwl.basic.utils;
import com.ycwl.basic.exception.CheckTokenException;
import com.ycwl.basic.model.jwt.JwtInfo;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
;
/**
* @author yangchen
*/
@SuppressWarnings("ALL")
@Slf4j
@Component
public class JwtTokenUtil {
@Getter
@Value("${jwt.expire:15}")
private int expire;
private static String PRI_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKOpJ+Ob4VI6sipH47lNQF94YVjNvf/NS8x8gsq/qYG8JOM016prGpHBF6fZOv1yKDnBwJRwC+2oBm3PmybXUZiKIYScoLIFcoV9GbuZZ1ktEWpzUSbN4ZHMj2ylkVHi07HlR4L3PzJlbzC410yg2ZS2WKoanJRHUAmrcN4bvXvBAgMBAAECgYBw7LLdVh1uw5lTmy8CGM+mEEX7JFtJObpnajJE+2JWZh99tmRo7mXy1C0iX71YS4B9+baLtZRFc36cHneLoV5mqhWOf84W/zha+z5dlh1ErSLL6t8YKpJ2GQUMu9Y90VHf5eyhUTu0W7bc+Nvr3GSzaDpMy4fm0XjrazIBuYDvAQJBAOShdiZJnKPBLP98XsVD8L3EB1Tpe3qFviYHhvnhaafMmoY8AR3OqMAIn8jLUiUsIdiOpWL2tNFfCkk0kwLpb2kCQQC3QKXKQjY1j8YGrSQw8YFry5qFcdHP+ybw8lc090wHZjFYlpLSjL6AoTwt+bMyArr2WWCN9G/tU5aVLajZc/aZAkByMtAQGc664L+4MYgo4mG6d9Ltr930eh9bYYEjCVu76+/3QruQBuy1Vtlw81XpqVySjdXAU9hHiEBcBn20A6OZAkAW65IQ8ykel+X3zc4aBQrf9a5VBIBumAYt2tHHgSrUPhbr8qFYjlwBcKk7QuED302NJG6sMqeRMoRCElztHdD5AkAWZCbWQQtFmgWB9fZQxKT94c+zL7HJwgcmtmQq8JHgcoOE1jgi5bVksm8vhDeATOAUEAt0Dt+vwTPaPvFL5JdW";
private static String PUB_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjqSfjm+FSOrIqR+O5TUBfeGFYzb3/zUvMfILKv6mBvCTjNNeqaxqRwRen2Tr9cig5wcCUcAvtqAZtz5sm11GYiiGEnKCyBXKFfRm7mWdZLRFqc1EmzeGRzI9spZFR4tOx5UeC9z8yZW8wuNdMoNmUtliqGpyUR1AJq3DeG717wQIDAQAB";
/**
* 生成 token
*
* @param jwtInfo
* @param otherInfo
* @param expireTime 会增加一个 expire 作为 token 的过期时间
* @return
* @throws Exception
*/
public String generateToken(JwtInfo jwtInfo) throws Exception {
// 过期时间,默认 15 天
LocalDateTime expireTime = LocalDateTime.now().plusDays(expire);
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
return token;
}
/**
* 解析Token
*
* @param token
* @return
* @throws Exception
*/
public JwtInfo parsingToken(String token) throws CheckTokenException {
try {
JwtInfo infoFromToken = JwtAnalysisUtil.getInfoFromToken(token, RsaKeyUtil.toBytes(PUB_KEY));
return infoFromToken;
} catch (Exception e) {
e.printStackTrace();
throw new CheckTokenException("token is invalid");
}
}
/*********************************************** 测试 ***************************************************/
/**
* 测试 token
*
* @param args
*/
// public static void main(String[] args) throws Exception {
//
// JwtInfo jwtInfo = new JwtInfo("阿豹", "1", "role1", "yangchen", 1, LocalDateTime.now(), new HashMap<>());
//
// long a = Instant.now().toEpochMilli();
//
// JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
// String token = jwtTokenUtil.generateToken(jwtInfo);
//
// log.info("==> generate token: " + (Instant.now().toEpochMilli() - a) + " ms");
//
// System.out.println("=======");
// System.out.println();
//
// System.out.println(token);
//
// System.out.println();
// System.out.println("=======");
//
// long b = Instant.now().toEpochMilli();
//
// JwtInfo jwtInfo1 = jwtTokenUtil.parsingToken(token);
//
// log.info("==> paring token end " + (Instant.now().toEpochMilli() - b) + " ms");
//
// System.out.println();
// System.out.println();
// System.out.println();
// System.out.println(jwtInfo);
// System.out.println("=======");
// System.out.println(jwtInfo1.toString());
//
// }
public static void main(String[] args) throws Exception {
JwtInfo jwtInfo = new JwtInfo();
jwtInfo.setUserId("1");
LocalDateTime expireTime = LocalDateTime.now().plusDays(9999999);
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
System.out.println(token);
}
}

View File

@ -0,0 +1,180 @@
package com.ycwl.basic.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @date 2022年07月14日 14:12
* 数据格式转换工具类
*/
public class ObjectConvertUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ObjectConvertUtils.class);
/**
* 浅克隆
*
* @param source 原对象
* @param clazz 目标对象
* @return T
* @date 2022/4/6 13:45
*/
public static <T> T clone(Object source, Class<T> clazz) {
return clone(source, clazz, true);
}
/**
*
* @date 2022/7/18 16:36
* @param source 原对象
* @param clazz 目标对象
* @param whetherAssignNull 是否赋值空值:true是 false否
* @return T
*/
public static <T> T clone(Object source, Class<T> clazz, Boolean whetherAssignNull) {
T target;
if (source == null) {
return null;
}
try {
target = clazz.newInstance();
if (whetherAssignNull) {
BeanUtils.copyProperties(source, target);
} else {
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
}
return target;
} catch (Exception e) {
LOGGER.error("数据转换异常", e);
return null;
}
}
/**
* 对象与对象之间的数据转换
*
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @date 2022/7/14 17:24
*/
public static void clone(Object source, Object target) {
clone(source, target, true);
}
/**
*
* @date 2022/7/18 16:39
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @param whetherAssignNull 是否赋值空值:true是 false否
*/
public static void clone(Object source, Object target, Boolean whetherAssignNull) {
if (source == null) {
return;
}
try {
if (whetherAssignNull) {
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
} else {
BeanUtils.copyProperties(source, target);
}
} catch (Exception e) {
LOGGER.error("数据转换异常", e);
}
}
/**
* 对象与对象之间的数据转换
*
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @date 2022/7/15 9:11
*/
public static void cglibBeanCopierCloneObject(Object source, Object target) {
BeanCopierUtils.copyProperties(source, target);
}
/**
* 对象与对象之间的数据转换
*
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @date 2022/7/15 9:11
*/
public static <T> T cglibBeanCopierCloneObject(Object source, Class<T> target) {
T t;
try {
t = target.newInstance();
BeanCopierUtils.copyProperties(source, t);
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return t;
}
/**
* 将list集合转换为传入的对象的数据集合
*
* @param sourceList 原数据集合
* @param clazz 需要转换的集合数据对象
* @return java.util.List<T>
* @date 2022/4/6 13:49
*/
public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz) {
return cloneList(sourceList, clazz, true);
}
/**
*
* @date 2022/7/18 16:41
* @param sourceList 原数据集合
* @param clazz 需要转换的集合数据对象
* @param whetherAssignNull 是否赋值空值:true是 false否
* @return java.util.List<T>
*/
public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz, Boolean whetherAssignNull) {
try {
List<T> targetList = new ArrayList<>(sourceList.size());
for (Object source : sourceList) {
if (whetherAssignNull) {
targetList.add(clone(source, clazz));
} else {
targetList.add(clone(source, clazz, false));
}
}
return targetList;
} catch (Exception e) {
LOGGER.error("数据转换异常", e);
return null;
}
}
/**
* 获取需要忽略的属性
*/
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<>();
for (PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
// 此处判断可根据需求修改
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
}

View File

@ -0,0 +1,77 @@
package com.ycwl.basic.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @date 2022年08月08日 16:06
* redis缓存操作行为工具类
*/
@Component
public class RedisCacheOperationUtils {
/**
* string类型的redis操作类
*/
private static StringRedisTemplate stringRedisTemplate;
/**
* 通用的redis操作类
*/
private static RedisTemplate redisTemplate;
/**
* 创建string类型的操作对象
*/
public static BoundValueOperations<String, String> createValueOperations(String cacheKey) {
return stringRedisTemplate.boundValueOps(cacheKey);
}
/**
* 创建list类型的操作对象
*/
public static BoundListOperations<String, List<String>> createListOperations(String cacheKey) {
return redisTemplate.boundListOps(cacheKey);
}
/**
* 创建hash类型的操作对象
*/
public static BoundHashOperations createHashOperations(String cacheKey) {
return redisTemplate.boundHashOps(cacheKey);
}
/**
* 创建set类型的操作对象
*/
public static BoundSetOperations createSetOperations(String cacheKey) {
return redisTemplate.boundSetOps(cacheKey);
}
/**
* 创建zset类型的操作对象
*/
public static BoundZSetOperations createZSetOperations(String cacheKey) {
return redisTemplate.boundZSetOps(cacheKey);
}
/**
* 判断缓存key值是否存在
*/
public static Boolean hasKey(String cacheKey) {
return redisTemplate.hasKey(cacheKey);
}
/**
* 删除缓存的redis缓存key
*/
public static Boolean delete(String cacheKey) {
return redisTemplate.delete(cacheKey);
}
@Autowired
public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
RedisCacheOperationUtils.stringRedisTemplate = stringRedisTemplate;
}
@Autowired
public void setRedisTemplate(RedisTemplate redisTemplate) {
RedisCacheOperationUtils.redisTemplate = redisTemplate;
}
}

View File

@ -0,0 +1,79 @@
package com.ycwl.basic.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import java.io.IOException;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* @author yangchen
*/
@SuppressWarnings("ALL")
public class RsaKeyUtil {
public RsaKeyUtil() {
}
public static PublicKey getPublicKey(byte[] publicKey) throws Exception {
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKey);
return KeyFactory.getInstance("RSA").generatePublic(spec);
}
public static PrivateKey getPrivateKey(byte[] privateKey) throws Exception {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKey);
return KeyFactory.getInstance("RSA").generatePrivate(spec);
}
public static Map<String, byte[]> generateKey(String password) throws IOException, NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom secureRandom = new SecureRandom(password.getBytes());
keyPairGenerator.initialize(1024, secureRandom);
KeyPair keyPair;
byte[] publicKeyBytes = (keyPair = keyPairGenerator.genKeyPair()).getPublic().getEncoded();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
HashMap map;
(map = new HashMap()).put("pub", publicKeyBytes);
map.put("pri", privateKeyBytes);
return map;
}
public static String toHexString(byte[] b) {
return Base64.getEncoder().encodeToString(b);
}
public static final byte[] toBytes(String s) throws IOException {
return Base64.getDecoder().decode(s);
}
public static Jws<Claims> parserToken(String token, byte[] pubKey) throws Exception {
return Jwts.parser().setSigningKey(RsaKeyUtil.getPublicKey(pubKey)).parseClaimsJws(token);
}
/**
* 测试类
*
* @param args
* @throws NoSuchAlgorithmException
*/
public static void main(String[] args) throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom secureRandom = new SecureRandom("123".getBytes());
keyPairGenerator.initialize(1024, secureRandom);
KeyPair keyPair = keyPairGenerator.genKeyPair();
System.out.println(keyPair.getPublic().getEncoded());
System.out.println("====");
/**
* 生成公私密钥
*/
Map<String, byte[]> keyMap = RsaKeyUtil.generateKey("123456");
}
}

View File

@ -0,0 +1,138 @@
package com.ycwl.basic.utils;
import com.ycwl.basic.model.snowFlake.UniqueId;
import com.ycwl.basic.model.snowFlake.UniqueIdMetaData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author Created by liuhongguang
* @Description
*/
@Component
public class SnowFlakeUtil {
private Logger log = LoggerFactory.getLogger(com.ycwl.basic.utils.SnowFlakeUtil.class);
/**
* 记录上一毫秒数
*/
private static long lastTimestamp = -1L;
/**
* 记录毫秒内的序列,0-4095
*/
private static long sequence = 0L;
private static Long machineId = 1L;
private static Long datacenterId =1L;
public static synchronized String getId() {
long timestamp = System.currentTimeMillis();
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟被修改过,回退在上一次ID生成时间之前应当抛出异常!!!
if (timestamp < lastTimestamp) {
throw new IllegalStateException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
//如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & UniqueIdMetaData.SEQUENCE_MASK;
//毫秒内序列溢出
if (sequence == 0) {
//阻塞到下一个毫秒,获得新的时间戳
timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return String.valueOf(timestamp);
}
}
//时间戳改变,毫秒内序列重置
else {
sequence = 0L;
}
// 上次生成ID的时间截
lastTimestamp = timestamp;
// 移位并通过或运算组成64位ID
return String.valueOf(((timestamp - UniqueIdMetaData.START_TIME) << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS)
| (datacenterId << UniqueIdMetaData.DATACENTER_SHIFT_BITS)
| (machineId<< UniqueIdMetaData.MACHINE_SHIFT_BITS)
| sequence);
}
public UniqueId explainId(long id) {
UniqueId uniqueId = com.ycwl.basic.utils.SnowFlakeUtil.convert(id);
if (uniqueId == null) {
log.error("==> 解析ID失败, ID不合法");
return null;
}
return uniqueId;
}
public Date transTime(long time) {
return new Date(time + UniqueIdMetaData.START_TIME);
}
/**
* 唯一ID对象解析返回ID
*
* @param uniqueId
* @return
*/
public static long convert(UniqueId uniqueId) {
long result = 0;
try {
result = 0L;
result |= uniqueId.getSequence();
result |= uniqueId.getMachineId() << UniqueIdMetaData.MACHINE_SHIFT_BITS;
result |= uniqueId.getDatacenterId() << UniqueIdMetaData.DATACENTER_SHIFT_BITS;
result |= uniqueId.getTimestamp() << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS;
} catch (Exception e) {
e.printStackTrace();
return result;
}
return result;
}
public static UniqueId convert(long id) {
UniqueId uniqueId = null;
try {
uniqueId = new UniqueId();
uniqueId.setSequence(id & UniqueIdMetaData.SEQUENCE_MASK);
uniqueId.setMachineId((id >>> UniqueIdMetaData.MACHINE_SHIFT_BITS) & UniqueIdMetaData.MACHINE_MASK);
uniqueId.setDatacenterId((id >>> UniqueIdMetaData.DATACENTER_SHIFT_BITS) & UniqueIdMetaData.DATACENTER_MASK);
uniqueId.setTimestamp((id >>> UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS) & UniqueIdMetaData.TIMESTAMP_MASK);
} catch (Exception e) {
e.printStackTrace();
return uniqueId;
}
return uniqueId;
}
}

View File

@ -0,0 +1,11 @@
package com.ycwl.basic.utils;
public final class StringUtil {
public StringUtil() {
}
public static String a(Object obj) {
return obj == null ? "" : obj.toString();
}
}