You've already forked FrameTour-BE
Init
This commit is contained in:
108
src/main/java/com/ycwl/basic/utils/ApiConst.java
Normal file
108
src/main/java/com/ycwl/basic/utils/ApiConst.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
193
src/main/java/com/ycwl/basic/utils/ApiResponse.java
Normal file
193
src/main/java/com/ycwl/basic/utils/ApiResponse.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/com/ycwl/basic/utils/BeanCopierUtils.java
Normal file
44
src/main/java/com/ycwl/basic/utils/BeanCopierUtils.java
Normal 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);
|
||||
}
|
||||
}
|
137
src/main/java/com/ycwl/basic/utils/CodeGenerator.java
Normal file
137
src/main/java/com/ycwl/basic/utils/CodeGenerator.java
Normal 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();
|
||||
// }
|
||||
//
|
||||
//}
|
186
src/main/java/com/ycwl/basic/utils/CommonUtil.java
Normal file
186
src/main/java/com/ycwl/basic/utils/CommonUtil.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
202
src/main/java/com/ycwl/basic/utils/CustomBigDecimalUtils.java
Normal file
202
src/main/java/com/ycwl/basic/utils/CustomBigDecimalUtils.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
82
src/main/java/com/ycwl/basic/utils/JwtAnalysisUtil.java
Normal file
82
src/main/java/com/ycwl/basic/utils/JwtAnalysisUtil.java
Normal 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);
|
||||
}
|
||||
}
|
114
src/main/java/com/ycwl/basic/utils/JwtTokenUtil.java
Normal file
114
src/main/java/com/ycwl/basic/utils/JwtTokenUtil.java
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
180
src/main/java/com/ycwl/basic/utils/ObjectConvertUtils.java
Normal file
180
src/main/java/com/ycwl/basic/utils/ObjectConvertUtils.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
79
src/main/java/com/ycwl/basic/utils/RsaKeyUtil.java
Normal file
79
src/main/java/com/ycwl/basic/utils/RsaKeyUtil.java
Normal 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");
|
||||
}
|
||||
}
|
138
src/main/java/com/ycwl/basic/utils/SnowFlakeUtil.java
Normal file
138
src/main/java/com/ycwl/basic/utils/SnowFlakeUtil.java
Normal 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;
|
||||
}
|
||||
}
|
11
src/main/java/com/ycwl/basic/utils/StringUtil.java
Normal file
11
src/main/java/com/ycwl/basic/utils/StringUtil.java
Normal 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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user