save code
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>digital-common</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>digital-util</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--JWT-->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>${java-jwt.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>5.3.18</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!--集成springmvc框架 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<!--加载hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
</dependency>
|
||||
<!--加载beanutils-->
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-extension</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.11.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
</dependency>
|
||||
<!-- 阿里云短信 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
|
||||
<version>${aliyun-java-sdk-dysmsapi.version}</version>
|
||||
</dependency>
|
||||
<!-- aliyun oss -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${aliyun.oss.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>1.9.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>digital-base</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>autopoi</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package digital.util.desensitization.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 解密注解
|
||||
*
|
||||
* 在方法上定义 将方法返回对象中的敏感字段 解密,需要注意的是,如果没有加密过,解密会出问题,返回原字符串
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface SensitiveDecode {
|
||||
|
||||
/**
|
||||
* 指明需要脱敏的实体类class
|
||||
* @return
|
||||
*/
|
||||
Class entity() default Object.class;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package digital.util.desensitization.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 加密注解
|
||||
*
|
||||
* 在方法上声明 将方法返回对象中的敏感字段 加密/格式化
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface SensitiveEncode {
|
||||
|
||||
/**
|
||||
* 指明需要脱敏的实体类class
|
||||
* @return
|
||||
*/
|
||||
Class entity() default Object.class;
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package digital.util.desensitization.annotation;
|
||||
|
||||
|
||||
|
||||
import digital.util.desensitization.enums.SensitiveEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 在字段上定义 标识字段存储的信息是敏感的
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface SensitiveField {
|
||||
|
||||
/**
|
||||
* 不同类型处理不同
|
||||
* @return
|
||||
*/
|
||||
SensitiveEnum type() default SensitiveEnum.ENCODE;
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package digital.util.desensitization.aspect;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
import digital.util.desensitization.annotation.SensitiveDecode;
|
||||
import digital.util.desensitization.annotation.SensitiveEncode;
|
||||
import digital.util.desensitization.util.SensitiveInfoUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感数据切面处理类
|
||||
* @Author taoYan
|
||||
* @Date 2022/4/20 17:45
|
||||
**/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
public class SensitiveDataAspect {
|
||||
/**
|
||||
* 定义切点Pointcut
|
||||
*/
|
||||
@Pointcut("@annotation(digital.util.desensitization.annotation.SensitiveEncode) || @annotation(digital.util.desensitization.annotation.SensitiveDecode)")
|
||||
public void sensitivePointCut() {
|
||||
}
|
||||
@Around("sensitivePointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
// 处理结果
|
||||
Object result = point.proceed();
|
||||
if(result == null){
|
||||
return result;
|
||||
}
|
||||
Class resultClass = result.getClass();
|
||||
log.debug(" resultClass = {}" , resultClass);
|
||||
|
||||
if(resultClass.isPrimitive()){
|
||||
//是基本类型 直接返回 不需要处理
|
||||
return result;
|
||||
}
|
||||
// 获取方法注解信息:是哪个实体、是加密还是解密
|
||||
boolean isEncode = true;
|
||||
Class entity = null;
|
||||
MethodSignature methodSignature = (MethodSignature) point.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
SensitiveEncode encode = method.getAnnotation(SensitiveEncode.class);
|
||||
if(encode==null){
|
||||
SensitiveDecode decode = method.getAnnotation(SensitiveDecode.class);
|
||||
if(decode!=null){
|
||||
entity = decode.entity();
|
||||
isEncode = false;
|
||||
}
|
||||
}else{
|
||||
entity = encode.entity();
|
||||
}
|
||||
|
||||
long startTime=System.currentTimeMillis();
|
||||
if(resultClass.equals(entity) || entity.equals(Object.class)){
|
||||
// 方法返回实体和注解的entity一样,如果注解没有申明entity属性则认为是(方法返回实体和注解的entity一样)
|
||||
SensitiveInfoUtil.handlerObject(result, isEncode);
|
||||
} else if(result instanceof List){
|
||||
// 方法返回List<实体>
|
||||
SensitiveInfoUtil.handleList(result, entity, isEncode);
|
||||
}else{
|
||||
// 方法返回一个对象
|
||||
SensitiveInfoUtil.handleNestedObject(result, entity, isEncode);
|
||||
}
|
||||
long endTime=System.currentTimeMillis();
|
||||
log.info((isEncode ? "加密操作," : "解密操作,") + "Aspect程序耗时:" + (endTime - startTime) + "ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package digital.util.desensitization.enums;
|
||||
|
||||
|
||||
|
||||
public enum ResultTypeEnum {
|
||||
picture_1("401", "未检测到合适人脸"),
|
||||
picture_2("402", "mesh服务返回错误"),
|
||||
picture_3("403", "参数传递错误"),
|
||||
picture_4("404", "结果上传失败,网络错误"),
|
||||
picture_5("405", "算法处理错误"),
|
||||
;
|
||||
|
||||
ResultTypeEnum(String code, String content) {
|
||||
this.code = code;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
private String code;
|
||||
private String content;
|
||||
|
||||
|
||||
public static ResultTypeEnum codeIn(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (ResultTypeEnum em : ResultTypeEnum.values()) {
|
||||
if (em.getCode().equals(code)) {
|
||||
return em;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package digital.util.desensitization.enums;
|
||||
|
||||
/**
|
||||
* 敏感字段信息类型
|
||||
*/
|
||||
public enum SensitiveEnum {
|
||||
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*/
|
||||
ENCODE,
|
||||
|
||||
/**
|
||||
* 中文名
|
||||
*/
|
||||
CHINESE_NAME,
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
ID_CARD,
|
||||
|
||||
/**
|
||||
* 座机号
|
||||
*/
|
||||
FIXED_PHONE,
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
MOBILE_PHONE,
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
ADDRESS,
|
||||
|
||||
/**
|
||||
* 电子邮件
|
||||
*/
|
||||
EMAIL,
|
||||
|
||||
/**
|
||||
* 银行卡
|
||||
*/
|
||||
BANK_CARD,
|
||||
|
||||
/**
|
||||
* 公司开户银行联号
|
||||
*/
|
||||
CNAPS_CODE;
|
||||
|
||||
|
||||
}
|
||||
+362
@@ -0,0 +1,362 @@
|
||||
package digital.util.desensitization.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import digital.util.desensitization.annotation.SensitiveField;
|
||||
import digital.util.desensitization.enums.SensitiveEnum;
|
||||
import digital.util.encryption.AesEncryptUtil;
|
||||
import digital.util.util.oConvertUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感信息处理工具类
|
||||
* @author taoYan
|
||||
* @date 2022/4/20 18:01
|
||||
**/
|
||||
@Slf4j
|
||||
public class SensitiveInfoUtil {
|
||||
|
||||
/**
|
||||
* 处理嵌套对象
|
||||
* @param obj 方法返回值
|
||||
* @param entity 实体class
|
||||
* @param isEncode 是否加密(true: 加密操作 / false:解密操作)
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static void handleNestedObject(Object obj, Class entity, boolean isEncode) throws IllegalAccessException {
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if(field.getType().isPrimitive()){
|
||||
continue;
|
||||
}
|
||||
if(field.getType().equals(entity)){
|
||||
// 对象里面是实体
|
||||
field.setAccessible(true);
|
||||
Object nestedObject = field.get(obj);
|
||||
handlerObject(nestedObject, isEncode);
|
||||
break;
|
||||
}else{
|
||||
// 对象里面是List<实体>
|
||||
if(field.getGenericType() instanceof ParameterizedType){
|
||||
ParameterizedType pt = (ParameterizedType)field.getGenericType();
|
||||
if(pt.getRawType().equals(List.class)){
|
||||
if(pt.getActualTypeArguments()[0].equals(entity)){
|
||||
field.setAccessible(true);
|
||||
Object nestedObject = field.get(obj);
|
||||
handleList(nestedObject, entity, isEncode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Object
|
||||
* @param obj 方法返回值
|
||||
* @param isEncode 是否加密(true: 加密操作 / false:解密操作)
|
||||
* @return
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static Object handlerObject(Object obj, boolean isEncode) throws IllegalAccessException {
|
||||
log.debug(" obj --> "+ obj.toString());
|
||||
long startTime=System.currentTimeMillis();
|
||||
if (oConvertUtils.isEmpty(obj)) {
|
||||
return obj;
|
||||
}
|
||||
// 判断是不是一个对象
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
boolean isSensitiveField = field.isAnnotationPresent(SensitiveField.class);
|
||||
if(isSensitiveField){
|
||||
// 必须有SensitiveField注解 才作处理
|
||||
if(field.getType().isAssignableFrom(String.class)){
|
||||
//必须是字符串类型 才作处理
|
||||
field.setAccessible(true);
|
||||
String realValue = (String) field.get(obj);
|
||||
if(realValue==null || "".equals(realValue)){
|
||||
continue;
|
||||
}
|
||||
SensitiveField sf = field.getAnnotation(SensitiveField.class);
|
||||
if(isEncode==true){
|
||||
//加密
|
||||
String value = SensitiveInfoUtil.getEncodeData(realValue, sf.type());
|
||||
field.set(obj, value);
|
||||
}else{
|
||||
//解密只处理 encode类型的
|
||||
if(sf.type().equals(SensitiveEnum.ENCODE)){
|
||||
String value = SensitiveInfoUtil.getDecodeData(realValue);
|
||||
field.set(obj, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//long endTime=System.currentTimeMillis();
|
||||
//log.info((isEncode ? "加密操作," : "解密操作,") + "当前程序耗时:" + (endTime - startTime) + "ms");
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 List<实体>
|
||||
* @param obj
|
||||
* @param entity
|
||||
* @param isEncode(true: 加密操作 / false:解密操作)
|
||||
*/
|
||||
public static void handleList(Object obj, Class entity, boolean isEncode){
|
||||
List list = (List)obj;
|
||||
if(list.size()>0){
|
||||
Object first = list.get(0);
|
||||
if(first.getClass().equals(entity)){
|
||||
for(int i=0; i<list.size(); i++){
|
||||
Object temp = list.get(i);
|
||||
try {
|
||||
handlerObject(temp, isEncode);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理数据 获取解密后的数据
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static String getDecodeData(String data){
|
||||
String result = null;
|
||||
try {
|
||||
result = AesEncryptUtil.desEncrypt(data);
|
||||
} catch (Exception exception) {
|
||||
log.warn("数据解密错误,原数据:"+data);
|
||||
}
|
||||
//解决debug模式下,加解密失效导致中文被解密变成空的问题
|
||||
if(oConvertUtils.isEmpty(result) && oConvertUtils.isNotEmpty(data)){
|
||||
result = data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据 获取加密后的数据 或是格式化后的数据
|
||||
* @param data 字符串
|
||||
* @param sensitiveEnum 类型
|
||||
* @return 处理后的字符串
|
||||
*/
|
||||
public static String getEncodeData(String data, SensitiveEnum sensitiveEnum){
|
||||
String result;
|
||||
switch (sensitiveEnum){
|
||||
case ENCODE:
|
||||
try {
|
||||
result = AesEncryptUtil.encrypt(data);
|
||||
} catch (Exception exception) {
|
||||
log.error("数据加密错误", exception.getMessage());
|
||||
result = data;
|
||||
}
|
||||
break;
|
||||
case CHINESE_NAME:
|
||||
result = chineseName(data);
|
||||
break;
|
||||
case ID_CARD:
|
||||
result = idCardNum(data);
|
||||
break;
|
||||
case FIXED_PHONE:
|
||||
result = fixedPhone(data);
|
||||
break;
|
||||
case MOBILE_PHONE:
|
||||
result = mobilePhone(data);
|
||||
break;
|
||||
case ADDRESS:
|
||||
result = address(data, 3);
|
||||
break;
|
||||
case EMAIL:
|
||||
result = email(data);
|
||||
break;
|
||||
case BANK_CARD:
|
||||
result = bankCard(data);
|
||||
break;
|
||||
case CNAPS_CODE:
|
||||
result = cnapsCode(data);
|
||||
break;
|
||||
default:
|
||||
result = data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号
|
||||
* @param fullName 全名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
private static String chineseName(String fullName) {
|
||||
if (oConvertUtils.isEmpty(fullName)) {
|
||||
return "";
|
||||
}
|
||||
return formatRight(fullName, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号
|
||||
* @param familyName 姓
|
||||
* @param firstName 名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
private static String chineseName(String familyName, String firstName) {
|
||||
if (oConvertUtils.isEmpty(familyName) || oConvertUtils.isEmpty(firstName)) {
|
||||
return "";
|
||||
}
|
||||
return chineseName(familyName + firstName);
|
||||
}
|
||||
|
||||
/**
|
||||
* [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。
|
||||
* @param id 身份证号
|
||||
* @return <例子:*************5762>
|
||||
*/
|
||||
private static String idCardNum(String id) {
|
||||
if (oConvertUtils.isEmpty(id)) {
|
||||
return "";
|
||||
}
|
||||
return formatLeft(id, 4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* [固定电话] 后四位,其他隐藏
|
||||
* @param num 固定电话
|
||||
* @return <例子:****1234>
|
||||
*/
|
||||
private static String fixedPhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
return formatLeft(num, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [手机号码] 前三位,后四位,其他隐藏
|
||||
* @param num 手机号码
|
||||
* @return <例子:138******1234>
|
||||
*/
|
||||
private static String mobilePhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
int len = num.length();
|
||||
if(len<11){
|
||||
return num;
|
||||
}
|
||||
return formatBetween(num, 3, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护
|
||||
* @param address 地址
|
||||
* @param sensitiveSize 敏感信息长度
|
||||
* @return <例子:北京市海淀区****>
|
||||
*/
|
||||
private static String address(String address, int sensitiveSize) {
|
||||
if (oConvertUtils.isEmpty(address)) {
|
||||
return "";
|
||||
}
|
||||
int len = address.length();
|
||||
if(len<sensitiveSize){
|
||||
return address;
|
||||
}
|
||||
return formatRight(address, sensitiveSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示
|
||||
* @param email 电子邮箱
|
||||
* @return <例子:g**@163.com>
|
||||
*/
|
||||
private static String email(String email) {
|
||||
if (oConvertUtils.isEmpty(email)) {
|
||||
return "";
|
||||
}
|
||||
int index = email.indexOf("@");
|
||||
if (index <= 1){
|
||||
return email;
|
||||
}
|
||||
String begin = email.substring(0, 1);
|
||||
String end = email.substring(index);
|
||||
String stars = "**";
|
||||
return begin + stars + end;
|
||||
}
|
||||
|
||||
/**
|
||||
* [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号
|
||||
* @param cardNum 银行卡号
|
||||
* @return <例子:6222600**********1234>
|
||||
*/
|
||||
private static String bankCard(String cardNum) {
|
||||
if (oConvertUtils.isEmpty(cardNum)) {
|
||||
return "";
|
||||
}
|
||||
return formatBetween(cardNum, 6, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号
|
||||
* @param code 公司开户银行联号
|
||||
* @return <例子:12********>
|
||||
*/
|
||||
private static String cnapsCode(String code) {
|
||||
if (oConvertUtils.isEmpty(code)) {
|
||||
return "";
|
||||
}
|
||||
return formatRight(code, 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将右边的格式化成*
|
||||
* @param str 字符串
|
||||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatRight(String str, int reservedLength){
|
||||
String name = str.substring(0, reservedLength);
|
||||
String stars = String.join("", Collections.nCopies(str.length()-reservedLength, "*"));
|
||||
return name + stars;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将左边的格式化成*
|
||||
* @param str 字符串
|
||||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatLeft(String str, int reservedLength){
|
||||
int len = str.length();
|
||||
String show = str.substring(len-reservedLength);
|
||||
String stars = String.join("", Collections.nCopies(len-reservedLength, "*"));
|
||||
return stars + show;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将中间的格式化成*
|
||||
* @param str 字符串
|
||||
* @param beginLen 开始保留长度
|
||||
* @param endLen 结尾保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatBetween(String str, int beginLen, int endLen){
|
||||
int len = str.length();
|
||||
String begin = str.substring(0, beginLen);
|
||||
String end = str.substring(len-endLen);
|
||||
String stars = String.join("", Collections.nCopies(len-beginLen-endLen, "*"));
|
||||
return begin + stars + end;
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package digital.util.encryption;
|
||||
|
||||
import org.apache.shiro.codec.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* @Description: AES 加密
|
||||
* @author: smcp
|
||||
* @date: 2022/3/30 11:48
|
||||
*/
|
||||
public class AesEncryptUtil {
|
||||
|
||||
/**
|
||||
* 使用AES-128-CBC加密模式 key和iv可以相同
|
||||
*/
|
||||
private static String KEY = EncryptedString.key;
|
||||
private static String IV = EncryptedString.iv;
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
* @param data 要加密的数据
|
||||
* @param key 加密key
|
||||
* @param iv 加密iv
|
||||
* @return 加密的结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String data, String key, String iv) throws Exception {
|
||||
try {
|
||||
|
||||
//"算法/模式/补码方式"NoPadding PkcsPadding
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
int blockSize = cipher.getBlockSize();
|
||||
|
||||
byte[] dataBytes = data.getBytes();
|
||||
int plaintextLength = dataBytes.length;
|
||||
if (plaintextLength % blockSize != 0) {
|
||||
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
|
||||
}
|
||||
|
||||
byte[] plaintext = new byte[plaintextLength];
|
||||
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
|
||||
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
|
||||
byte[] encrypted = cipher.doFinal(plaintext);
|
||||
|
||||
return Base64.encodeToString(encrypted);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
* @param data 要解密的数据
|
||||
* @param key 解密key
|
||||
* @param iv 解密iv
|
||||
* @return 解密的结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String desEncrypt(String data, String key, String iv) throws Exception {
|
||||
try {
|
||||
byte[] encrypted1 = Base64.decode(data);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
String originalString = new String(original);
|
||||
return originalString;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认的key和iv加密
|
||||
* @param data
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String data) throws Exception {
|
||||
return encrypt(data, KEY, IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认的key和iv解密
|
||||
* @param data
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String desEncrypt(String data) throws Exception {
|
||||
return desEncrypt(data, KEY, IV);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 测试
|
||||
// */
|
||||
// public static void main(String args[]) throws Exception {
|
||||
// String test1 = "sa";
|
||||
// String test =new String(test1.getBytes(),"UTF-8");
|
||||
// String data = null;
|
||||
// String key = KEY;
|
||||
// String iv = IV;
|
||||
// // /g2wzfqvMOeazgtsUVbq1kmJawROa6mcRAzwG1/GeJ4=
|
||||
// data = encrypt(test, key, iv);
|
||||
// System.out.println("数据:"+test);
|
||||
// System.out.println("加密:"+data);
|
||||
// String jiemi =desEncrypt(data, key, iv).trim();
|
||||
// System.out.println("解密:"+jiemi);
|
||||
// }
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package digital.util.encryption;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: EncryptedString
|
||||
* @author: smcp
|
||||
*/
|
||||
@Data
|
||||
public class EncryptedString {
|
||||
|
||||
/**
|
||||
* 长度为16个字符
|
||||
*/
|
||||
public static String key = "1234567890adbcde";
|
||||
|
||||
/**
|
||||
* 长度为16个字符
|
||||
*/
|
||||
public static String iv = "1234567890hjlkew";
|
||||
}
|
||||
+551
@@ -0,0 +1,551 @@
|
||||
//package digital.util.util.es;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSONArray;
|
||||
//import com.alibaba.fastjson.JSONObject;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.beans.factory.annotation.Value;
|
||||
//import org.springframework.http.HttpHeaders;
|
||||
//import org.springframework.http.HttpMethod;
|
||||
//import org.springframework.http.HttpStatus;
|
||||
//import org.springframework.http.ResponseEntity;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//import org.springframework.util.StringUtils;
|
||||
//import digital.util.util.RestUtil;
|
||||
//import digital.util.util.oConvertUtils;
|
||||
//
|
||||
//import java.util.*;
|
||||
//
|
||||
///**
|
||||
// * 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等)
|
||||
// *
|
||||
// * @author sunjianlei
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//public class JeecgElasticsearchTemplate {
|
||||
// /**
|
||||
// * ElasticSearch 最大可返回条目数
|
||||
// */
|
||||
// public static final int ES_MAX_SIZE = 10000;
|
||||
// private final String FORMAT_JSON = "format=json";
|
||||
// /**
|
||||
// * es7
|
||||
// */
|
||||
// public static final String IE_SEVEN = "7";
|
||||
// /**
|
||||
// * url not found 404
|
||||
// */
|
||||
// public static final String URL_NOT_FOUND = "404 Not Found";
|
||||
// /**
|
||||
// * es服务地址
|
||||
// */
|
||||
// private String baseUrl;
|
||||
// /**
|
||||
// * Elasticsearch 的版本号
|
||||
// */
|
||||
// private String version = null;
|
||||
//
|
||||
// public JeecgElasticsearchTemplate(@Value("${jeecg.elasticsearch.cluster-nodes}") String baseUrl, @Value("${jeecg.elasticsearch.check-enabled}") boolean checkEnabled) {
|
||||
// log.debug("JeecgElasticsearchTemplate BaseURL:" + baseUrl);
|
||||
// if (oConvertUtils.isNotEmpty(baseUrl)) {
|
||||
// this.baseUrl = baseUrl;
|
||||
// // 验证配置的ES地址是否有效
|
||||
// if (checkEnabled) {
|
||||
// try {
|
||||
// this.getElasticsearchVersion();
|
||||
// log.info("ElasticSearch 服务连接成功");
|
||||
// log.info("ElasticSearch version: " + this.version);
|
||||
// } catch (Exception e) {
|
||||
// this.version = "";
|
||||
// log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取 Elasticsearch 的版本号信息,失败返回null
|
||||
// */
|
||||
// private void getElasticsearchVersion() {
|
||||
// if (this.version == null) {
|
||||
// String url = this.getBaseUrl().toString();
|
||||
// JSONObject result = RestUtil.get(url);
|
||||
// if (result != null) {
|
||||
// JSONObject v = result.getJSONObject("version");
|
||||
// this.version = v.getString("number");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public StringBuilder getBaseUrl(String indexName, String typeName) {
|
||||
// typeName = typeName.trim().toLowerCase();
|
||||
// return this.getBaseUrl(indexName).append("/").append(typeName);
|
||||
// }
|
||||
//
|
||||
// public StringBuilder getBaseUrl(String indexName) {
|
||||
// indexName = indexName.trim().toLowerCase();
|
||||
// return this.getBaseUrl().append("/").append(indexName);
|
||||
// }
|
||||
//
|
||||
// public StringBuilder getBaseUrl() {
|
||||
// return new StringBuilder("http://").append(this.baseUrl);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * cat 查询ElasticSearch系统数据,返回json
|
||||
// */
|
||||
// private <T> ResponseEntity<T> cat(String urlAfter, Class<T> responseType) {
|
||||
// String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString();
|
||||
// return RestUtil.request(url, HttpMethod.GET, null, null, null, responseType);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 查询所有索引
|
||||
// * <p>
|
||||
// * 查询地址:GET http://{baseUrl}/_cat/indices
|
||||
// */
|
||||
// public JSONArray getIndices() {
|
||||
// return getIndices(null);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 查询单个索引
|
||||
// * <p>
|
||||
// * 查询地址:GET http://{baseUrl}/_cat/indices/{indexName}
|
||||
// */
|
||||
// public JSONArray getIndices(String indexName) {
|
||||
// StringBuilder urlAfter = new StringBuilder("/indices");
|
||||
// if (!StringUtils.isEmpty(indexName)) {
|
||||
// urlAfter.append("/").append(indexName.trim().toLowerCase());
|
||||
// }
|
||||
// return cat(urlAfter.toString(), JSONArray.class).getBody();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 索引是否存在
|
||||
// */
|
||||
// public boolean indexExists(String indexName) {
|
||||
// try {
|
||||
// JSONArray array = getIndices(indexName);
|
||||
// return array != null;
|
||||
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
|
||||
// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
|
||||
// return false;
|
||||
// } else {
|
||||
// throw ex;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据ID获取索引数据,未查询到返回null
|
||||
// * <p>
|
||||
// * 查询地址:GET http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
||||
// *
|
||||
// * @param indexName 索引名称
|
||||
// * @param typeName type,一个任意字符串,用于分类
|
||||
// * @param dataId 数据id
|
||||
// * @return
|
||||
// */
|
||||
// public JSONObject getDataById(String indexName, String typeName, String dataId) {
|
||||
// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
|
||||
// log.info("url:" + url);
|
||||
// JSONObject result = RestUtil.get(url);
|
||||
// boolean found = result.getBoolean("found");
|
||||
// if (found) {
|
||||
// return result.getJSONObject("_source");
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 创建索引
|
||||
// * <p>
|
||||
// * 查询地址:PUT http://{baseUrl}/{indexName}
|
||||
// */
|
||||
// public boolean createIndex(String indexName) {
|
||||
// String url = this.getBaseUrl(indexName).toString();
|
||||
//
|
||||
// /* 返回结果 (仅供参考)
|
||||
// "createIndex": {
|
||||
// "shards_acknowledged": true,
|
||||
// "acknowledged": true,
|
||||
// "index": "hello_world"
|
||||
// }
|
||||
// */
|
||||
// try {
|
||||
// return RestUtil.put(url).getBoolean("acknowledged");
|
||||
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
|
||||
// if (HttpStatus.BAD_REQUEST == ex.getStatusCode()) {
|
||||
// log.warn("索引创建失败:" + indexName + " 已存在,无需再创建");
|
||||
// } else {
|
||||
// ex.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 删除索引
|
||||
// * <p>
|
||||
// * 查询地址:DELETE http://{baseUrl}/{indexName}
|
||||
// */
|
||||
// public boolean removeIndex(String indexName) {
|
||||
// String url = this.getBaseUrl(indexName).toString();
|
||||
// try {
|
||||
// return RestUtil.delete(url).getBoolean("acknowledged");
|
||||
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
|
||||
// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
|
||||
// log.warn("索引删除失败:" + indexName + " 不存在,无需删除");
|
||||
// } else {
|
||||
// ex.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取索引字段映射(可获取字段类型)
|
||||
// * <p>
|
||||
// *
|
||||
// * @param indexName 索引名称
|
||||
// * @param typeName 分类名称
|
||||
// * @return
|
||||
// */
|
||||
// public JSONObject getIndexMapping(String indexName, String typeName) {
|
||||
// String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString();
|
||||
// // 针对 es 7.x 版本做兼容
|
||||
// this.getElasticsearchVersion();
|
||||
// if (oConvertUtils.isNotEmpty(this.version) && this.version.startsWith(IE_SEVEN)) {
|
||||
// url += "&include_type_name=true";
|
||||
// }
|
||||
// log.info("getIndexMapping-url:" + url);
|
||||
// /*
|
||||
// * 参考返回JSON结构:
|
||||
// *
|
||||
// *{
|
||||
// * // 索引名称
|
||||
// * "[indexName]": {
|
||||
// * "mappings": {
|
||||
// * // 分类名称
|
||||
// * "[typeName]": {
|
||||
// * "properties": {
|
||||
// * // 字段名
|
||||
// * "input_number": {
|
||||
// * // 字段类型
|
||||
// * "type": "long"
|
||||
// * },
|
||||
// * "input_string": {
|
||||
// * "type": "text",
|
||||
// * "fields": {
|
||||
// * "keyword": {
|
||||
// * "type": "keyword",
|
||||
// * "ignore_above": 256
|
||||
// * }
|
||||
// * }
|
||||
// * }
|
||||
// * }
|
||||
// * }
|
||||
// * }
|
||||
// * }
|
||||
// * }
|
||||
// */
|
||||
// try {
|
||||
// return RestUtil.get(url);
|
||||
// } catch (org.springframework.web.client.HttpClientErrorException e) {
|
||||
// String message = e.getMessage();
|
||||
// if (message != null && message.contains(URL_NOT_FOUND)) {
|
||||
// return null;
|
||||
// }
|
||||
// throw e;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取索引字段映射,返回Java实体类
|
||||
// *
|
||||
// * @param indexName
|
||||
// * @param typeName
|
||||
// * @return
|
||||
// */
|
||||
// public <T> Map<String, T> getIndexMappingFormat(String indexName, String typeName, Class<T> clazz) {
|
||||
// JSONObject mapping = this.getIndexMapping(indexName, typeName);
|
||||
// Map<String, T> map = new HashMap<>(5);
|
||||
// if (mapping == null) {
|
||||
// return map;
|
||||
// }
|
||||
// // 获取字段属性
|
||||
// JSONObject properties = mapping.getJSONObject(indexName)
|
||||
// .getJSONObject("mappings")
|
||||
// .getJSONObject(typeName)
|
||||
// .getJSONObject("properties");
|
||||
// // 封装成 java类型
|
||||
// for (String key : properties.keySet()) {
|
||||
// T entity = properties.getJSONObject(key).toJavaObject(clazz);
|
||||
// map.put(key, entity);
|
||||
// }
|
||||
// return map;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 保存数据,详见:saveOrUpdate
|
||||
// */
|
||||
// public boolean save(String indexName, String typeName, String dataId, JSONObject data) {
|
||||
// return this.saveOrUpdate(indexName, typeName, dataId, data);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 更新数据,详见:saveOrUpdate
|
||||
// */
|
||||
// public boolean update(String indexName, String typeName, String dataId, JSONObject data) {
|
||||
// return this.saveOrUpdate(indexName, typeName, dataId, data);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 保存或修改索引数据
|
||||
// * <p>
|
||||
// * 查询地址:PUT http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
||||
// *
|
||||
// * @param indexName 索引名称
|
||||
// * @param typeName type,一个任意字符串,用于分类
|
||||
// * @param dataId 数据id
|
||||
// * @param data 要存储的数据
|
||||
// * @return
|
||||
// */
|
||||
// public boolean saveOrUpdate(String indexName, String typeName, String dataId, JSONObject data) {
|
||||
// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).append("?refresh=wait_for").toString();
|
||||
// /* 返回结果(仅供参考)
|
||||
// "createIndexA2": {
|
||||
// "result": "created",
|
||||
// "_shards": {
|
||||
// "total": 2,
|
||||
// "successful": 1,
|
||||
// "failed": 0
|
||||
// },
|
||||
// "_seq_no": 0,
|
||||
// "_index": "test_index_1",
|
||||
// "_type": "test_type_1",
|
||||
// "_id": "a2",
|
||||
// "_version": 1,
|
||||
// "_primary_term": 1
|
||||
// }
|
||||
// */
|
||||
//
|
||||
// try {
|
||||
// // 去掉 data 中为空的值
|
||||
// Set<String> keys = data.keySet();
|
||||
// List<String> emptyKeys = new ArrayList<>(keys.size());
|
||||
// for (String key : keys) {
|
||||
// String value = data.getString(key);
|
||||
// //1、剔除空值
|
||||
// if (oConvertUtils.isEmpty(value) || "[]".equals(value)) {
|
||||
// emptyKeys.add(key);
|
||||
// }
|
||||
// //2、剔除上传控件值(会导致ES同步失败,报异常failed to parse field [ge_pic] of type [text] )
|
||||
// if (oConvertUtils.isNotEmpty(value) && value.indexOf("[{") != -1) {
|
||||
// emptyKeys.add(key);
|
||||
// log.info("-------剔除上传控件字段------------key: " + key);
|
||||
// }
|
||||
// }
|
||||
// for (String key : emptyKeys) {
|
||||
// data.remove(key);
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// String result = RestUtil.put(url, data).getString("result");
|
||||
// return "created".equals(result) || "updated".equals(result);
|
||||
// } catch (Exception e) {
|
||||
// log.error(e.getMessage() + "\n-- url: " + url + "\n-- data: " + data.toJSONString());
|
||||
// //TODO 打印接口返回异常json
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 批量保存数据
|
||||
// *
|
||||
// * @param indexName 索引名称
|
||||
// * @param typeName type,一个任意字符串,用于分类
|
||||
// * @param dataList 要存储的数据数组,每行数据必须包含id
|
||||
// * @return
|
||||
// */
|
||||
// public boolean saveBatch(String indexName, String typeName, JSONArray dataList) {
|
||||
// String url = this.getBaseUrl().append("/_bulk").append("?refresh=wait_for").toString();
|
||||
// StringBuilder bodySb = new StringBuilder();
|
||||
// for (int i = 0; i < dataList.size(); i++) {
|
||||
// JSONObject data = dataList.getJSONObject(i);
|
||||
// String id = data.getString("id");
|
||||
// // 该行的操作
|
||||
// // {"create": {"_id":"${id}", "_index": "${indexName}", "_type": "${typeName}"}}
|
||||
// JSONObject action = new JSONObject();
|
||||
// JSONObject actionInfo = new JSONObject();
|
||||
// actionInfo.put("_id", id);
|
||||
// actionInfo.put("_index", indexName);
|
||||
// actionInfo.put("_type", typeName);
|
||||
// action.put("create", actionInfo);
|
||||
// bodySb.append(action.toJSONString()).append("\n");
|
||||
// // 该行的数据
|
||||
// data.remove("id");
|
||||
// bodySb.append(data.toJSONString()).append("\n");
|
||||
// }
|
||||
// System.out.println("+-+-+-: bodySb.toString(): " + bodySb.toString());
|
||||
// HttpHeaders headers = RestUtil.getHeaderApplicationJson();
|
||||
// RestUtil.request(url, HttpMethod.PUT, headers, null, bodySb, JSONObject.class);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 删除索引数据
|
||||
// * <p>
|
||||
// * 请求地址:DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
||||
// */
|
||||
// public boolean delete(String indexName, String typeName, String dataId) {
|
||||
// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
|
||||
// /* 返回结果(仅供参考)
|
||||
// {
|
||||
// "_index": "es_demo",
|
||||
// "_type": "docs",
|
||||
// "_id": "001",
|
||||
// "_version": 3,
|
||||
// "result": "deleted",
|
||||
// "_shards": {
|
||||
// "total": 1,
|
||||
// "successful": 1,
|
||||
// "failed": 0
|
||||
// },
|
||||
// "_seq_no": 28,
|
||||
// "_primary_term": 18
|
||||
// }
|
||||
// */
|
||||
// try {
|
||||
// return "deleted".equals(RestUtil.delete(url).getString("result"));
|
||||
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
|
||||
// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
|
||||
// return false;
|
||||
// } else {
|
||||
// throw ex;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /* = = = 以下关于查询和查询条件的方法 = = =*/
|
||||
//
|
||||
// /**
|
||||
// * 查询数据
|
||||
// * <p>
|
||||
// * 请求地址:POST http://{baseUrl}/{indexName}/{typeName}/_search
|
||||
// */
|
||||
// public JSONObject search(String indexName, String typeName, JSONObject queryObject) {
|
||||
// String url = this.getBaseUrl(indexName, typeName).append("/_search").toString();
|
||||
//
|
||||
// log.info("url:" + url + " ,search: " + queryObject.toJSONString());
|
||||
// JSONObject res = RestUtil.post(url, queryObject);
|
||||
// log.info("url:" + url + " ,return res: \n" + res.toJSONString());
|
||||
// return res;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param source (源滤波器)指定返回的字段,传null返回所有字段
|
||||
// * @param query
|
||||
// * @param from 从第几条数据开始
|
||||
// * @param size 返回条目数
|
||||
// * @return { "query": query }
|
||||
// */
|
||||
// public JSONObject buildQuery(List<String> source, JSONObject query, int from, int size) {
|
||||
// JSONObject json = new JSONObject();
|
||||
// if (source != null) {
|
||||
// json.put("_source", source);
|
||||
// }
|
||||
// json.put("query", query);
|
||||
// json.put("from", from);
|
||||
// json.put("size", size);
|
||||
// return json;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return { "bool" : { "must": must, "must_not": mustNot, "should": should } }
|
||||
// */
|
||||
// public JSONObject buildBoolQuery(JSONArray must, JSONArray mustNot, JSONArray should) {
|
||||
// JSONObject bool = new JSONObject();
|
||||
// if (must != null) {
|
||||
// bool.put("must", must);
|
||||
// }
|
||||
// if (mustNot != null) {
|
||||
// bool.put("must_not", mustNot);
|
||||
// }
|
||||
// if (should != null) {
|
||||
// bool.put("should", should);
|
||||
// }
|
||||
// JSONObject json = new JSONObject();
|
||||
// json.put("bool", bool);
|
||||
// return json;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param field 要查询的字段
|
||||
// * @param args 查询参数,参考: *哈哈* OR *哒* NOT *呵* OR *啊*
|
||||
// * @return
|
||||
// */
|
||||
// public JSONObject buildQueryString(String field, String... args) {
|
||||
// if (field == null) {
|
||||
// return null;
|
||||
// }
|
||||
// StringBuilder sb = new StringBuilder(field).append(":(");
|
||||
// if (args != null) {
|
||||
// for (String arg : args) {
|
||||
// sb.append(arg).append(" ");
|
||||
// }
|
||||
// }
|
||||
// sb.append(")");
|
||||
// return this.buildQueryString(sb.toString());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return { "query_string": { "query": query } }
|
||||
// */
|
||||
// public JSONObject buildQueryString(String query) {
|
||||
// JSONObject queryString = new JSONObject();
|
||||
// queryString.put("query", query);
|
||||
// JSONObject json = new JSONObject();
|
||||
// json.put("query_string", queryString);
|
||||
// return json;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param field 查询字段
|
||||
// * @param min 最小值
|
||||
// * @param max 最大值
|
||||
// * @param containMin 范围内是否包含最小值
|
||||
// * @param containMax 范围内是否包含最大值
|
||||
// * @return { "range" : { field : { 『 "gt『e』?containMin" : min 』?min!=null , 『 "lt『e』?containMax" : max 』}} }
|
||||
// */
|
||||
// public JSONObject buildRangeQuery(String field, Object min, Object max, boolean containMin, boolean containMax) {
|
||||
// JSONObject inner = new JSONObject();
|
||||
// if (min != null) {
|
||||
// if (containMin) {
|
||||
// inner.put("gte", min);
|
||||
// } else {
|
||||
// inner.put("gt", min);
|
||||
// }
|
||||
// }
|
||||
// if (max != null) {
|
||||
// if (containMax) {
|
||||
// inner.put("lte", max);
|
||||
// } else {
|
||||
// inner.put("lt", max);
|
||||
// }
|
||||
// }
|
||||
// JSONObject range = new JSONObject();
|
||||
// range.put(field, inner);
|
||||
// JSONObject json = new JSONObject();
|
||||
// json.put("range", range);
|
||||
// return json;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
@@ -0,0 +1,98 @@
|
||||
//package digital.util.util.es;
|
||||
//
|
||||
///**
|
||||
// * 用于创建 ElasticSearch 的 queryString
|
||||
// *
|
||||
// * @author sunjianlei
|
||||
// */
|
||||
//public class QueryStringBuilder {
|
||||
//
|
||||
// StringBuilder builder;
|
||||
//
|
||||
// public QueryStringBuilder(String field, String str, boolean not, boolean addQuot) {
|
||||
// builder = this.createBuilder(field, str, not, addQuot);
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder(String field, String str, boolean not) {
|
||||
// builder = this.createBuilder(field, str, not, true);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 创建 StringBuilder
|
||||
// *
|
||||
// * @param field
|
||||
// * @param str
|
||||
// * @param not 是否是不匹配
|
||||
// * @param addQuot 是否添加双引号
|
||||
// * @return
|
||||
// */
|
||||
// public StringBuilder createBuilder(String field, String str, boolean not, boolean addQuot) {
|
||||
// StringBuilder sb = new StringBuilder(field).append(":(");
|
||||
// if (not) {
|
||||
// sb.append(" NOT ");
|
||||
// }
|
||||
// this.addQuotEffect(sb, str, addQuot);
|
||||
// return sb;
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder and(String str) {
|
||||
// return this.and(str, true);
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder and(String str, boolean addQuot) {
|
||||
// builder.append(" AND ");
|
||||
// this.addQuot(str, addQuot);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder or(String str) {
|
||||
// return this.or(str, true);
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder or(String str, boolean addQuot) {
|
||||
// builder.append(" OR ");
|
||||
// this.addQuot(str, addQuot);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder not(String str) {
|
||||
// return this.not(str, true);
|
||||
// }
|
||||
//
|
||||
// public QueryStringBuilder not(String str, boolean addQuot) {
|
||||
// builder.append(" NOT ");
|
||||
// this.addQuot(str, addQuot);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 添加双引号(模糊查询,不能加双引号)
|
||||
// */
|
||||
// private QueryStringBuilder addQuot(String str, boolean addQuot) {
|
||||
// return this.addQuotEffect(this.builder, str, addQuot);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 是否在两边加上双引号
|
||||
// * @param builder
|
||||
// * @param str
|
||||
// * @param addQuot
|
||||
// * @return
|
||||
// */
|
||||
// private QueryStringBuilder addQuotEffect(StringBuilder builder, String str, boolean addQuot) {
|
||||
// if (addQuot) {
|
||||
// builder.append('"');
|
||||
// }
|
||||
// builder.append(str);
|
||||
// if (addQuot) {
|
||||
// builder.append('"');
|
||||
// }
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return builder.append(")").toString();
|
||||
// }
|
||||
//
|
||||
//}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package digital.util.exception;
|
||||
|
||||
/**
|
||||
* @Description: smcp自定义401异常
|
||||
* @author: smcp
|
||||
*/
|
||||
public class JeecgBoot401Exception extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JeecgBoot401Exception(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBoot401Exception(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JeecgBoot401Exception(String message, Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package digital.util.exception;
|
||||
|
||||
/**
|
||||
* @Description: smcp自定义异常
|
||||
* @author: smcp
|
||||
*/
|
||||
public class JeecgBootException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JeecgBootException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBootException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JeecgBootException(String message,Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
package digital.util.exception;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
//import org.springframework.data.redis.connection.PoolException;
|
||||
import org.springframework.data.redis.connection.PoolException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
import digital.base.enums.SentinelErrorInfoEnum;
|
||||
import digital.base.vo.Result;
|
||||
|
||||
import javax.xml.bind.ValidationException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*
|
||||
* @Author scott
|
||||
* @Date 2019
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class JeecgBootExceptionHandler {
|
||||
|
||||
//绑普通字符串没绑好异常
|
||||
@ExceptionHandler(BindException.class)
|
||||
public Result handleBindException(BindException e){
|
||||
log.error("参数不匹配",e);
|
||||
//获取参数绑定结果(包括绑定错误信息)
|
||||
BindingResult bindingResult = e.getBindingResult();
|
||||
//获取属性错误集合
|
||||
List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
|
||||
String errMsg = fieldErrorList.stream()
|
||||
.map(fieldError->fieldError.getField()+":"+fieldError.getDefaultMessage())
|
||||
.collect(Collectors.joining(","));
|
||||
return Result.error(errMsg);
|
||||
}
|
||||
/**
|
||||
* 方法参数校验
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
log.error(e.getMessage());
|
||||
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
|
||||
String message = allErrors.stream().map(s -> s.getDefaultMessage()).collect(Collectors.joining(";"));
|
||||
return Result.error(message);
|
||||
}
|
||||
// @ExceptionHandler(BeanPropertyBindingResult.class)
|
||||
// public String handleBeanPropertyBindingResult(BeanPropertyBindingResult exception) {
|
||||
// // 处理BeanPropertyBindingResult异常的逻辑
|
||||
// // 可以获取异常信息、错误码等,并返回一个适当的响应给客户端
|
||||
// return "发生验证错误,请检查输入数据是否符合要求";
|
||||
// }
|
||||
// @ExceptionHandler(BeanPropertyBindingResult.class)
|
||||
// public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
// log.error(e.getMessage());
|
||||
// List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
|
||||
// String message = allErrors.stream().map(s -> s.getDefaultMessage()).collect(Collectors.joining(";"));
|
||||
// return Result.error(message);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* ValidationException
|
||||
*/
|
||||
@ExceptionHandler(ValidationException.class)
|
||||
public Result<?> handleValidationException(ValidationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getCause().getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* ConstraintViolationException
|
||||
*/
|
||||
// @ExceptionHandler(ConstraintViolationException.class)
|
||||
// public Result<?> handleConstraintViolationException(ConstraintViolationException e) {
|
||||
//
|
||||
// Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
|
||||
// if (violations.size() > 0) {
|
||||
// List<String> list = new ArrayList<>();
|
||||
// for (ConstraintViolation<?> violation : violations) {
|
||||
// list.add(violation.getMessage());
|
||||
// }
|
||||
//
|
||||
// if (!list.isEmpty()) {
|
||||
// log.error(list.toString());
|
||||
// return Result.error(list.toString());
|
||||
// }
|
||||
// }
|
||||
// return Result.error(e.getMessage());
|
||||
// }
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBootException.class)
|
||||
public Result<?> handleJeecgBootException(JeecgBootException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义微服务异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgCloudException.class)
|
||||
public Result<?> handleJeecgCloudException(JeecgCloudException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBoot401Exception.class)
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
public Result<?> handleJeecgBoot401Exception(JeecgBoot401Exception e){
|
||||
log.error(e.getMessage(), e);
|
||||
return new Result(401,e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
public Result<?> handlerNoFoundException(Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(404, "路径不存在,请检查路径是否正确");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public Result<?> handleDuplicateKeyException(DuplicateKeyException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("数据库中已存在该记录");
|
||||
}
|
||||
|
||||
@ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
|
||||
public Result<?> handleAuthorizationException(AuthorizationException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.noauth("没有权限,请联系管理员授权");
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result<?> handleException(Exception e){
|
||||
log.error(e.getMessage(), e);
|
||||
//update-begin---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常
|
||||
Throwable throwable = e.getCause();
|
||||
SentinelErrorInfoEnum errorInfoEnum = SentinelErrorInfoEnum.getErrorByException(throwable);
|
||||
if (ObjectUtil.isNotEmpty(errorInfoEnum)) {
|
||||
return Result.error(errorInfoEnum.getError());
|
||||
}
|
||||
//update-end---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常
|
||||
return Result.error("操作失败,"+e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author 政辉
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
public Result<?> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("不支持");
|
||||
sb.append(e.getMethod());
|
||||
sb.append("请求方法,");
|
||||
sb.append("支持以下");
|
||||
String [] methods = e.getSupportedMethods();
|
||||
if(methods!=null){
|
||||
for(String str:methods){
|
||||
sb.append(str);
|
||||
sb.append("、");
|
||||
}
|
||||
}
|
||||
log.error(sb.toString(), e);
|
||||
//return Result.error("没有权限,请联系管理员授权");
|
||||
return Result.error(405,sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
|
||||
*/
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DataIntegrityViolationException.class)
|
||||
public Result<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("字段太长,超出数据库字段的长度");
|
||||
}
|
||||
|
||||
@ExceptionHandler(PoolException.class)
|
||||
public Result<?> handlePoolException(PoolException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("Redis 连接异常!");
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package digital.util.exception;
|
||||
|
||||
/**
|
||||
* @Description: jeecg-cloud自定义异常
|
||||
* @Author: zyf
|
||||
* @Date: 2022-05-30
|
||||
*/
|
||||
public class JeecgCloudException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JeecgCloudException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package digital.util.filter;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @author: lsq
|
||||
* @date: 2021年08月09日 15:29
|
||||
*/
|
||||
public class FileTypeFilter {
|
||||
|
||||
/**文件后缀*/
|
||||
private static String[] forbidType = {"jsp","php"};
|
||||
|
||||
/**初始化文件头类型,不够的自行补充*/
|
||||
final static HashMap<String, String> FILE_TYPE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");
|
||||
FILE_TYPE_MAP.put("3c3f7068700a0a2f2a2a0a202a205048", "php");
|
||||
/* fileTypeMap.put("ffd8ffe000104a464946", "jpg");
|
||||
fileTypeMap.put("89504e470d0a1a0a0000", "png");
|
||||
fileTypeMap.put("47494638396126026f01", "gif");
|
||||
fileTypeMap.put("49492a00227105008037", "tif");
|
||||
fileTypeMap.put("424d228c010000000000", "bmp");
|
||||
fileTypeMap.put("424d8240090000000000", "bmp");
|
||||
fileTypeMap.put("424d8e1b030000000000", "bmp");
|
||||
fileTypeMap.put("41433130313500000000", "dwg");
|
||||
fileTypeMap.put("3c21444f435459504520", "html");
|
||||
fileTypeMap.put("3c21646f637479706520", "htm");
|
||||
fileTypeMap.put("48544d4c207b0d0a0942", "css");
|
||||
fileTypeMap.put("696b2e71623d696b2e71", "js");
|
||||
fileTypeMap.put("7b5c727466315c616e73", "rtf");
|
||||
fileTypeMap.put("38425053000100000000", "psd");
|
||||
fileTypeMap.put("46726f6d3a203d3f6762", "eml");
|
||||
fileTypeMap.put("d0cf11e0a1b11ae10000", "doc");
|
||||
fileTypeMap.put("5374616E64617264204A", "mdb");
|
||||
fileTypeMap.put("252150532D41646F6265", "ps");
|
||||
fileTypeMap.put("255044462d312e350d0a", "pdf");
|
||||
fileTypeMap.put("2e524d46000000120001", "rmvb");
|
||||
fileTypeMap.put("464c5601050000000900", "flv");
|
||||
fileTypeMap.put("00000020667479706d70", "mp4");
|
||||
fileTypeMap.put("49443303000000002176", "mp3");
|
||||
fileTypeMap.put("000001ba210001000180", "mpg");
|
||||
fileTypeMap.put("3026b2758e66cf11a6d9", "wmv");
|
||||
fileTypeMap.put("52494646e27807005741", "wav");
|
||||
fileTypeMap.put("52494646d07d60074156", "avi");
|
||||
fileTypeMap.put("4d546864000000060001", "mid");
|
||||
fileTypeMap.put("504b0304140000000800", "zip");
|
||||
fileTypeMap.put("526172211a0700cf9073", "rar");
|
||||
fileTypeMap.put("235468697320636f6e66", "ini");
|
||||
fileTypeMap.put("504b03040a0000000000", "jar");
|
||||
fileTypeMap.put("4d5a9000030000000400", "exe");
|
||||
fileTypeMap.put("3c25402070616765206c", "jsp");
|
||||
fileTypeMap.put("4d616e69666573742d56", "mf");
|
||||
fileTypeMap.put("3c3f786d6c2076657273", "xml");
|
||||
fileTypeMap.put("494e5345525420494e54", "sql");
|
||||
fileTypeMap.put("7061636b616765207765", "java");
|
||||
fileTypeMap.put("406563686f206f66660d", "bat");
|
||||
fileTypeMap.put("1f8b0800000000000000", "gz");
|
||||
fileTypeMap.put("6c6f67346a2e726f6f74", "properties");
|
||||
fileTypeMap.put("cafebabe0000002e0041", "class");
|
||||
fileTypeMap.put("49545346030000006000", "chm");
|
||||
fileTypeMap.put("04000000010000001300", "mxp");
|
||||
fileTypeMap.put("504b0304140006000800", "docx");
|
||||
fileTypeMap.put("6431303a637265617465", "torrent");
|
||||
fileTypeMap.put("6D6F6F76", "mov");
|
||||
fileTypeMap.put("FF575043", "wpd");
|
||||
fileTypeMap.put("CFAD12FEC5FD746F", "dbx");
|
||||
fileTypeMap.put("2142444E", "pst");
|
||||
fileTypeMap.put("AC9EBD8F", "qdf");
|
||||
fileTypeMap.put("E3828596", "pwl");
|
||||
fileTypeMap.put("2E7261FD", "ram");*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName
|
||||
* @return String
|
||||
* @description 通过文件后缀名获取文件类型
|
||||
*/
|
||||
private static String getFileTypeBySuffix(String fileName) {
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件类型过滤
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public static void fileTypeFilter(MultipartFile file) throws Exception {
|
||||
String suffix = getFileType(file);
|
||||
for (String type : forbidType) {
|
||||
if (type.contains(suffix)) {
|
||||
throw new Exception("上传失败,文件类型异常:" + suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过读取文件头部获得文件类型
|
||||
*
|
||||
* @param file
|
||||
* @return 文件类型
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
private static String getFileType(MultipartFile file) throws Exception {
|
||||
String fileExtendName = null;
|
||||
InputStream is;
|
||||
try {
|
||||
//is = new FileInputStream(file);
|
||||
is = file.getInputStream();
|
||||
byte[] b = new byte[10];
|
||||
is.read(b, 0, b.length);
|
||||
String fileTypeHex = String.valueOf(bytesToHexString(b));
|
||||
Iterator<String> keyIter = FILE_TYPE_MAP.keySet().iterator();
|
||||
while (keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
// 验证前5个字符比较
|
||||
if (key.toLowerCase().startsWith(fileTypeHex.toLowerCase().substring(0, 5))
|
||||
|| fileTypeHex.toLowerCase().substring(0, 5).startsWith(key.toLowerCase())) {
|
||||
fileExtendName = FILE_TYPE_MAP.get(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 如果不是上述类型,则判断扩展名
|
||||
if (StringUtils.isBlank(fileExtendName)) {
|
||||
String fileName = file.getOriginalFilename();
|
||||
return getFileTypeBySuffix(fileName);
|
||||
}
|
||||
is.close();
|
||||
return fileExtendName;
|
||||
} catch (Exception exception) {
|
||||
throw new Exception(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件头部字符串
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
private static String bytesToHexString(byte[] src) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (src == null || src.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
int v = src[i] & 0xFF;
|
||||
String hv = Integer.toHexString(v);
|
||||
if (hv.length() < 2) {
|
||||
stringBuilder.append(0);
|
||||
}
|
||||
stringBuilder.append(hv);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package digital.util.filter;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* 文件上传字符串过滤特殊字符
|
||||
* @author: smcp
|
||||
*/
|
||||
public class StrAttackFilter {
|
||||
|
||||
public static String filter(String str) throws PatternSyntaxException {
|
||||
// 清除掉所有特殊字符
|
||||
String regEx = "[`_《》~!@#$%^&*()+=|{}':;',\\[\\].<>?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
|
||||
Pattern p = Pattern.compile(regEx);
|
||||
Matcher m = p.matcher(str);
|
||||
return m.replaceAll("").trim();
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// String filter = filter("@#jeecg/《》【bo】¥%……&*(o))))!@t<>,.,/?'\'~~`");
|
||||
// System.out.println(filter);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,655 @@
|
||||
package digital.util.oss;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.oss.*;
|
||||
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
|
||||
import com.aliyun.oss.common.comm.Protocol;
|
||||
import com.aliyun.oss.common.utils.BinaryUtil;
|
||||
import com.aliyun.oss.model.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.tomcat.util.http.fileupload.FileItemStream;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import digital.base.vo.LoginUser;
|
||||
import digital.util.util.CommonUtils;
|
||||
import digital.util.util.oConvertUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Description: 阿里云 oss 上传工具类(高依赖版)
|
||||
* @Date: 2019/5/10
|
||||
*/
|
||||
@Slf4j
|
||||
public class OssBootUtil {
|
||||
|
||||
private static String endPoint;
|
||||
private static String accessKeyId;
|
||||
private static String accessKeySecret;
|
||||
private static String bucketName;
|
||||
private static String staticDomain;
|
||||
private static String callBackUrl;
|
||||
|
||||
public static void setEndPoint(String endPoint) {
|
||||
OssBootUtil.endPoint = endPoint;
|
||||
}
|
||||
|
||||
public static void setAccessKeyId(String accessKeyId) {
|
||||
OssBootUtil.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
public static void setAccessKeySecret(String accessKeySecret) {
|
||||
OssBootUtil.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
public static void setBucketName(String bucketName) {
|
||||
OssBootUtil.bucketName = bucketName;
|
||||
}
|
||||
|
||||
public static void setStaticDomain(String staticDomain) {
|
||||
OssBootUtil.staticDomain = staticDomain;
|
||||
}
|
||||
|
||||
public static String getStaticDomain() {
|
||||
return staticDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* oss 工具客户端
|
||||
*/
|
||||
private static OSSClient ossClient = null;
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
* 文件上传成功,返回文件完整访问路径
|
||||
* 文件上传失败,返回 null
|
||||
*
|
||||
* @param file 待上传文件
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String uploadOssKsf(MultipartFile file, String fileDir,String customBucket) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = UserUtil.getId() + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
|
||||
return fileUrl.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
* 文件上传成功,返回文件完整访问路径
|
||||
* 文件上传失败,返回 null
|
||||
*
|
||||
* @param file 待上传文件
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String uploadOssKsf(File file, String fileDir, String customBucket) {
|
||||
return uploadOssKsf(file,fileDir,customBucket,"");
|
||||
}
|
||||
|
||||
public static String uploadOssVideo(File file, String fileDir,String newFileName) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getName();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = newFileName;
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), FileUtil.getInputStream(file));
|
||||
// 设置权限(公开读)
|
||||
ossClient.setObjectAcl(newBucket,fileUrl.toString(), CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
// log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
return fileUrl.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
* 文件上传成功,返回文件完整访问路径
|
||||
* 文件上传失败,返回 null
|
||||
*
|
||||
* @param file 待上传文件
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String uploadOssKsf(File file, String fileDir, String customBucket,String preFix) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getName();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = preFix+UserUtil.getId() + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), FileUtil.getInputStream(file));
|
||||
return fileUrl.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String uploadOssMat(MultipartFile file, String fileDir,String customBucket,String newFileName) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
|
||||
return fileUrl.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
* 文件上传成功,返回文件完整访问路径
|
||||
* 文件上传失败,返回 null
|
||||
*
|
||||
* @param file 待上传文件
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String uploadOssMed(MultipartFile file, String fileDir,String customBucket) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
|
||||
return fileUrl.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String uploadOssVideo(MultipartFile file, String fileDir,String customBucket) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getName();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
|
||||
return fileUrl.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
* 文件上传成功,返回文件完整访问路径
|
||||
* 文件上传失败,返回 null
|
||||
*
|
||||
* @param file 待上传文件
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String upload(MultipartFile file, String fileDir,String customBucket) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
|
||||
// 设置权限(公开读)
|
||||
ossClient.setObjectAcl(newBucket,fileUrl.toString(), CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
// log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return FILE_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param file
|
||||
* @param fileDir
|
||||
* @return
|
||||
*/
|
||||
public static String upload(MultipartFile file, String fileDir) {
|
||||
return upload(file, fileDir,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
* 文件上传成功,返回文件完整访问路径
|
||||
* 文件上传失败,返回 null
|
||||
*
|
||||
* @param file 待上传文件
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String upload(FileItemStream file, String fileDir) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
try {
|
||||
String suffix = file.getName().substring(file.getName().lastIndexOf('.'));
|
||||
String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
fileUrl = fileUrl.append(fileDir + fileName);
|
||||
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.openStream());
|
||||
// 设置权限(公开读)
|
||||
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
// log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return FILE_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param url
|
||||
*/
|
||||
public static void deleteUrl(String url) {
|
||||
deleteUrl(url,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param url
|
||||
*/
|
||||
public static void deleteUrl(String url,String bucket) {
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(bucket)){
|
||||
newBucket = bucket;
|
||||
}
|
||||
String bucketUrl = "";
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
bucketUrl = staticDomain + "/" ;
|
||||
} else {
|
||||
bucketUrl = "https://" + newBucket + "." + endPoint + "/";
|
||||
}
|
||||
url = url.replace(bucketUrl,"");
|
||||
ossClient.deleteObject(newBucket, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param fileName
|
||||
*/
|
||||
public static void delete(String fileName) {
|
||||
ossClient.deleteObject(bucketName, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件流
|
||||
* @param objectName
|
||||
* @param bucket
|
||||
* @return
|
||||
*/
|
||||
public static InputStream getOssFile(String objectName,String bucket){
|
||||
InputStream inputStream = null;
|
||||
try{
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(bucket)){
|
||||
newBucket = bucket;
|
||||
}
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
// initOSS("oss-accelerate.aliyuncs.com", "LTAI5tFigifExsV2BxWYCyd1", "khvitMKIOMDehLf7QouuZATgcDl75k");
|
||||
OSSObject ossObject = ossClient.getObject(newBucket,objectName);
|
||||
inputStream = new BufferedInputStream(ossObject.getObjectContent());
|
||||
}catch (Exception e){
|
||||
log.info("文件获取失败" + e.getMessage());
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件流
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public static InputStream getOssFile(String objectName){
|
||||
return getOssFile(objectName,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件外链
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @param expires
|
||||
* @return
|
||||
*/
|
||||
// public static String getObjectURL(String bucketName, String objectName, Date expires) {
|
||||
// initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
// try{
|
||||
// if(ossClient.doesObjectExist(bucketName,objectName)){
|
||||
// URL url = ossClient.generatePresignedUrl(bucketName,objectName,expires);
|
||||
// String urlString="";
|
||||
// urlString = url.toString().replace("http://"+bucketName+"."+endPoint,staticDomain);
|
||||
// urlString = urlString.toString().replace("https://"+bucketName+"."+endPoint,staticDomain);
|
||||
// return urlString;
|
||||
// }
|
||||
// }catch (Exception e){
|
||||
// log.info("文件路径获取失败" + e.getMessage());
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取文件外链
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @param expires
|
||||
* @return
|
||||
*/
|
||||
public static String getObjectURL(String bucketName, String objectName, Date expires) {
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
try{
|
||||
if(ossClient.doesObjectExist(bucketName,objectName)){
|
||||
// 设置URL过期时间为10年 3600l* 1000*24*365*10
|
||||
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 20);
|
||||
URL url = ossClient.generatePresignedUrl(bucketName,objectName,expiration);
|
||||
String urlString="";
|
||||
urlString = url.toString().replace("http://"+bucketName+"."+endPoint,staticDomain);
|
||||
urlString = urlString.toString().replace("https://"+bucketName+"."+endPoint,staticDomain);
|
||||
return urlString;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.info("文件路径获取失败" + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDigitalObjectURL(String bucketName, String objectName, Date expires) {
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
try{
|
||||
if(ossClient.doesObjectExist(bucketName,objectName)){
|
||||
// 设置URL过期时间为10年 3600l* 1000*24*365*10
|
||||
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 20);
|
||||
URL url = ossClient.generatePresignedUrl(bucketName,objectName,expiration);
|
||||
String urlString=staticDomain+"/"+objectName;
|
||||
// String urlString="";
|
||||
// urlString = url.toString().replace("http://"+bucketName+"."+endPoint,staticDomain);
|
||||
// urlString = urlString.toString().replace("https://"+bucketName+"."+endPoint,staticDomain);
|
||||
return urlString;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.info("文件路径获取失败" + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getObjectThumbnailURL(String bucketName, String objectName) {
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
try {
|
||||
if (ossClient.doesObjectExist(bucketName, objectName)) {
|
||||
String style = "image/resize,h_250,m_lfit";
|
||||
GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
|
||||
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 20);
|
||||
req.setExpiration(expiration);
|
||||
req.setProcess(style);
|
||||
String urlString = "";
|
||||
URL signedUrl = ossClient.generatePresignedUrl(req);
|
||||
urlString = signedUrl.toString().replace("http://" + bucketName + "." + endPoint, staticDomain);
|
||||
urlString = urlString.toString().replace("https://" + bucketName + "." + endPoint, staticDomain);
|
||||
return urlString;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.info("文件路径获取失败" + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 oss 客户端
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static OSSClient initOSS(String endpoint, String accessKeyId, String accessKeySecret) {
|
||||
if (ossClient == null) {
|
||||
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
||||
clientConfiguration.setProtocol(Protocol.HTTPS);
|
||||
ossClient = new OSSClient(endpoint,
|
||||
new DefaultCredentialProvider(accessKeyId, accessKeySecret),clientConfiguration
|
||||
);
|
||||
}
|
||||
return ossClient;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到oss
|
||||
* @param stream
|
||||
* @param relativePath
|
||||
* @return
|
||||
*/
|
||||
public static String upload(InputStream stream, String relativePath) {
|
||||
String FILE_URL = null;
|
||||
String fileUrl = relativePath;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + relativePath;
|
||||
} else {
|
||||
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(bucketName, relativePath,stream);
|
||||
// 设置权限(公开读)
|
||||
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
// log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
return FILE_URL;
|
||||
}
|
||||
|
||||
|
||||
public static void setCallBackUrl(String callBackUrl) {
|
||||
OssBootUtil.callBackUrl = callBackUrl;
|
||||
}
|
||||
|
||||
public static String getCallBackUrl() {
|
||||
return callBackUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* // String accessId = "LTAI5tRWhHy73uXBWHgcsC69"; // 请填写您的AccessKeyId。
|
||||
* // String accessKey = "qNepcIbYfWTLoQnCgOh8388cUVMZQ6"; // 请填写您的AccessKeySecret。
|
||||
* // String endpoint = "oss-cn-beijing.aliyuncs.com"; // 请填写您的 endpoint。
|
||||
* // String bucket = "hnmedicineoss"; // 请填写您的 bucketname 。
|
||||
* // String host = "http://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
|
||||
* // // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
|
||||
* // String callbackUrl = "https://hnmedicine.crabholder.cn/claimbyself/insurance/user/v1/doCallBackOss";
|
||||
*
|
||||
|
||||
* @param dir
|
||||
* @param fileName
|
||||
* @return
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public static Map<String, String> getStatsToken(String dir, String fileName) throws UnsupportedEncodingException {
|
||||
OSSClient client = initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
long expireTime = 300;
|
||||
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
|
||||
java.sql.Date expiration = new java.sql.Date(expireEndTime);
|
||||
PolicyConditions policyConds = new PolicyConditions();
|
||||
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
|
||||
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
|
||||
String postPolicy = client.generatePostPolicy(expiration, policyConds);
|
||||
byte[] binaryData = postPolicy.getBytes("utf-8");
|
||||
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
|
||||
String postSignature = client.calculatePostSignature(postPolicy);
|
||||
Map<String, String> respMap = new LinkedHashMap<String, String>();
|
||||
respMap.put("accessKeyId", accessKeyId);
|
||||
respMap.put("policy", encodedPolicy);
|
||||
respMap.put("signature", postSignature);
|
||||
respMap.put("dir", dir);
|
||||
respMap.put("host", staticDomain);
|
||||
respMap.put("expire", String.valueOf(expireEndTime / 1000));
|
||||
// respMap.put("expire", formatISO8601Date(expiration));
|
||||
JSONObject jasonCallback = new JSONObject();
|
||||
jasonCallback.put("callbackUrl", callBackUrl);
|
||||
jasonCallback.put("callbackBody",
|
||||
"ossFilePath=${object}&object=${object}&size=${size}&mimeType=${mimeType}&height=" +
|
||||
"${imageInfo.height}&width=${imageInfo.width}&fileType=1&fileName="+fileName+"&userId="+loginUser.getId());
|
||||
jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
|
||||
String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
|
||||
respMap.put("callback", base64CallbackBody);
|
||||
return respMap;
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package digital.util.oss;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.PutObjectRequest;
|
||||
|
||||
public class OssUploadWithThirdPartySTS {
|
||||
public static void main(String[] args) {
|
||||
// 第三方STS提供的临时凭证信息
|
||||
String tempAccessKeyId = "临时AccessKeyId";
|
||||
String tempAccessKeySecret = "临时AccessKeySecret";
|
||||
String securityToken = "安全令牌Token";
|
||||
String ossEndpoint = "OSS的Endpoint"; // 例如:oss-cn-hangzhou.aliyuncs.com
|
||||
String ossBucketName = "你的OSS Bucket名称";
|
||||
|
||||
|
||||
|
||||
System.out.println("文件上传成功!");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package digital.util.oss;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import digital.base.vo.LoginUser;
|
||||
|
||||
/**
|
||||
* U CAN GET A CRAB WHEN U MEET US!
|
||||
* IF GET A QUESTION,PLEASE CONTACT US:
|
||||
* WEBSITE: www.crabholder.cn www.crabholder.com
|
||||
* EMAIL:crabholder@163.com.
|
||||
* CREATED ON 2020/7/13!
|
||||
*/
|
||||
public class UserUtil {
|
||||
public static LoginUser getLoginUser() {
|
||||
return (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
}
|
||||
public static String getId() {
|
||||
return ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getId();
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
package digital.util.security;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 查询表/字段 黑名单处理
|
||||
* @Author taoYan
|
||||
* @Date 2022/3/17 11:21
|
||||
**/
|
||||
@Slf4j
|
||||
public abstract class AbstractQueryBlackListHandler {
|
||||
|
||||
/**
|
||||
* key-表名
|
||||
* value-字段名,多个逗号隔开
|
||||
* 两种配置方式-- 全部配置成小写
|
||||
* ruleMap.put("sys_user", "*")sys_user所有的字段不支持查询
|
||||
* ruleMap.put("sys_user", "username,password")sys_user中的username和password不支持查询
|
||||
*/
|
||||
public static Map<String, String> ruleMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
ruleMap.put("sys_user", "password,salt");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 sql语句 获取表和字段信息,需要到具体的实现类重写此方法-
|
||||
* 不同的场景 处理可能不太一样 需要自定义,但是返回值确定
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
protected abstract List<QueryTable> getQueryTableInfo(String sql);
|
||||
|
||||
|
||||
/**
|
||||
* 校验sql语句 成功返回true
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
public boolean isPass(String sql) {
|
||||
List<QueryTable> list = this.getQueryTableInfo(sql.toLowerCase());
|
||||
if(list==null){
|
||||
return true;
|
||||
}
|
||||
log.info("--获取sql信息--", list.toString());
|
||||
boolean flag = true;
|
||||
for (QueryTable table : list) {
|
||||
String name = table.getName();
|
||||
String fieldString = ruleMap.get(name);
|
||||
// 有没有配置这张表
|
||||
if (fieldString != null) {
|
||||
if ("*".equals(fieldString) || table.isAll()) {
|
||||
flag = false;
|
||||
log.warn("sql黑名单校验,表【"+name+"】禁止查询");
|
||||
break;
|
||||
} else if (table.existSameField(fieldString)) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询的表的信息
|
||||
*/
|
||||
protected class QueryTable {
|
||||
//表名
|
||||
private String name;
|
||||
//表的别名
|
||||
private String alias;
|
||||
// 字段名集合
|
||||
private Set<String> fields;
|
||||
// 是否查询所有字段
|
||||
private boolean all;
|
||||
|
||||
public QueryTable() {
|
||||
}
|
||||
|
||||
public QueryTable(String name, String alias) {
|
||||
this.name = name;
|
||||
this.alias = alias;
|
||||
this.all = false;
|
||||
this.fields = new HashSet<>();
|
||||
}
|
||||
|
||||
public void addField(String field) {
|
||||
this.fields.add(field);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Set<String> getFields() {
|
||||
return new HashSet<>(fields);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setFields(Set<String> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public boolean isAll() {
|
||||
return all;
|
||||
}
|
||||
|
||||
public void setAll(boolean all) {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有相同字段
|
||||
*
|
||||
* @param fieldString
|
||||
* @return
|
||||
*/
|
||||
public boolean existSameField(String fieldString) {
|
||||
String[] arr = fieldString.split(",");
|
||||
for (String exp : fields) {
|
||||
for (String config : arr) {
|
||||
if (exp.equals(config)) {
|
||||
// 非常明确的列直接比较
|
||||
log.warn("sql黑名单校验,表【"+name+"】中字段【"+config+"】禁止查询");
|
||||
return true;
|
||||
} else {
|
||||
// 使用表达式的列 只能判读字符串包含了
|
||||
String aliasColumn = config;
|
||||
if (alias != null && alias.length() > 0) {
|
||||
aliasColumn = alias + "." + config;
|
||||
}
|
||||
if (exp.indexOf(aliasColumn) > 0) {
|
||||
log.warn("sql黑名单校验,表【"+name+"】中字段【"+config+"】禁止查询");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryTable{" +
|
||||
"name='" + name + '\'' +
|
||||
", alias='" + alias + '\'' +
|
||||
", fields=" + fields +
|
||||
", all=" + all +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public String getError(){
|
||||
// TODO
|
||||
return "sql黑名单校验不通过,请联系管理员!";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package digital.util.security;
|
||||
|
||||
import cn.hutool.core.codec.Base64Decoder;
|
||||
import cn.hutool.core.codec.Base64Encoder;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.asymmetric.KeyType;
|
||||
import cn.hutool.crypto.asymmetric.RSA;
|
||||
import cn.hutool.crypto.asymmetric.Sign;
|
||||
import cn.hutool.crypto.asymmetric.SignAlgorithm;
|
||||
import cn.hutool.crypto.symmetric.AES;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import digital.util.security.entity.*;
|
||||
import digital.util.security.entity.*;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.KeyPair;
|
||||
|
||||
/**
|
||||
* @Description: SecurityTools
|
||||
* @author: smcp
|
||||
*/
|
||||
public class SecurityTools {
|
||||
public static final String ALGORITHM = "AES/ECB/PKCS5Padding";
|
||||
|
||||
public static SecurityResp valid(SecurityReq req) {
|
||||
SecurityResp resp=new SecurityResp();
|
||||
String pubKey=req.getPubKey();
|
||||
String aesKey=req.getAesKey();
|
||||
String data=req.getData();
|
||||
String signData=req.getSignData();
|
||||
RSA rsa=new RSA(null, Base64Decoder.decode(pubKey));
|
||||
Sign sign= new Sign(SignAlgorithm.SHA1withRSA,null,pubKey);
|
||||
|
||||
|
||||
|
||||
byte[] decryptAes = rsa.decrypt(aesKey, KeyType.PublicKey);
|
||||
//log.info("rsa解密后的秘钥"+ Base64Encoder.encode(decryptAes));
|
||||
AES aes = SecureUtil.aes(decryptAes);
|
||||
|
||||
String dencrptValue =aes.decryptStr(data);
|
||||
//log.info("解密后报文"+dencrptValue);
|
||||
resp.setData(JSONObject.parseObject(dencrptValue));
|
||||
|
||||
boolean verify = sign.verify(dencrptValue.getBytes(), Base64Decoder.decode(signData));
|
||||
resp.setSuccess(verify);
|
||||
return resp;
|
||||
}
|
||||
|
||||
public static SecuritySignResp sign(SecuritySignReq req) {
|
||||
SecretKey secretKey = SecureUtil.generateKey(ALGORITHM);
|
||||
byte[] key= secretKey.getEncoded();
|
||||
String prikey=req.getPrikey();
|
||||
String data=req.getData();
|
||||
|
||||
AES aes = SecureUtil.aes(key);
|
||||
aes.getSecretKey().getEncoded();
|
||||
String encrptData =aes.encryptBase64(data);
|
||||
RSA rsa=new RSA(prikey,null);
|
||||
byte[] encryptAesKey = rsa.encrypt(secretKey.getEncoded(), KeyType.PrivateKey);
|
||||
//log.info(("rsa加密过的秘钥=="+Base64Encoder.encode(encryptAesKey));
|
||||
|
||||
Sign sign= new Sign(SignAlgorithm.SHA1withRSA,prikey,null);
|
||||
byte[] signed = sign.sign(data.getBytes());
|
||||
|
||||
//log.info(("签名数据===》》"+Base64Encoder.encode(signed));
|
||||
|
||||
SecuritySignResp resp=new SecuritySignResp();
|
||||
resp.setAesKey(Base64Encoder.encode(encryptAesKey));
|
||||
resp.setData(encrptData);
|
||||
resp.setSignData(Base64Encoder.encode(signed));
|
||||
return resp;
|
||||
}
|
||||
public static MyKeyPair generateKeyPair(){
|
||||
KeyPair keyPair= SecureUtil.generateKeyPair(SignAlgorithm.SHA1withRSA.getValue(),2048);
|
||||
String priKey= Base64Encoder.encode(keyPair.getPrivate().getEncoded());
|
||||
String pubkey= Base64Encoder.encode(keyPair.getPublic().getEncoded());
|
||||
MyKeyPair resp=new MyKeyPair();
|
||||
resp.setPriKey(priKey);
|
||||
resp.setPubKey(pubkey);
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package digital.util.security.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: MyKeyPair
|
||||
* @author: smcp
|
||||
*/
|
||||
@Data
|
||||
public class MyKeyPair {
|
||||
private String priKey;
|
||||
private String pubKey;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package digital.util.security.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: SecurityReq
|
||||
* @author: smcp
|
||||
*/
|
||||
@Data
|
||||
public class SecurityReq {
|
||||
private String data;
|
||||
private String pubKey;
|
||||
private String signData;
|
||||
private String aesKey;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package digital.util.security.entity;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: SecurityResp
|
||||
* @author: smcp
|
||||
*/
|
||||
@Data
|
||||
public class SecurityResp {
|
||||
private Boolean success;
|
||||
private JSONObject data;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package digital.util.security.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: SecuritySignReq
|
||||
* @author: smcp
|
||||
*/
|
||||
@Data
|
||||
public class SecuritySignReq {
|
||||
private String data;
|
||||
private String prikey;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package digital.util.security.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: SecuritySignResp
|
||||
* @author: smcp
|
||||
*/
|
||||
@Data
|
||||
public class SecuritySignResp {
|
||||
private String data;
|
||||
private String signData;
|
||||
private String aesKey;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//package org.jeecg.common.util.superSearch;
|
||||
//
|
||||
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
//
|
||||
///**
|
||||
// * 判断类型,追加查询规则
|
||||
// *
|
||||
// * @Author Scott
|
||||
// * @Date 2019年02月14日
|
||||
// */
|
||||
//public class ObjectParseUtil {
|
||||
//
|
||||
// /**
|
||||
// *
|
||||
// * @param queryWrapper QueryWrapper
|
||||
// * @param name 字段名字
|
||||
// * @param rule 查询规则
|
||||
// * @param value 查询条件值
|
||||
// */
|
||||
// public static void addCriteria(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
|
||||
// if (value == null || rule == null) {
|
||||
// return;
|
||||
// }
|
||||
// switch (rule) {
|
||||
// case GT:
|
||||
// queryWrapper.gt(name, value);
|
||||
// break;
|
||||
// case GE:
|
||||
// queryWrapper.ge(name, value);
|
||||
// break;
|
||||
// case LT:
|
||||
// queryWrapper.lt(name, value);
|
||||
// break;
|
||||
// case LE:
|
||||
// queryWrapper.le(name, value);
|
||||
// break;
|
||||
// case EQ:
|
||||
// queryWrapper.eq(name, value);
|
||||
// break;
|
||||
// case NE:
|
||||
// queryWrapper.ne(name, value);
|
||||
// break;
|
||||
// case IN:
|
||||
// queryWrapper.in(name, (Object[]) value);
|
||||
// break;
|
||||
// case LIKE:
|
||||
// queryWrapper.like(name, value);
|
||||
// break;
|
||||
// case LEFT_LIKE:
|
||||
// queryWrapper.likeLeft(name, value);
|
||||
// break;
|
||||
// case RIGHT_LIKE:
|
||||
// queryWrapper.likeRight(name, value);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,71 @@
|
||||
//package org.jeecg.common.util.superSearch;
|
||||
//
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * Query 规则 常量
|
||||
// * @Author Scott
|
||||
// * @Date 2019年02月14日
|
||||
// */
|
||||
//public enum QueryRuleEnum {
|
||||
//
|
||||
// /**查询规则 大于*/
|
||||
// GT(">","大于"),
|
||||
// /**查询规则 大于等于*/
|
||||
// GE(">=","大于等于"),
|
||||
// /**查询规则 小于*/
|
||||
// LT("<","小于"),
|
||||
// /**查询规则 小于等于*/
|
||||
// LE("<=","小于等于"),
|
||||
// /**查询规则 等于*/
|
||||
// EQ("=","等于"),
|
||||
// /**查询规则 不等于*/
|
||||
// NE("!=","不等于"),
|
||||
// /**查询规则 包含*/
|
||||
// IN("IN","包含"),
|
||||
// /**查询规则 全模糊*/
|
||||
// LIKE("LIKE","全模糊"),
|
||||
// /**查询规则 左模糊*/
|
||||
// LEFT_LIKE("LEFT_LIKE","左模糊"),
|
||||
// /**查询规则 右模糊*/
|
||||
// RIGHT_LIKE("RIGHT_LIKE","右模糊"),
|
||||
// /**查询规则 自定义SQL片段*/
|
||||
// SQL_RULES("EXTEND_SQL","自定义SQL片段");
|
||||
//
|
||||
// private String value;
|
||||
//
|
||||
// private String msg;
|
||||
//
|
||||
// QueryRuleEnum(String value, String msg){
|
||||
// this.value = value;
|
||||
// this.msg = msg;
|
||||
// }
|
||||
//
|
||||
// public String getValue() {
|
||||
// return value;
|
||||
// }
|
||||
//
|
||||
// public void setValue(String value) {
|
||||
// this.value = value;
|
||||
// }
|
||||
//
|
||||
// public String getMsg() {
|
||||
// return msg;
|
||||
// }
|
||||
//
|
||||
// public void setMsg(String msg) {
|
||||
// this.msg = msg;
|
||||
// }
|
||||
//
|
||||
// public static QueryRuleEnum getByValue(String value){
|
||||
// if(oConvertUtils.isEmpty(value)) {
|
||||
// return null;
|
||||
// }
|
||||
// for(QueryRuleEnum val :values()){
|
||||
// if (val.getValue().equals(value)){
|
||||
// return val;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,15 @@
|
||||
//package org.jeecg.common.util.superSearch;
|
||||
//
|
||||
//import lombok.Data;
|
||||
//
|
||||
///**
|
||||
// * @Description: QueryRuleVo
|
||||
// * @author: smcp
|
||||
// */
|
||||
//@Data
|
||||
//public class QueryRuleVo {
|
||||
//
|
||||
// private String field;
|
||||
// private String rule;
|
||||
// private String val;
|
||||
//}
|
||||
@@ -0,0 +1,13 @@
|
||||
package digital.util.util;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Author 张代浩
|
||||
*
|
||||
*/
|
||||
public enum BrowserType {
|
||||
/**
|
||||
* 浏览类型 IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko
|
||||
*/
|
||||
IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package digital.util.util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Author 张代浩
|
||||
*
|
||||
*/
|
||||
public class BrowserUtils {
|
||||
|
||||
/**
|
||||
* 判断是否是IE
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static boolean isIe(HttpServletRequest request) {
|
||||
return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request
|
||||
.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取IE版本
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static Double getIeVersion(HttpServletRequest request) {
|
||||
Double version = 0.0;
|
||||
if (getBrowserType(request, IE11)) {
|
||||
version = 11.0;
|
||||
} else if (getBrowserType(request, IE10)) {
|
||||
version = 10.0;
|
||||
} else if (getBrowserType(request, IE9)) {
|
||||
version = 9.0;
|
||||
} else if (getBrowserType(request, IE8)) {
|
||||
version = 8.0;
|
||||
} else if (getBrowserType(request, IE7)) {
|
||||
version = 7.0;
|
||||
} else if (getBrowserType(request, IE6)) {
|
||||
version = 6.0;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取浏览器类型
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static BrowserType getBrowserType(HttpServletRequest request) {
|
||||
BrowserType browserType = null;
|
||||
if (getBrowserType(request, IE11)) {
|
||||
browserType = BrowserType.IE11;
|
||||
}
|
||||
if (getBrowserType(request, IE10)) {
|
||||
browserType = BrowserType.IE10;
|
||||
}
|
||||
if (getBrowserType(request, IE9)) {
|
||||
browserType = BrowserType.IE9;
|
||||
}
|
||||
if (getBrowserType(request, IE8)) {
|
||||
browserType = BrowserType.IE8;
|
||||
}
|
||||
if (getBrowserType(request, IE7)) {
|
||||
browserType = BrowserType.IE7;
|
||||
}
|
||||
if (getBrowserType(request, IE6)) {
|
||||
browserType = BrowserType.IE6;
|
||||
}
|
||||
if (getBrowserType(request, FIREFOX)) {
|
||||
browserType = BrowserType.Firefox;
|
||||
}
|
||||
if (getBrowserType(request, SAFARI)) {
|
||||
browserType = BrowserType.Safari;
|
||||
}
|
||||
if (getBrowserType(request, CHROME)) {
|
||||
browserType = BrowserType.Chrome;
|
||||
}
|
||||
if (getBrowserType(request, OPERA)) {
|
||||
browserType = BrowserType.Opera;
|
||||
}
|
||||
if (getBrowserType(request, CAMINO)) {
|
||||
browserType = BrowserType.Camino;
|
||||
}
|
||||
return browserType;
|
||||
}
|
||||
|
||||
private static boolean getBrowserType(HttpServletRequest request,
|
||||
String brosertype) {
|
||||
return request.getHeader("USER-AGENT").toLowerCase()
|
||||
.indexOf(brosertype) > 0 ? true : false;
|
||||
}
|
||||
|
||||
private final static String IE11 = "rv:11.0";
|
||||
private final static String IE10 = "MSIE 10.0";
|
||||
private final static String IE9 = "MSIE 9.0";
|
||||
private final static String IE8 = "MSIE 8.0";
|
||||
private final static String IE7 = "MSIE 7.0";
|
||||
private final static String IE6 = "MSIE 6.0";
|
||||
private final static String MAXTHON = "Maxthon";
|
||||
private final static String QQ = "QQBrowser";
|
||||
private final static String GREEN = "GreenBrowser";
|
||||
private final static String SE360 = "360SE";
|
||||
private final static String FIREFOX = "Firefox";
|
||||
private final static String OPERA = "Opera";
|
||||
private final static String CHROME = "Chrome";
|
||||
private final static String SAFARI = "Safari";
|
||||
private final static String OTHER = "其它";
|
||||
private final static String CAMINO = "Camino";
|
||||
|
||||
public static String checkBrowse(HttpServletRequest request) {
|
||||
String userAgent = request.getHeader("USER-AGENT");
|
||||
if (regex(OPERA, userAgent)) {
|
||||
return OPERA;
|
||||
}
|
||||
if (regex(CHROME, userAgent)) {
|
||||
return CHROME;
|
||||
}
|
||||
if (regex(FIREFOX, userAgent)) {
|
||||
return FIREFOX;
|
||||
}
|
||||
if (regex(SAFARI, userAgent)) {
|
||||
return SAFARI;
|
||||
}
|
||||
if (regex(SE360, userAgent)) {
|
||||
return SE360;
|
||||
}
|
||||
if (regex(GREEN, userAgent)) {
|
||||
return GREEN;
|
||||
}
|
||||
if (regex(QQ, userAgent)) {
|
||||
return QQ;
|
||||
}
|
||||
if (regex(MAXTHON, userAgent)) {
|
||||
return MAXTHON;
|
||||
}
|
||||
if (regex(IE11, userAgent)) {
|
||||
return IE11;
|
||||
}
|
||||
if (regex(IE10, userAgent)) {
|
||||
return IE10;
|
||||
}
|
||||
if (regex(IE9, userAgent)) {
|
||||
return IE9;
|
||||
}
|
||||
if (regex(IE8, userAgent)) {
|
||||
return IE8;
|
||||
}
|
||||
if (regex(IE7, userAgent)) {
|
||||
return IE7;
|
||||
}
|
||||
if (regex(IE6, userAgent)) {
|
||||
return IE6;
|
||||
}
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
public static boolean regex(String regex, String str) {
|
||||
Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
|
||||
Matcher m = p.matcher(str);
|
||||
return m.find();
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, String> langMap = new HashMap<String, String>();
|
||||
private final static String ZH = "zh";
|
||||
private final static String ZH_CN = "zh-cn";
|
||||
|
||||
private final static String EN = "en";
|
||||
private final static String EN_US = "en";
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
langMap.put(ZH, ZH_CN);
|
||||
langMap.put(EN, EN_US);
|
||||
}
|
||||
|
||||
public static String getBrowserLanguage(HttpServletRequest request) {
|
||||
|
||||
String browserLang = request.getLocale().getLanguage();
|
||||
String browserLangCode = (String)langMap.get(browserLang);
|
||||
|
||||
if(browserLangCode == null)
|
||||
{
|
||||
browserLangCode = EN_US;
|
||||
}
|
||||
return browserLangCode;
|
||||
}
|
||||
|
||||
/** 判断请求是否来自电脑端 */
|
||||
public static boolean isDesktop(HttpServletRequest request) {
|
||||
return !isMobile(request);
|
||||
}
|
||||
|
||||
/** 判断请求是否来自移动端 */
|
||||
public static boolean isMobile(HttpServletRequest request) {
|
||||
String ua = request.getHeader("User-Agent").toLowerCase();
|
||||
String type = "(phone|pad|pod|iphone|ipod|ios|ipad|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|webos|symbian|windows phone)";
|
||||
Pattern pattern = Pattern.compile(type);
|
||||
return pattern.matcher(ua).find();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecgframework.poi.util.PoiPublicUtil;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import digital.base.constant.CommonConstant;
|
||||
import digital.base.constant.DataBaseConstant;
|
||||
import digital.base.constant.SymbolConstant;
|
||||
import digital.util.filter.FileTypeFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Description: 通用工具
|
||||
* @author: smcp
|
||||
*/
|
||||
@Slf4j
|
||||
public class CommonUtils {
|
||||
|
||||
/**
|
||||
* 中文正则
|
||||
*/
|
||||
private static Pattern ZHONGWEN_PATTERN = Pattern.compile("[\u4e00-\u9fa5]");
|
||||
|
||||
/**
|
||||
* 文件名 正则字符串
|
||||
* 文件名支持的字符串:字母数字中文.-_()() 除此之外的字符将被删除
|
||||
*/
|
||||
private static String FILE_NAME_REGEX = "[^A-Za-z\\.\\(\\)\\-()\\_0-9\\u4e00-\\u9fa5]";
|
||||
|
||||
public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
|
||||
String dbPath = null;
|
||||
String fileName = "image" + Math.round(Math.random() * 100000000000L);
|
||||
fileName += "." + PoiPublicUtil.getFileExtendName(data);
|
||||
try {
|
||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||
File file = new File(basePath + File.separator + bizPath + File.separator );
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();// 创建文件根目录
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(data, savefile);
|
||||
dbPath = bizPath + File.separator + fileName;
|
||||
}else {
|
||||
InputStream in = new ByteArrayInputStream(data);
|
||||
String relativePath = bizPath + "/" + fileName;
|
||||
// if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
|
||||
// dbPath = MinioUtil.upload(in,relativePath);
|
||||
// }else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
||||
// dbPath = OssBootUtil.upload(in,relativePath);
|
||||
// }
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return dbPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件名是否带盘符,重新处理
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static String getFileName(String fileName){
|
||||
//判断是否带有盘符信息
|
||||
// Check for Unix-style path
|
||||
int unixSep = fileName.lastIndexOf('/');
|
||||
// Check for Windows-style path
|
||||
int winSep = fileName.lastIndexOf('\\');
|
||||
// Cut off at latest possible point
|
||||
int pos = (winSep > unixSep ? winSep : unixSep);
|
||||
if (pos != -1) {
|
||||
// Any sort of path separator found...
|
||||
fileName = fileName.substring(pos + 1);
|
||||
}
|
||||
//替换上传文件名字的特殊字符
|
||||
fileName = fileName.replace("=","").replace(",","").replace("&","")
|
||||
.replace("#", "").replace("“", "").replace("”", "");
|
||||
//替换上传文件名字中的空格
|
||||
fileName=fileName.replaceAll("\\s","");
|
||||
//update-beign-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常
|
||||
fileName = fileName.replaceAll(FILE_NAME_REGEX, "");
|
||||
//update-end-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* java 判断字符串里是否包含中文字符
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean ifContainChinese(String str) {
|
||||
if(str.getBytes().length == str.length()){
|
||||
return false;
|
||||
}else{
|
||||
Matcher m = ZHONGWEN_PATTERN.matcher(str);
|
||||
if (m.find()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一全局上传
|
||||
* @Return: java.lang.String
|
||||
*/
|
||||
// public static String upload(MultipartFile file, String bizPath, String uploadType) {
|
||||
// String url = "";
|
||||
// if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
|
||||
// url = MinioUtil.upload(file,bizPath);
|
||||
// }else{
|
||||
// url = OssBootUtil.upload(file,bizPath);
|
||||
// }
|
||||
// return url;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 本地文件上传
|
||||
*
|
||||
* @param mf 文件
|
||||
* @param bizPath 自定义路径
|
||||
* @return
|
||||
*/
|
||||
public static String uploadLocal(MultipartFile mf, String bizPath, String uploadpath) {
|
||||
try {
|
||||
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
||||
FileTypeFilter.fileTypeFilter(mf);
|
||||
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
||||
String fileName = null;
|
||||
File file = new File(uploadpath + File.separator + bizPath + File.separator );
|
||||
if (!file.exists()) {
|
||||
// 创建文件根目录
|
||||
file.mkdirs();
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = mf.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||
}else{
|
||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(mf.getBytes(), savefile);
|
||||
String dbpath = null;
|
||||
if(oConvertUtils.isNotEmpty(bizPath)){
|
||||
dbpath = bizPath + File.separator + fileName;
|
||||
}else{
|
||||
dbpath = fileName;
|
||||
}
|
||||
if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) {
|
||||
dbpath = dbpath.replace("\\", "/");
|
||||
}
|
||||
return dbpath;
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一全局上传 带桶
|
||||
* @Return: java.lang.String
|
||||
*/
|
||||
// public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) {
|
||||
// String url = "";
|
||||
// if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
|
||||
// url = MinioUtil.upload(file,bizPath,customBucket);
|
||||
// }else{
|
||||
// url = OssBootUtil.upload(file,bizPath,customBucket);
|
||||
// }
|
||||
// return url;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 当前系统数据库类型
|
||||
*/
|
||||
private static String DB_TYPE = "";
|
||||
private static DbType dbTypeEnum = null;
|
||||
|
||||
/**
|
||||
* 全局获取平台数据库类型(作废了)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getDatabaseType() {
|
||||
if(oConvertUtils.isNotEmpty(DB_TYPE)){
|
||||
return DB_TYPE;
|
||||
}
|
||||
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
|
||||
try {
|
||||
return getDatabaseTypeByDataSource(dataSource);
|
||||
} catch (SQLException e) {
|
||||
//e.printStackTrace();
|
||||
log.warn(e.getMessage(),e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局获取平台数据库类型(对应mybaisPlus枚举)
|
||||
* @return
|
||||
*/
|
||||
public static DbType getDatabaseTypeEnum() {
|
||||
if (oConvertUtils.isNotEmpty(dbTypeEnum)) {
|
||||
return dbTypeEnum;
|
||||
}
|
||||
try {
|
||||
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
|
||||
dbTypeEnum = JdbcUtils.getDbType(dataSource.getConnection().getMetaData().getURL());
|
||||
return dbTypeEnum;
|
||||
} catch (SQLException e) {
|
||||
log.warn(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据源key获取DataSourceProperty
|
||||
* @param sourceKey
|
||||
* @return
|
||||
*/
|
||||
public static DataSourceProperty getDataSourceProperty(String sourceKey){
|
||||
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class);
|
||||
Map<String, DataSourceProperty> map = prop.getDatasource();
|
||||
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey);
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sourceKey 获取数据源连接
|
||||
* @param sourceKey
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Connection getDataSourceConnect(String sourceKey) throws SQLException {
|
||||
if (oConvertUtils.isEmpty(sourceKey)) {
|
||||
sourceKey = "master";
|
||||
}
|
||||
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class);
|
||||
Map<String, DataSourceProperty> map = prop.getDatasource();
|
||||
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey);
|
||||
if(db==null){
|
||||
return null;
|
||||
}
|
||||
DriverManagerDataSource ds = new DriverManagerDataSource ();
|
||||
ds.setDriverClassName(db.getDriverClassName());
|
||||
ds.setUrl(db.getUrl());
|
||||
ds.setUsername(db.getUsername());
|
||||
ds.setPassword(db.getPassword());
|
||||
return ds.getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库类型
|
||||
* @param dataSource
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
|
||||
if("".equals(DB_TYPE)) {
|
||||
Connection connection = dataSource.getConnection();
|
||||
try {
|
||||
DatabaseMetaData md = connection.getMetaData();
|
||||
String dbType = md.getDatabaseProductName().toUpperCase();
|
||||
String sqlserver= "SQL SERVER";
|
||||
if(dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE)>=0 ||dbType.indexOf(DataBaseConstant.DB_TYPE_DM)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER)>=0||dbType.indexOf(sqlserver)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
|
||||
}else {
|
||||
log.error("数据库类型:[" + dbType + "]不识别!");
|
||||
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
return DB_TYPE;
|
||||
|
||||
}
|
||||
/**
|
||||
* 获取服务器地址
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static String getBaseUrl(HttpServletRequest request) {
|
||||
//1.【兼容】兼容微服务下的 base path-------
|
||||
String xGatewayBasePath = request.getHeader("X_GATEWAY_BASE_PATH");
|
||||
if(oConvertUtils.isNotEmpty(xGatewayBasePath)){
|
||||
log.info("x_gateway_base_path = "+ xGatewayBasePath);
|
||||
return xGatewayBasePath;
|
||||
}
|
||||
//2.【兼容】SSL认证之后,request.getScheme()获取不到https的问题
|
||||
// https://blog.csdn.net/weixin_34376986/article/details/89767950
|
||||
String scheme = request.getHeader("X-Forwarded-Scheme");
|
||||
if(oConvertUtils.isEmpty(scheme)){
|
||||
scheme = request.getScheme();
|
||||
}
|
||||
|
||||
//3.常规操作
|
||||
String serverName = request.getServerName();
|
||||
int serverPort = request.getServerPort();
|
||||
String contextPath = request.getContextPath();
|
||||
|
||||
//返回 host domain
|
||||
String baseDomainPath = null;
|
||||
int length = 80;
|
||||
if(length == serverPort){
|
||||
baseDomainPath = scheme + "://" + serverName + contextPath ;
|
||||
}else{
|
||||
baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
|
||||
}
|
||||
log.info("-----Common getBaseUrl----- : " + baseDomainPath);
|
||||
return baseDomainPath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,674 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import digital.base.constant.SymbolConstant;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* 类描述:时间操作定义类
|
||||
*
|
||||
* @Author: 张代浩
|
||||
* @Date:2012-12-8 12:15:03
|
||||
* @Version 1.0
|
||||
*/
|
||||
public class DateUtils extends PropertyEditorSupport {
|
||||
|
||||
public static ThreadLocal<SimpleDateFormat> date_sdf = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("yyyy-MM-dd");
|
||||
}
|
||||
};
|
||||
public static ThreadLocal<SimpleDateFormat> yyyyMMdd = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("yyyyMMdd");
|
||||
}
|
||||
};
|
||||
public static ThreadLocal<SimpleDateFormat> date_sdf_wz = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("yyyy年MM月dd日");
|
||||
}
|
||||
};
|
||||
public static ThreadLocal<SimpleDateFormat> time_sdf = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
}
|
||||
};
|
||||
public static ThreadLocal<SimpleDateFormat> yyyymmddhhmmss = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
}
|
||||
};
|
||||
public static ThreadLocal<SimpleDateFormat> short_time_sdf = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("HH:mm");
|
||||
}
|
||||
};
|
||||
public static ThreadLocal<SimpleDateFormat> datetimeFormat = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 以毫秒表示的时间
|
||||
*/
|
||||
private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
|
||||
private static final long HOUR_IN_MILLIS = 3600 * 1000;
|
||||
private static final long MINUTE_IN_MILLIS = 60 * 1000;
|
||||
private static final long SECOND_IN_MILLIS = 1000;
|
||||
|
||||
/**
|
||||
* 指定模式的时间格式
|
||||
* @param pattern
|
||||
* @return
|
||||
*/
|
||||
private static SimpleDateFormat getSdFormat(String pattern) {
|
||||
return new SimpleDateFormat(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前日历,这里用中国时间表示
|
||||
*
|
||||
* @return 以当地时区表示的系统当前日历
|
||||
*/
|
||||
public static Calendar getCalendar() {
|
||||
return Calendar.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定毫秒数表示的日历
|
||||
*
|
||||
* @param millis 毫秒数
|
||||
* @return 指定毫秒数表示的日历
|
||||
*/
|
||||
public static Calendar getCalendar(long millis) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
// --------------------cal.setTimeInMillis(millis);
|
||||
cal.setTime(new Date(millis));
|
||||
return cal;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// getDate
|
||||
// 各种方式获取的Date
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 当前日期
|
||||
*
|
||||
* @return 系统当前时间
|
||||
*/
|
||||
public static Date getDate() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定毫秒数表示的日期
|
||||
*
|
||||
* @param millis 毫秒数
|
||||
* @return 指定毫秒数表示的日期
|
||||
*/
|
||||
public static Date getDate(long millis) {
|
||||
return new Date(millis);
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间戳转换为字符串
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String timestamptoStr(Timestamp time) {
|
||||
Date date = null;
|
||||
if (null != time) {
|
||||
date = new Date(time.getTime());
|
||||
}
|
||||
return date2Str(date_sdf.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转换时间戳
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static Timestamp str2Timestamp(String str) {
|
||||
Date date = str2Date(str, date_sdf.get());
|
||||
return new Timestamp(date.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转换成日期
|
||||
*
|
||||
* @param str
|
||||
* @param sdf
|
||||
* @return
|
||||
*/
|
||||
public static Date str2Date(String str, SimpleDateFormat sdf) {
|
||||
if (null == str || "".equals(str)) {
|
||||
return null;
|
||||
}
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf.parse(str);
|
||||
return date;
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期转换为字符串
|
||||
*
|
||||
* @param dateSdf 日期格式
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String date2Str(SimpleDateFormat dateSdf) {
|
||||
synchronized (dateSdf) {
|
||||
Date date = getDate();
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
return dateSdf.format(date);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
*
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String dateformat(String date, String format) {
|
||||
SimpleDateFormat sformat = new SimpleDateFormat(format);
|
||||
Date nowDate = null;
|
||||
try {
|
||||
nowDate = sformat.parse(date);
|
||||
} catch (ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return sformat.format(nowDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期转换为字符串
|
||||
*
|
||||
* @param date 日期
|
||||
* @param dateSdf 日期格式
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String date2Str(Date date, SimpleDateFormat dateSdf) {
|
||||
synchronized (dateSdf) {
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
return dateSdf.format(date);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期转换为字符串
|
||||
*
|
||||
* @param format 日期格式
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String getDate(String format) {
|
||||
Date date = new Date();
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定毫秒数的时间戳
|
||||
*
|
||||
* @param millis 毫秒数
|
||||
* @return 指定毫秒数的时间戳
|
||||
*/
|
||||
public static Timestamp getTimestamp(long millis) {
|
||||
return new Timestamp(millis);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字符形式表示的时间戳
|
||||
*
|
||||
* @param time 毫秒数
|
||||
* @return 以字符形式表示的时间戳
|
||||
*/
|
||||
public static Timestamp getTimestamp(String time) {
|
||||
return new Timestamp(Long.parseLong(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统当前的时间戳
|
||||
*
|
||||
* @return 系统当前的时间戳
|
||||
*/
|
||||
public static Timestamp getTimestamp() {
|
||||
return new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前时间,格式 yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @return 当前时间的标准形式字符串
|
||||
*/
|
||||
public static String now() {
|
||||
return datetimeFormat.get().format(getCalendar().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的时间戳
|
||||
*
|
||||
* @param date 指定日期
|
||||
* @return 指定日期的时间戳
|
||||
*/
|
||||
public static Timestamp getTimestamp(Date date) {
|
||||
return new Timestamp(date.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日历的时间戳
|
||||
*
|
||||
* @param cal 指定日历
|
||||
* @return 指定日历的时间戳
|
||||
*/
|
||||
public static Timestamp getCalendarTimestamp(Calendar cal) {
|
||||
// ---------------------return new Timestamp(cal.getTimeInMillis());
|
||||
return new Timestamp(cal.getTime().getTime());
|
||||
}
|
||||
|
||||
public static Timestamp gettimestamp() {
|
||||
Date dt = new Date();
|
||||
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String nowTime = df.format(dt);
|
||||
java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
|
||||
return buydate;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// getMillis
|
||||
// 各种方式获取的Millis
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 系统时间的毫秒数
|
||||
*
|
||||
* @return 系统时间的毫秒数
|
||||
*/
|
||||
public static long getMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日历的毫秒数
|
||||
*
|
||||
* @param cal 指定日历
|
||||
* @return 指定日历的毫秒数
|
||||
*/
|
||||
public static long getMillis(Calendar cal) {
|
||||
// --------------------return cal.getTimeInMillis();
|
||||
return cal.getTime().getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的毫秒数
|
||||
*
|
||||
* @param date 指定日期
|
||||
* @return 指定日期的毫秒数
|
||||
*/
|
||||
public static long getMillis(Date date) {
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定时间戳的毫秒数
|
||||
*
|
||||
* @param ts 指定时间戳
|
||||
* @return 指定时间戳的毫秒数
|
||||
*/
|
||||
public static long getMillis(Timestamp ts) {
|
||||
return ts.getTime();
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// formatDate
|
||||
// 将日期按照一定的格式转化为字符串
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 默认方式表示的系统当前日期,具体格式:年-月-日
|
||||
*
|
||||
* @return 默认日期按“年-月-日“格式显示
|
||||
*/
|
||||
public static String formatDate() {
|
||||
return date_sdf.get().format(getCalendar().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
|
||||
*/
|
||||
public static String formatDateTime() {
|
||||
return datetimeFormat.get().format(getCalendar().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间字符串
|
||||
*/
|
||||
public static String getDataString(SimpleDateFormat formatstr) {
|
||||
synchronized (formatstr) {
|
||||
return formatstr.format(getCalendar().getTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的默认显示,具体格式:年-月-日
|
||||
*
|
||||
* @param cal 指定的日期
|
||||
* @return 指定日期按“年-月-日“格式显示
|
||||
*/
|
||||
public static String formatDate(Calendar cal) {
|
||||
return date_sdf.get().format(cal.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的默认显示,具体格式:年-月-日
|
||||
*
|
||||
* @param date 指定的日期
|
||||
* @return 指定日期按“年-月-日“格式显示
|
||||
*/
|
||||
public static String formatDate(Date date) {
|
||||
return date_sdf.get().format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定毫秒数表示日期的默认显示,具体格式:年-月-日
|
||||
*
|
||||
* @param millis 指定的毫秒数
|
||||
* @return 指定毫秒数表示日期按“年-月-日“格式显示
|
||||
*/
|
||||
public static String formatDate(long millis) {
|
||||
return date_sdf.get().format(new Date(millis));
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认日期按指定格式显示
|
||||
*
|
||||
* @param pattern 指定的格式
|
||||
* @return 默认日期按指定格式显示
|
||||
*/
|
||||
public static String formatDate(String pattern) {
|
||||
return getSdFormat(pattern).format(getCalendar().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期按指定格式显示
|
||||
*
|
||||
* @param cal 指定的日期
|
||||
* @param pattern 指定的格式
|
||||
* @return 指定日期按指定格式显示
|
||||
*/
|
||||
public static String formatDate(Calendar cal, String pattern) {
|
||||
return getSdFormat(pattern).format(cal.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期按指定格式显示
|
||||
*
|
||||
* @param date 指定的日期
|
||||
* @param pattern 指定的格式
|
||||
* @return 指定日期按指定格式显示
|
||||
*/
|
||||
public static String formatDate(Date date, String pattern) {
|
||||
return getSdFormat(pattern).format(date);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// formatTime
|
||||
// 将日期按照一定的格式转化为字符串
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 默认方式表示的系统当前日期,具体格式:年-月-日 时:分
|
||||
*
|
||||
* @return 默认日期按“年-月-日 时:分“格式显示
|
||||
*/
|
||||
public static String formatTime() {
|
||||
return time_sdf.get().format(getCalendar().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分
|
||||
*
|
||||
* @param millis 指定的毫秒数
|
||||
* @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示
|
||||
*/
|
||||
public static String formatTime(long millis) {
|
||||
return time_sdf.get().format(new Date(millis));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的默认显示,具体格式:年-月-日 时:分
|
||||
*
|
||||
* @param cal 指定的日期
|
||||
* @return 指定日期按“年-月-日 时:分“格式显示
|
||||
*/
|
||||
public static String formatTime(Calendar cal) {
|
||||
return time_sdf.get().format(cal.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的默认显示,具体格式:年-月-日 时:分
|
||||
*
|
||||
* @param date 指定的日期
|
||||
* @return 指定日期按“年-月-日 时:分“格式显示
|
||||
*/
|
||||
public static String formatTime(Date date) {
|
||||
return time_sdf.get().format(date);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// formatShortTime
|
||||
// 将日期按照一定的格式转化为字符串
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 默认方式表示的系统当前日期,具体格式:时:分
|
||||
*
|
||||
* @return 默认日期按“时:分“格式显示
|
||||
*/
|
||||
public static String formatShortTime() {
|
||||
return short_time_sdf.get().format(getCalendar().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定毫秒数表示日期的默认显示,具体格式:时:分
|
||||
*
|
||||
* @param millis 指定的毫秒数
|
||||
* @return 指定毫秒数表示日期按“时:分“格式显示
|
||||
*/
|
||||
public static String formatShortTime(long millis) {
|
||||
return short_time_sdf.get().format(new Date(millis));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的默认显示,具体格式:时:分
|
||||
*
|
||||
* @param cal 指定的日期
|
||||
* @return 指定日期按“时:分“格式显示
|
||||
*/
|
||||
public static String formatShortTime(Calendar cal) {
|
||||
return short_time_sdf.get().format(cal.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定日期的默认显示,具体格式:时:分
|
||||
*
|
||||
* @param date 指定的日期
|
||||
* @return 指定日期按“时:分“格式显示
|
||||
*/
|
||||
public static String formatShortTime(Date date) {
|
||||
return short_time_sdf.get().format(date);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// parseDate
|
||||
// parseCalendar
|
||||
// parseTimestamp
|
||||
// 将字符串按照一定的格式转化为日期或时间
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
|
||||
*
|
||||
* @param src 将要转换的原始字符窜
|
||||
* @param pattern 转换的匹配格式
|
||||
* @return 如果转换成功则返回转换后的日期
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Date parseDate(String src, String pattern) throws ParseException {
|
||||
return getSdFormat(pattern).parse(src);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
|
||||
*
|
||||
* @param src 将要转换的原始字符窜
|
||||
* @param pattern 转换的匹配格式
|
||||
* @return 如果转换成功则返回转换后的日期
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Calendar parseCalendar(String src, String pattern) throws ParseException {
|
||||
|
||||
Date date = parseDate(src, pattern);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
return cal;
|
||||
}
|
||||
|
||||
public static String formatAddDate(String src, String pattern, int amount) throws ParseException {
|
||||
Calendar cal;
|
||||
cal = parseCalendar(src, pattern);
|
||||
cal.add(Calendar.DATE, amount);
|
||||
return formatDate(cal);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
|
||||
*
|
||||
* @param src 将要转换的原始字符窜
|
||||
* @param pattern 转换的匹配格式
|
||||
* @return 如果转换成功则返回转换后的时间戳
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
|
||||
Date date = parseDate(src, pattern);
|
||||
return new Timestamp(date.getTime());
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// dateDiff
|
||||
// 计算两个日期之间的差值
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 计算两个时间之间的差值,根据标志的不同而不同
|
||||
*
|
||||
* @param flag 计算标志,表示按照年/月/日/时/分/秒等计算
|
||||
* @param calSrc 减数
|
||||
* @param calDes 被减数
|
||||
* @return 两个日期之间的差值
|
||||
*/
|
||||
public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
|
||||
|
||||
long millisDiff = getMillis(calSrc) - getMillis(calDes);
|
||||
char year = 'y';
|
||||
char day = 'd';
|
||||
char hour = 'h';
|
||||
char minute = 'm';
|
||||
char second = 's';
|
||||
|
||||
if (flag == year) {
|
||||
return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR));
|
||||
}
|
||||
|
||||
if (flag == day) {
|
||||
return (int) (millisDiff / DAY_IN_MILLIS);
|
||||
}
|
||||
|
||||
if (flag == hour) {
|
||||
return (int) (millisDiff / HOUR_IN_MILLIS);
|
||||
}
|
||||
|
||||
if (flag == minute) {
|
||||
return (int) (millisDiff / MINUTE_IN_MILLIS);
|
||||
}
|
||||
|
||||
if (flag == second) {
|
||||
return (int) (millisDiff / SECOND_IN_MILLIS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Long getCurrentTimestamp() {
|
||||
return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date()));
|
||||
}
|
||||
|
||||
/**
|
||||
* String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
|
||||
* HH:mm:ss“ * @param text String类型的时间值
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
if (StringUtils.hasText(text)) {
|
||||
try {
|
||||
int length10 = 10;
|
||||
int length19 = 19;
|
||||
if (text.indexOf(SymbolConstant.COLON) == -1 && text.length() == length10) {
|
||||
setValue(DateUtils.date_sdf.get().parse(text));
|
||||
} else if (text.indexOf(SymbolConstant.COLON) > 0 && text.length() == length19) {
|
||||
setValue(DateUtils.datetimeFormat.get().parse(text));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Could not parse date, date format is error ");
|
||||
}
|
||||
} catch (ParseException ex) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
|
||||
iae.initCause(ex);
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getYear() {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
calendar.setTime(getDate());
|
||||
return calendar.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package digital.util.util;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
public class DigitalPersonUtils {
|
||||
|
||||
@Value("${digital.secret}")
|
||||
private String secret;
|
||||
@Value("${digital.reqFrom}")
|
||||
private String reqFrom;
|
||||
@Value("${digital.appId}")
|
||||
private String appId;
|
||||
|
||||
public String authorization() {
|
||||
String secrets = this.secret + getCurrentTimestamp();
|
||||
String authorization = SecureUtil.md5(secret);
|
||||
return authorization;
|
||||
}
|
||||
|
||||
private static String getCurrentTimestamp() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
|
||||
return sdf.format(new Date());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @Description: 短信枚举类
|
||||
* @author: smcp
|
||||
*/
|
||||
public enum DySmsEnum {
|
||||
|
||||
/**
|
||||
* 登录短信模板编码
|
||||
*/
|
||||
LOGIN_TEMPLATE_CODE("SMS_246725484", "数字力场", "code"),
|
||||
/**
|
||||
* 忘记密码短信模板编码
|
||||
*/
|
||||
FORGET_PASSWORD_TEMPLATE_CODE("SMS_175435174", "JEECG", "code"),
|
||||
/**
|
||||
* 注册账号短信模板编码
|
||||
*/
|
||||
REGISTER_TEMPLATE_CODE("SMS_175430166", "JEECG", "code"),
|
||||
/**
|
||||
* 会议通知
|
||||
*/
|
||||
MEET_NOTICE_TEMPLATE_CODE("SMS_201480469", "H5活动之家", "username,title,minute,time"),
|
||||
/**
|
||||
* 我的计划通知
|
||||
*/
|
||||
PLAN_NOTICE_TEMPLATE_CODE("SMS_201470515", "H5活动之家", "username,title,time");
|
||||
|
||||
/**
|
||||
* 短信模板编码
|
||||
*/
|
||||
private String templateCode;
|
||||
/**
|
||||
* 签名
|
||||
*/
|
||||
private String signName;
|
||||
/**
|
||||
* 短信模板必需的数据名称,多个key以逗号分隔,此处配置作为校验
|
||||
*/
|
||||
private String keys;
|
||||
|
||||
private DySmsEnum(String templateCode,String signName,String keys) {
|
||||
this.templateCode = templateCode;
|
||||
this.signName = signName;
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public String getTemplateCode() {
|
||||
return templateCode;
|
||||
}
|
||||
|
||||
public void setTemplateCode(String templateCode) {
|
||||
this.templateCode = templateCode;
|
||||
}
|
||||
|
||||
public String getSignName() {
|
||||
return signName;
|
||||
}
|
||||
|
||||
public void setSignName(String signName) {
|
||||
this.signName = signName;
|
||||
}
|
||||
|
||||
public String getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public void setKeys(String keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public static DySmsEnum toEnum(String templateCode) {
|
||||
if(StringUtils.isEmpty(templateCode)){
|
||||
return null;
|
||||
}
|
||||
for(DySmsEnum item : DySmsEnum.values()) {
|
||||
if(item.getTemplateCode().equals(templateCode)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import com.aliyuncs.profile.IClientProfile;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Created on 17/6/7.
|
||||
* 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过
|
||||
* 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
|
||||
* 工程依赖了2个jar包(存放在工程的libs目录下)
|
||||
* 1:aliyun-java-sdk-core.jar
|
||||
* 2:aliyun-java-sdk-dysmsapi.jar
|
||||
* <p>
|
||||
* 备注:Demo工程编码采用UTF-8
|
||||
* 国际短信发送请勿参照此DEMO
|
||||
*
|
||||
* @author: smcp
|
||||
*/
|
||||
public class DySmsHelper {
|
||||
|
||||
/**
|
||||
* 产品名称:云通信短信API产品,开发者无需替换
|
||||
*/
|
||||
static final String PRODUCT = "Dysmsapi";
|
||||
/**
|
||||
* 产品域名,开发者无需替换
|
||||
*/
|
||||
static final String DOMAIN = "dysmsapi.aliyuncs.com";
|
||||
private final static Logger logger = LoggerFactory.getLogger(DySmsHelper.class);
|
||||
/**
|
||||
* TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
|
||||
*/
|
||||
static String accessKeyId = "LTAI5t6x568R1E6hVvgdr1B9";
|
||||
static String accessKeySecret = "F8uPuRJI5Tq0ICKyuhRBNF6MxOlXo0";
|
||||
|
||||
public static String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
|
||||
public static void setAccessKeyId(String accessKeyId) {
|
||||
DySmsHelper.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
public static String getAccessKeySecret() {
|
||||
return accessKeySecret;
|
||||
}
|
||||
|
||||
public static void setAccessKeySecret(String accessKeySecret) {
|
||||
DySmsHelper.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
public static boolean sendSms(String phone, JSONObject templateParamJson, DySmsEnum dySmsEnum) throws ClientException {
|
||||
//可自助调整超时时间
|
||||
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
|
||||
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
|
||||
|
||||
//update-begin-author:taoyan date:20200811 for:配置类数据获取
|
||||
// StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
// setAccessKeyId(staticConfig.getAccessKeyId());
|
||||
// setAccessKeySecret(staticConfig.getAccessKeySecret());
|
||||
//update-end-author:taoyan date:20200811 for:配置类数据获取
|
||||
|
||||
//初始化acsClient,暂不支持region化
|
||||
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
|
||||
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", PRODUCT, DOMAIN);
|
||||
IAcsClient acsClient = new DefaultAcsClient(profile);
|
||||
|
||||
//验证json参数
|
||||
validateParam(templateParamJson, dySmsEnum);
|
||||
|
||||
//组装请求对象-具体描述见控制台-文档部分内容
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
//必填:待发送手机号
|
||||
request.setPhoneNumbers(phone);
|
||||
//必填:短信签名-可在短信控制台中找到
|
||||
request.setSignName(dySmsEnum.getSignName());
|
||||
//必填:短信模板-可在短信控制台中找到
|
||||
request.setTemplateCode(dySmsEnum.getTemplateCode());
|
||||
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
||||
request.setTemplateParam(templateParamJson.toJSONString());
|
||||
|
||||
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
|
||||
//request.setSmsUpExtendCode("90997");
|
||||
|
||||
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
|
||||
//request.setOutId("yourOutId");
|
||||
|
||||
boolean result = false;
|
||||
|
||||
//hint 此处可能会抛出异常,注意catch
|
||||
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
|
||||
logger.info("短信接口返回的数据----------------");
|
||||
logger.info("{Code:" + sendSmsResponse.getCode() + ",Message:" + sendSmsResponse.getMessage() + ",RequestId:" + sendSmsResponse.getRequestId() + ",BizId:" + sendSmsResponse.getBizId() + "}");
|
||||
String ok = "OK";
|
||||
if (ok.equals(sendSmsResponse.getCode())) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private static void validateParam(JSONObject templateParamJson, DySmsEnum dySmsEnum) {
|
||||
String keys = dySmsEnum.getKeys();
|
||||
String[] keyArr = keys.split(",");
|
||||
for (String item : keyArr) {
|
||||
if (!templateParamJson.containsKey(item)) {
|
||||
throw new RuntimeException("模板缺少参数:" + item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static void main(String[] args) throws ClientException, InterruptedException {
|
||||
// JSONObject obj = new JSONObject();
|
||||
// obj.put("code", "1234");
|
||||
// sendSms("18610015538", obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package digital.util.util;
|
||||
|
||||
/**
|
||||
* author: smcp
|
||||
* date:2022-08-15 16:18
|
||||
* description:
|
||||
**/
|
||||
public class EmailUtils {
|
||||
|
||||
public static String email(String email) {
|
||||
if (oConvertUtils.isEmpty(email)) {
|
||||
return "";
|
||||
}
|
||||
int index = email.indexOf("@");
|
||||
if (index <= 1){
|
||||
return email;
|
||||
}
|
||||
String begin = email.substring(0, 1);
|
||||
String end = email.substring(index);
|
||||
String stars = "**";
|
||||
return begin + stars + end;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import digital.base.handler.IFillRuleHandler;
|
||||
|
||||
|
||||
/**
|
||||
* 规则值自动生成工具类
|
||||
*
|
||||
* @author qinfeng
|
||||
* @举例: 自动生成订单号;自动生成当前日期
|
||||
*/
|
||||
@Slf4j
|
||||
public class FillRuleUtil {
|
||||
|
||||
/**
|
||||
* @param ruleCode ruleCode
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Object executeRule(String ruleCode, JSONObject formData) {
|
||||
if (!StringUtils.isEmpty(ruleCode)) {
|
||||
try {
|
||||
// 获取 Service
|
||||
ServiceImpl impl = (ServiceImpl) SpringContextUtils.getBean("sysFillRuleServiceImpl");
|
||||
// 根据 ruleCode 查询出实体
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.eq("rule_code", ruleCode);
|
||||
JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper)));
|
||||
if (entity == null) {
|
||||
log.warn("填值规则:" + ruleCode + " 不存在");
|
||||
return null;
|
||||
}
|
||||
// 获取必要的参数
|
||||
String ruleClass = entity.getString("ruleClass");
|
||||
JSONObject params = entity.getJSONObject("ruleParams");
|
||||
if (params == null) {
|
||||
params = new JSONObject();
|
||||
}
|
||||
if (formData == null) {
|
||||
formData = new JSONObject();
|
||||
}
|
||||
// 通过反射执行配置的类里的方法
|
||||
IFillRuleHandler ruleHandler = (IFillRuleHandler) Class.forName(ruleClass).newInstance();
|
||||
return ruleHandler.execute(params, formData);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
/**
|
||||
* HTML 工具类
|
||||
* @author: smcp
|
||||
* @date: 2022/3/30 14:43
|
||||
*/
|
||||
@SuppressWarnings("AlibabaClassNamingShouldBeCamel")
|
||||
public class HTMLUtils {
|
||||
|
||||
/**
|
||||
* 获取HTML内的文本,不包含标签
|
||||
*
|
||||
* @param html HTML 代码
|
||||
*/
|
||||
public static String getInnerText(String html) {
|
||||
if (StringUtils.isNotBlank(html)) {
|
||||
//去掉 html 的标签
|
||||
String content = html.replaceAll("</?[^>]+>", "");
|
||||
// 将多个空格合并成一个空格
|
||||
content = content.replaceAll("( )+", " ");
|
||||
// 反向转义字符
|
||||
content = HtmlUtils.htmlUnescape(content);
|
||||
return content.trim();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import digital.base.constant.CommonConstant;
|
||||
import digital.base.vo.Result;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 导出返回信息
|
||||
* @author: smcp
|
||||
*/
|
||||
@Slf4j
|
||||
public class ImportExcelUtil {
|
||||
|
||||
public static Result<?> imporReturnRes(int errorLines,int successLines,List<String> errorMessage) throws IOException {
|
||||
if (errorLines == 0) {
|
||||
return Result.ok("共" + successLines + "行数据全部导入成功!");
|
||||
} else {
|
||||
JSONObject result = new JSONObject(5);
|
||||
int totalCount = successLines + errorLines;
|
||||
result.put("totalCount", totalCount);
|
||||
result.put("errorCount", errorLines);
|
||||
result.put("successCount", successLines);
|
||||
result.put("msg", "总上传行数:" + totalCount + ",已导入行数:" + successLines + ",错误行数:" + errorLines);
|
||||
String fileUrl = PmsUtil.saveErrorTxtByList(errorMessage, "userImportExcelErrorLog");
|
||||
int lastIndex = fileUrl.lastIndexOf(File.separator);
|
||||
String fileName = fileUrl.substring(lastIndex + 1);
|
||||
result.put("fileUrl", "/sys/common/static/" + fileUrl);
|
||||
result.put("fileName", fileName);
|
||||
Result res = Result.ok(result);
|
||||
res.setCode(201);
|
||||
res.setMessage("文件导入成功,但有错误。");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> importDateSave(List<?> list, Class serviceClass, List<String> errorMessage, String errorFlag) {
|
||||
IService bean =(IService) SpringContextUtils.getBean(serviceClass);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
try {
|
||||
boolean save = bean.save(list.get(i));
|
||||
if(!save){
|
||||
throw new Exception(errorFlag);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String message = e.getMessage().toLowerCase();
|
||||
int lineNumber = i + 1;
|
||||
// 通过索引名判断出错信息
|
||||
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:角色编码已经存在,忽略导入。");
|
||||
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:任务类名已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:职务编码已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:部门编码已经存在,忽略导入。");
|
||||
}else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public static List<String> importDateSaveOne(Object obj, Class serviceClass,List<String> errorMessage,int i,String errorFlag) {
|
||||
IService bean =(IService) SpringContextUtils.getBean(serviceClass);
|
||||
try {
|
||||
boolean save = bean.save(obj);
|
||||
if(!save){
|
||||
throw new Exception(errorFlag);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String message = e.getMessage().toLowerCase();
|
||||
int lineNumber = i + 1;
|
||||
// 通过索引名判断出错信息
|
||||
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:角色编码已经存在,忽略导入。");
|
||||
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:任务类名已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:职务编码已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:部门编码已经存在,忽略导入。");
|
||||
}else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import digital.base.constant.CommonConstant;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*
|
||||
* @Author scott
|
||||
*
|
||||
* update: 【类名改了大小写】 date: 2022-04-18
|
||||
* @email jeecgos@163.com
|
||||
* @Date 2019年01月14日
|
||||
*/
|
||||
public class IpUtils {
|
||||
private static Logger logger = LoggerFactory.getLogger(IpUtils.class);
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
|
||||
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ip = null;
|
||||
try {
|
||||
ip = request.getHeader("x-forwarded-for");
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || ip.length() == 0 ||CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("IPUtils ERROR ", e);
|
||||
}
|
||||
|
||||
// //使用代理,则获取第一个IP地址
|
||||
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
|
||||
// if(ip.indexOf(",") > 0) {
|
||||
// ip = ip.substring(0, ip.indexOf(","));
|
||||
// }
|
||||
// }
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import digital.base.vo.SysPermissionDataRuleModel;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName: JeecgDataAutorUtils
|
||||
* @Description: 数据权限查询规则容器工具类
|
||||
* @Author: 张代浩
|
||||
* @Date: 2012-12-15 下午11:27:39
|
||||
*/
|
||||
public class JeecgDataAutorUtils {
|
||||
|
||||
public static final String MENU_DATA_AUTHOR_RULES = "MENU_DATA_AUTHOR_RULES";
|
||||
|
||||
public static final String MENU_DATA_AUTHOR_RULE_SQL = "MENU_DATA_AUTHOR_RULE_SQL";
|
||||
|
||||
public static final String SYS_USER_INFO = "SYS_USER_INFO";
|
||||
|
||||
/**
|
||||
* 往链接请求里面,传入数据查询条件
|
||||
*
|
||||
* @param request
|
||||
* @param dataRules
|
||||
*/
|
||||
public static synchronized void installDataSearchConditon(HttpServletRequest request, List<SysPermissionDataRuleModel> dataRules) {
|
||||
@SuppressWarnings("unchecked")
|
||||
// 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST
|
||||
List<SysPermissionDataRuleModel> list = (List<SysPermissionDataRuleModel>) loadDataSearchConditon();
|
||||
if (list == null) {
|
||||
// 2.如果不存在,则new一个list
|
||||
list = new ArrayList<SysPermissionDataRuleModel>();
|
||||
}
|
||||
for (SysPermissionDataRuleModel tsDataRule : dataRules) {
|
||||
list.add(tsDataRule);
|
||||
}
|
||||
// 3.往list里面增量存指
|
||||
request.setAttribute(MENU_DATA_AUTHOR_RULES, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求对应的数据权限规则
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static synchronized List<SysPermissionDataRuleModel> loadDataSearchConditon() {
|
||||
return (List<SysPermissionDataRuleModel>) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULES);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求对应的数据权限SQL
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String loadDataSearchConditonSqlString() {
|
||||
return (String) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULE_SQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 往链接请求里面,传入数据查询条件
|
||||
*
|
||||
* @param request
|
||||
* @param sql
|
||||
*/
|
||||
public static synchronized void installDataSearchConditon(HttpServletRequest request, String sql) {
|
||||
String ruleSql = (String) loadDataSearchConditonSqlString();
|
||||
if (!StringUtils.hasText(ruleSql)) {
|
||||
request.setAttribute(MENU_DATA_AUTHOR_RULE_SQL, sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将用户信息存到request
|
||||
*
|
||||
* @param request
|
||||
* @param userinfo
|
||||
*/
|
||||
public static synchronized void installUserInfo(HttpServletRequest request, SysUserCacheInfo userinfo) {
|
||||
request.setAttribute(SYS_USER_INFO, userinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将用户信息存到request
|
||||
*
|
||||
* @param userinfo
|
||||
*/
|
||||
public static synchronized void installUserInfo(SysUserCacheInfo userinfo) {
|
||||
SpringContextUtils.getHttpServletRequest().setAttribute(SYS_USER_INFO, userinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从request获取用户信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized SysUserCacheInfo loadUserInfo() {
|
||||
return (SysUserCacheInfo) SpringContextUtils.getHttpServletRequest().getAttribute(SYS_USER_INFO);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,613 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* redis 工具类
|
||||
* @Author Scott
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class JeecgRedisUtil {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean expire(String key, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key 获取过期时间
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @return 时间(秒) 返回0代表为永久有效
|
||||
*/
|
||||
public long getExpire(String key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param key 可以传一个值 或多个
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void del(String... key) {
|
||||
if (key != null && key.length > 0) {
|
||||
if (key.length == 1) {
|
||||
redisTemplate.delete(key[0]);
|
||||
} else {
|
||||
//springboot2.4后用法
|
||||
redisTemplate.delete(Arrays.asList(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================String=============================
|
||||
/**
|
||||
* 普通缓存获取
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object get(String key) {
|
||||
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean set(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
set(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*
|
||||
* @param key 键
|
||||
* @param by 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public long incr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递增因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param by 要减少几(小于0)
|
||||
* @return
|
||||
*/
|
||||
public long decr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递减因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
}
|
||||
|
||||
// ================================Map=================================
|
||||
/**
|
||||
* HashGet
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return 值
|
||||
*/
|
||||
public Object hget(String key, String item) {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取hashKey对应的所有键值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 对应的多个键值
|
||||
*/
|
||||
public Map<Object, Object> hmget(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @return true 成功 false 失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet 并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @param time 时间(秒)
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除hash表中的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 可以使多个 不能为null
|
||||
*/
|
||||
public void hdel(String key, Object... item) {
|
||||
redisTemplate.opsForHash().delete(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断hash表中是否有该项的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hHasKey(String key, String item) {
|
||||
return redisTemplate.opsForHash().hasKey(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public double hincr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, by);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要减少记(小于0)
|
||||
* @return
|
||||
*/
|
||||
public double hdecr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, -by);
|
||||
}
|
||||
|
||||
// ============================set=============================
|
||||
/**
|
||||
* 根据key获取Set中的所有值
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public Set<Object> sGet(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据value从一个set中查询,是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean sHasKey(String key, Object value) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据放入set缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSet(String key, Object... values) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将set数据放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSetAndTime(String key, long time, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取set缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long sGetSetSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除值为value的
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long setRemove(String key, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().remove(key, values);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// ===============================list=================================
|
||||
|
||||
/**
|
||||
* 获取list缓存的内容
|
||||
*
|
||||
* @param key 键
|
||||
* @param start 开始
|
||||
* @param end 结束 0 到 -1代表所有值
|
||||
* @return
|
||||
*/
|
||||
public List<Object> lGet(String key, long start, long end) {
|
||||
try {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取list缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long lGetListSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过索引 获取list中的值
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
|
||||
* @return
|
||||
*/
|
||||
public Object lGetIndex(String key, long index) {
|
||||
try {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引修改list中的某条数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().set(key, index, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除N个值为value
|
||||
*
|
||||
* @param key 键
|
||||
* @param count 移除多少个
|
||||
* @param value 值
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long lRemove(String key, long count, Object value) {
|
||||
try {
|
||||
Long remove = redisTemplate.opsForList().remove(key, count, value);
|
||||
return remove;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定前缀的一系列key
|
||||
* 使用scan命令代替keys, Redis是单线程处理,keys命令在KEY数量较多时,
|
||||
* 操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求
|
||||
* @param keyPrefix
|
||||
* @return
|
||||
*/
|
||||
private Set<String> keys(String keyPrefix) {
|
||||
String realKey = keyPrefix + "*";
|
||||
|
||||
try {
|
||||
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
|
||||
Set<String> binaryKeys = new HashSet<>();
|
||||
//springboot2.4后用法
|
||||
Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(realKey).count(Integer.MAX_VALUE).build());
|
||||
while (cursor.hasNext()) {
|
||||
binaryKeys.add(new String(cursor.next()));
|
||||
}
|
||||
|
||||
return binaryKeys;
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定前缀的一系列key
|
||||
* @param keyPrefix
|
||||
*/
|
||||
public void removeAll(String keyPrefix) {
|
||||
try {
|
||||
Set<String> keys = keys(keyPrefix);
|
||||
redisTemplate.delete(keys);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Joiner;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import digital.base.constant.CommonConstant;
|
||||
import digital.base.constant.DataBaseConstant;
|
||||
import digital.base.constant.SymbolConstant;
|
||||
import digital.base.vo.LoginUser;
|
||||
import digital.base.vo.Result;
|
||||
import digital.util.exception.JeecgBootException;
|
||||
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* @Author Scott
|
||||
* @Date 2018-07-12 14:23
|
||||
* @Desc JWT工具类
|
||||
**/
|
||||
public class JwtUtil {
|
||||
|
||||
/**
|
||||
* Token有效期为7天(Token在reids中缓存时间为两倍)
|
||||
*/
|
||||
public static final long EXPIRE_TIME = (7 * 12) * 60 * 60 * 1000;
|
||||
static final String WELL_NUMBER = SymbolConstant.WELL_NUMBER + SymbolConstant.LEFT_CURLY_BRACKET;
|
||||
|
||||
/**
|
||||
* @param response
|
||||
* @param code
|
||||
* @param errorMsg
|
||||
*/
|
||||
public static void responseError(ServletResponse response, Integer code, String errorMsg) {
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
// issues/I4YH95浏览器显示乱码问题
|
||||
httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
|
||||
Result jsonResult = new Result(code, errorMsg);
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = httpServletResponse.getOutputStream();
|
||||
httpServletResponse.setCharacterEncoding("UTF-8");
|
||||
httpServletResponse.setStatus(401);
|
||||
os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8"));
|
||||
os.flush();
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验token是否正确
|
||||
*
|
||||
* @param token 密钥
|
||||
* @param secret 用户的密码
|
||||
* @return 是否正确
|
||||
*/
|
||||
public static boolean verify(String token, String username, String secret) {
|
||||
try {
|
||||
// 根据密码生成JWT效验器
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
|
||||
// 效验TOKEN
|
||||
DecodedJWT jwt = verifier.verify(token);
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得token中的信息无需secret解密也能获得
|
||||
*
|
||||
* @return token中包含的用户名
|
||||
*/
|
||||
public static String getUsername(String token) {
|
||||
try {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim("username").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名,5min后过期
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param secret 用户的密码
|
||||
* @return 加密的token
|
||||
*/
|
||||
public static String sign(String username, String secret) {
|
||||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
|
||||
}
|
||||
|
||||
public static String getToken(String username, String secret) {
|
||||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据request中的token获取用户账号
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @throws JeecgBootException
|
||||
*/
|
||||
public static String getUserNameByToken(HttpServletRequest request) throws JeecgBootException {
|
||||
String accessToken = request.getHeader("X-Access-Token");
|
||||
String username = getUsername(accessToken);
|
||||
if (oConvertUtils.isEmpty(username)) {
|
||||
throw new JeecgBootException("未获取到用户");
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从session中获取变量
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getSessionData(String key) {
|
||||
//${myVar}%
|
||||
//得到${} 后面的值
|
||||
String moshi = "";
|
||||
String wellNumber = WELL_NUMBER;
|
||||
|
||||
if (key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET) != -1) {
|
||||
moshi = key.substring(key.indexOf("}") + 1);
|
||||
}
|
||||
String returnValue = null;
|
||||
if (key.contains(wellNumber)) {
|
||||
key = key.substring(2, key.indexOf("}"));
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(key)) {
|
||||
HttpSession session = SpringContextUtils.getHttpServletRequest().getSession();
|
||||
returnValue = (String) session.getAttribute(key);
|
||||
}
|
||||
//结果加上${} 后面的值
|
||||
if (returnValue != null) {
|
||||
returnValue = returnValue + moshi;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前用户中获取变量
|
||||
*
|
||||
* @param key
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public static String getUserSystemData(String key, SysUserCacheInfo user) {
|
||||
if (user == null) {
|
||||
user = JeecgDataAutorUtils.loadUserInfo();
|
||||
}
|
||||
//#{sys_user_code}%
|
||||
|
||||
// 获取登录用户信息
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
String moshi = "";
|
||||
String wellNumber = WELL_NUMBER;
|
||||
if (key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET) != -1) {
|
||||
moshi = key.substring(key.indexOf("}") + 1);
|
||||
}
|
||||
String returnValue = null;
|
||||
//针对特殊标示处理#{sysOrgCode},判断替换
|
||||
if (key.contains(wellNumber)) {
|
||||
key = key.substring(2, key.indexOf("}"));
|
||||
} else {
|
||||
key = key;
|
||||
}
|
||||
//替换为系统登录用户帐号
|
||||
if (key.equals(DataBaseConstant.SYS_USER_CODE) || key.toLowerCase().equals(DataBaseConstant.SYS_USER_CODE_TABLE)) {
|
||||
if (user == null) {
|
||||
returnValue = sysUser.getUsername();
|
||||
} else {
|
||||
returnValue = user.getSysUserCode();
|
||||
}
|
||||
}
|
||||
//替换为系统登录用户真实名字
|
||||
else if (key.equals(DataBaseConstant.SYS_USER_NAME) || key.toLowerCase().equals(DataBaseConstant.SYS_USER_NAME_TABLE)) {
|
||||
if (user == null) {
|
||||
returnValue = sysUser.getRealname();
|
||||
} else {
|
||||
returnValue = user.getSysUserName();
|
||||
}
|
||||
}
|
||||
|
||||
//替换为系统用户登录所使用的机构编码
|
||||
else if (key.equals(DataBaseConstant.SYS_ORG_CODE) || key.toLowerCase().equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) {
|
||||
// if (user == null) {
|
||||
// returnValue = sysUser.getOrgCode();
|
||||
// } else {
|
||||
// returnValue = user.getSysOrgCode();
|
||||
// }
|
||||
}
|
||||
//替换为系统用户所拥有的所有机构编码
|
||||
else if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE) || key.toLowerCase().equals(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) {
|
||||
if (user == null) {
|
||||
//TODO 暂时使用用户登录部门,存在逻辑缺陷,不是用户所拥有的部门
|
||||
// returnValue = sysUser.getOrgCode();
|
||||
} else {
|
||||
if (user.isOneDepart()) {
|
||||
returnValue = user.getSysMultiOrgCode().get(0);
|
||||
} else {
|
||||
returnValue = Joiner.on(",").join(user.getSysMultiOrgCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
//替换为当前系统时间(年月日)
|
||||
else if (key.equals(DataBaseConstant.SYS_DATE) || key.toLowerCase().equals(DataBaseConstant.SYS_DATE_TABLE)) {
|
||||
returnValue = DateUtils.formatDate();
|
||||
}
|
||||
//替换为当前系统时间(年月日时分秒)
|
||||
else if (key.equals(DataBaseConstant.SYS_TIME) || key.toLowerCase().equals(DataBaseConstant.SYS_TIME_TABLE)) {
|
||||
returnValue = DateUtils.now();
|
||||
}
|
||||
//流程状态默认值(默认未发起)
|
||||
else if (key.equals(DataBaseConstant.BPM_STATUS) || key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) {
|
||||
returnValue = "1";
|
||||
}
|
||||
//update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||
else if (key.equals(DataBaseConstant.TENANT_ID) || key.toLowerCase().equals(DataBaseConstant.TENANT_ID_TABLE)) {
|
||||
// returnValue = sysUser.getRelTenantIds();
|
||||
boolean flag = returnValue != null && returnValue.indexOf(SymbolConstant.COMMA) > 0;
|
||||
if (oConvertUtils.isEmpty(returnValue) || flag) {
|
||||
returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||
if (returnValue != null) {
|
||||
returnValue = returnValue + moshi;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUzMzY1MTMsInVzZXJuYW1lIjoiYWRtaW4ifQ.xjhud_tWCNYBOg_aRlMgOdlZoWFFKB_givNElHNw3X0";
|
||||
// System.out.println(JwtUtil.getUsername(token));
|
||||
// }
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package digital.util.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ListToStringConverter {
|
||||
public static String convert(List<String> list) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
sb.append(list.get(i));
|
||||
if (i < list.size() - 1) {
|
||||
sb.append("-");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package digital.util.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* @Description: 加密工具
|
||||
*
|
||||
* update: 【类名改了大小写】 date: 2022-04-18
|
||||
* @author: smcp
|
||||
*/
|
||||
public class Md5Util {
|
||||
|
||||
private static final String[] HEXDIGITS = { "0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
|
||||
|
||||
public static String byteArrayToHexString(byte[] b) {
|
||||
StringBuffer resultSb = new StringBuffer();
|
||||
for (int i = 0; i < b.length; i++){
|
||||
resultSb.append(byteToHexString(b[i]));
|
||||
}
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
private static String byteToHexString(byte b) {
|
||||
int n = b;
|
||||
if (n < 0) {
|
||||
n += 256;
|
||||
}
|
||||
int d1 = n / 16;
|
||||
int d2 = n % 16;
|
||||
return HEXDIGITS[d1] + HEXDIGITS[d2];
|
||||
}
|
||||
|
||||
public static String md5Encode(String origin, String charsetname) {
|
||||
String resultString = null;
|
||||
try {
|
||||
resultString = new String(origin);
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
if (charsetname == null || "".equals(charsetname)) {
|
||||
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
|
||||
} else {
|
||||
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
//package digital.util.util;
|
||||
//
|
||||
//import io.minio.*;
|
||||
//import io.minio.http.Method;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.web.multipart.MultipartFile;
|
||||
//import digital.base.constant.SymbolConstant;
|
||||
//import digital.util.util.filter.FileTypeFilter;
|
||||
//import digital.util.util.filter.StrAttackFilter;
|
||||
//
|
||||
//import java.io.InputStream;
|
||||
//import java.net.URLDecoder;
|
||||
//
|
||||
///**
|
||||
// * minio文件上传工具类
|
||||
// * @author: smcp
|
||||
// */
|
||||
//@Slf4j
|
||||
//public class MinioUtil {
|
||||
// private static String minioUrl;
|
||||
// private static String minioName;
|
||||
// private static String minioPass;
|
||||
// private static String bucketName;
|
||||
//
|
||||
// public static void setMinioUrl(String minioUrl) {
|
||||
// MinioUtil.minioUrl = minioUrl;
|
||||
// }
|
||||
//
|
||||
// public static void setMinioName(String minioName) {
|
||||
// MinioUtil.minioName = minioName;
|
||||
// }
|
||||
//
|
||||
// public static void setMinioPass(String minioPass) {
|
||||
// MinioUtil.minioPass = minioPass;
|
||||
// }
|
||||
//
|
||||
// public static void setBucketName(String bucketName) {
|
||||
// MinioUtil.bucketName = bucketName;
|
||||
// }
|
||||
//
|
||||
// public static String getMinioUrl() {
|
||||
// return minioUrl;
|
||||
// }
|
||||
//
|
||||
// public static String getBucketName() {
|
||||
// return bucketName;
|
||||
// }
|
||||
//
|
||||
// private static MinioClient minioClient = null;
|
||||
//
|
||||
// /**
|
||||
// * 上传文件
|
||||
// * @param file
|
||||
// * @return
|
||||
// */
|
||||
// public static String upload(MultipartFile file, String bizPath, String customBucket) {
|
||||
// String fileUrl = "";
|
||||
// //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
|
||||
// bizPath = StrAttackFilter.filter(bizPath);
|
||||
// //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
|
||||
// String newBucket = bucketName;
|
||||
// if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
// newBucket = customBucket;
|
||||
// }
|
||||
// try {
|
||||
// initMinio(minioUrl, minioName,minioPass);
|
||||
// // 检查存储桶是否已经存在
|
||||
// if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(newBucket).build())) {
|
||||
// log.info("Bucket already exists.");
|
||||
// } else {
|
||||
// // 创建一个名为ota的存储桶
|
||||
// minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
|
||||
// log.info("create a new bucket.");
|
||||
// }
|
||||
// //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
||||
// FileTypeFilter.fileTypeFilter(file);
|
||||
// //update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
||||
// InputStream stream = file.getInputStream();
|
||||
// // 获取文件名
|
||||
// String orgName = file.getOriginalFilename();
|
||||
// if("".equals(orgName)){
|
||||
// orgName=file.getName();
|
||||
// }
|
||||
// orgName = CommonUtils.getFileName(orgName);
|
||||
// String objectName = bizPath+"/"
|
||||
// +( orgName.indexOf(".")==-1
|
||||
// ?orgName + "_" + System.currentTimeMillis()
|
||||
// :orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."))
|
||||
// );
|
||||
//
|
||||
// // 使用putObject上传一个本地文件到存储桶中。
|
||||
// if(objectName.startsWith(SymbolConstant.SINGLE_SLASH)){
|
||||
// objectName = objectName.substring(1);
|
||||
// }
|
||||
// PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
|
||||
// .bucket(newBucket)
|
||||
// .contentType("application/octet-stream")
|
||||
// .stream(stream,stream.available(),-1).build();
|
||||
// minioClient.putObject(objectArgs);
|
||||
// stream.close();
|
||||
// fileUrl = minioUrl+newBucket+"/"+objectName;
|
||||
// }catch (Exception e){
|
||||
// log.error(e.getMessage(), e);
|
||||
// }
|
||||
// return fileUrl;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 文件上传
|
||||
// * @param file
|
||||
// * @param bizPath
|
||||
// * @return
|
||||
// */
|
||||
// public static String upload(MultipartFile file, String bizPath) {
|
||||
// return upload(file,bizPath,null);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取文件流
|
||||
// * @param bucketName
|
||||
// * @param objectName
|
||||
// * @return
|
||||
// */
|
||||
// public static InputStream getMinioFile(String bucketName,String objectName){
|
||||
// InputStream inputStream = null;
|
||||
// try {
|
||||
// initMinio(minioUrl, minioName, minioPass);
|
||||
// GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName)
|
||||
// .bucket(bucketName).build();
|
||||
// inputStream = minioClient.getObject(objectArgs);
|
||||
// } catch (Exception e) {
|
||||
// log.info("文件获取失败" + e.getMessage());
|
||||
// }
|
||||
// return inputStream;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 删除文件
|
||||
// * @param bucketName
|
||||
// * @param objectName
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public static void removeObject(String bucketName, String objectName) {
|
||||
// try {
|
||||
// initMinio(minioUrl, minioName,minioPass);
|
||||
// RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(objectName)
|
||||
// .bucket(bucketName).build();
|
||||
// minioClient.removeObject(objectArgs);
|
||||
// }catch (Exception e){
|
||||
// log.info("文件删除失败" + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取文件外链
|
||||
// * @param bucketName
|
||||
// * @param objectName
|
||||
// * @param expires
|
||||
// * @return
|
||||
// */
|
||||
// public static String getObjectUrl(String bucketName, String objectName, Integer expires) {
|
||||
// initMinio(minioUrl, minioName,minioPass);
|
||||
// try{
|
||||
// //update-begin---author:liusq Date:20220121 for:获取文件外链报错提示method不能为空,导致文件下载和预览失败----
|
||||
// GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName)
|
||||
// .bucket(bucketName)
|
||||
// .expiry(expires).method(Method.GET).build();
|
||||
// //update-begin---author:liusq Date:20220121 for:获取文件外链报错提示method不能为空,导致文件下载和预览失败----
|
||||
// String url = minioClient.getPresignedObjectUrl(objectArgs);
|
||||
// return URLDecoder.decode(url,"UTF-8");
|
||||
// }catch (Exception e){
|
||||
// log.info("文件路径获取失败" + e.getMessage());
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 初始化客户端
|
||||
// * @param minioUrl
|
||||
// * @param minioName
|
||||
// * @param minioPass
|
||||
// * @return
|
||||
// */
|
||||
// private static MinioClient initMinio(String minioUrl, String minioName,String minioPass) {
|
||||
// if (minioClient == null) {
|
||||
// try {
|
||||
// minioClient = MinioClient.builder()
|
||||
// .endpoint(minioUrl)
|
||||
// .credentials(minioName, minioPass)
|
||||
// .build();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// return minioClient;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 上传文件到minio
|
||||
// * @param stream
|
||||
// * @param relativePath
|
||||
// * @return
|
||||
// */
|
||||
// public static String upload(InputStream stream,String relativePath) throws Exception {
|
||||
// initMinio(minioUrl, minioName,minioPass);
|
||||
// if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
|
||||
// log.info("Bucket already exists.");
|
||||
// } else {
|
||||
// // 创建一个名为ota的存储桶
|
||||
// minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
// log.info("create a new bucket.");
|
||||
// }
|
||||
// PutObjectArgs objectArgs = PutObjectArgs.builder().object(relativePath)
|
||||
// .bucket(bucketName)
|
||||
// .contentType("application/octet-stream")
|
||||
// .stream(stream,stream.available(),-1).build();
|
||||
// minioClient.putObject(objectArgs);
|
||||
// stream.close();
|
||||
// return minioUrl+bucketName+"/"+relativePath;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,106 @@
|
||||
package digital.util.util;
|
||||
|
||||
|
||||
import digital.base.constant.SymbolConstant;
|
||||
|
||||
/**
|
||||
* @Author 张代浩
|
||||
*/
|
||||
public class MyClassLoader extends ClassLoader {
|
||||
public static Class getClassByScn(String className) {
|
||||
Class myclass = null;
|
||||
try {
|
||||
myclass = Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(className+" not found!");
|
||||
}
|
||||
return myclass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得类的全名,包括包名
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static String getPackPath(Object object) {
|
||||
// 检查用户传入的参数是否为空
|
||||
if (object == null) {
|
||||
throw new java.lang.IllegalArgumentException("参数不能为空!");
|
||||
}
|
||||
// 获得类的全名,包括包名
|
||||
String clsName = object.getClass().getName();
|
||||
return clsName;
|
||||
}
|
||||
|
||||
public static String getAppPath(Class cls) {
|
||||
// 检查用户传入的参数是否为空
|
||||
if (cls == null) {
|
||||
throw new java.lang.IllegalArgumentException("参数不能为空!");
|
||||
}
|
||||
ClassLoader loader = cls.getClassLoader();
|
||||
// 获得类的全名,包括包名
|
||||
String clsName = cls.getName() + ".class";
|
||||
// 获得传入参数所在的包
|
||||
Package pack = cls.getPackage();
|
||||
String path = "";
|
||||
// 如果不是匿名包,将包名转化为路径
|
||||
if (pack != null) {
|
||||
String packName = pack.getName();
|
||||
String javaSpot="java.";
|
||||
String javaxSpot="javax.";
|
||||
// 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库
|
||||
if (packName.startsWith(javaSpot) || packName.startsWith(javaxSpot)) {
|
||||
throw new java.lang.IllegalArgumentException("不要传送系统类!");
|
||||
}
|
||||
// 在类的名称中,去掉包名的部分,获得类的文件名
|
||||
clsName = clsName.substring(packName.length() + 1);
|
||||
// 判定包名是否是简单包名,如果是,则直接将包名转换为路径,
|
||||
if (packName.indexOf(SymbolConstant.SPOT) < 0) {
|
||||
path = packName + "/";
|
||||
} else {
|
||||
// 否则按照包名的组成部分,将包名转换为路径
|
||||
int start = 0, end = 0;
|
||||
end = packName.indexOf(".");
|
||||
StringBuilder pathBuilder = new StringBuilder();
|
||||
while (end != -1) {
|
||||
pathBuilder.append(packName, start, end).append("/");
|
||||
start = end + 1;
|
||||
end = packName.indexOf(".", start);
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(pathBuilder.toString())){
|
||||
path = pathBuilder.toString();
|
||||
}
|
||||
path = path + packName.substring(start) + "/";
|
||||
}
|
||||
}
|
||||
// 调用ClassLoader的getResource方法,传入包含路径信息的类文件名
|
||||
java.net.URL url = loader.getResource(path + clsName);
|
||||
// 从URL对象中获取路径信息
|
||||
String realPath = url.getPath();
|
||||
// 去掉路径信息中的协议名"file:"
|
||||
int pos = realPath.indexOf("file:");
|
||||
if (pos > -1) {
|
||||
realPath = realPath.substring(pos + 5);
|
||||
}
|
||||
// 去掉路径信息最后包含类文件信息的部分,得到类所在的路径
|
||||
pos = realPath.indexOf(path + clsName);
|
||||
realPath = realPath.substring(0, pos - 1);
|
||||
// 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名
|
||||
if (realPath.endsWith(SymbolConstant.EXCLAMATORY_MARK)) {
|
||||
realPath = realPath.substring(0, realPath.lastIndexOf("/"));
|
||||
}
|
||||
/*------------------------------------------------------------
|
||||
ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径
|
||||
中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要
|
||||
的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的
|
||||
中文及空格路径
|
||||
-------------------------------------------------------------*/
|
||||
try {
|
||||
realPath = java.net.URLDecoder.decode(realPath, "utf-8");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return realPath;
|
||||
}// getAppPath定义结束
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package digital.util.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
import java.security.Key;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* @Description: 密码工具类
|
||||
* @author: smcp
|
||||
*/
|
||||
public class PasswordUtil {
|
||||
|
||||
/**
|
||||
* JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
|
||||
* PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
|
||||
* */
|
||||
|
||||
/**
|
||||
* 定义使用的算法为:PBEWITHMD5andDES算法
|
||||
* 加密算法
|
||||
*/
|
||||
public static final String ALGORITHM = "PBEWithMD5AndDES";
|
||||
|
||||
/**
|
||||
* 定义使用的算法为:PBEWITHMD5andDES算法
|
||||
* 密钥
|
||||
*/
|
||||
public static final String SALT = "63293188";
|
||||
|
||||
/**
|
||||
* 定义迭代次数为1000次
|
||||
*/
|
||||
private static final int ITERATIONCOUNT = 1000;
|
||||
|
||||
/**
|
||||
* 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
|
||||
*
|
||||
* @return byte[] 盐值
|
||||
* */
|
||||
public static byte[] getSalt() throws Exception {
|
||||
// 实例化安全随机数
|
||||
SecureRandom random = new SecureRandom();
|
||||
// 产出盐
|
||||
return random.generateSeed(8);
|
||||
}
|
||||
|
||||
public static byte[] getStaticSalt() {
|
||||
// 产出盐
|
||||
return SALT.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据PBE密码生成一把密钥
|
||||
*
|
||||
* @param password
|
||||
* 生成密钥时所使用的密码
|
||||
* @return Key PBE算法密钥
|
||||
* */
|
||||
private static Key getPbeKey(String password) {
|
||||
// 实例化使用的算法
|
||||
SecretKeyFactory keyFactory;
|
||||
SecretKey secretKey = null;
|
||||
try {
|
||||
keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
|
||||
// 设置PBE密钥参数
|
||||
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
|
||||
// 生成密钥
|
||||
secretKey = keyFactory.generateSecret(keySpec);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密明文字符串
|
||||
*
|
||||
* @param plaintext
|
||||
* 待加密的明文字符串
|
||||
* @param password
|
||||
* 生成密钥时所使用的密码
|
||||
* @param salt
|
||||
* 盐值
|
||||
* @return 加密后的密文字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String plaintext, String password, String salt) {
|
||||
|
||||
Key key = getPbeKey(password);
|
||||
byte[] encipheredData = null;
|
||||
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
|
||||
//update-begin-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
|
||||
encipheredData = cipher.doFinal(plaintext.getBytes("utf-8"));
|
||||
//update-end-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return bytesToHexString(encipheredData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密密文字符串
|
||||
*
|
||||
* @param ciphertext
|
||||
* 待解密的密文字符串
|
||||
* @param password
|
||||
* 生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
|
||||
* @param salt
|
||||
* 盐值(如需解密,该参数需要与加密时使用的一致)
|
||||
* @return 解密后的明文字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String decrypt(String ciphertext, String password, String salt) {
|
||||
|
||||
Key key = getPbeKey(password);
|
||||
byte[] passDec = null;
|
||||
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
|
||||
|
||||
passDec = cipher.doFinal(hexStringToBytes(ciphertext));
|
||||
}
|
||||
|
||||
catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
return new String(passDec);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param src
|
||||
* 字节数组
|
||||
* @return
|
||||
*/
|
||||
public static String bytesToHexString(byte[] src) {
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
if (src == null || src.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
int v = src[i] & 0xFF;
|
||||
String hv = Integer.toHexString(v);
|
||||
if (hv.length() < 2) {
|
||||
stringBuilder.append(0);
|
||||
}
|
||||
stringBuilder.append(hv);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符串转换为字节数组
|
||||
*
|
||||
* @param hexString
|
||||
* 十六进制字符串
|
||||
* @return
|
||||
*/
|
||||
public static byte[] hexStringToBytes(String hexString) {
|
||||
if (hexString == null || "".equals(hexString)) {
|
||||
return null;
|
||||
}
|
||||
hexString = hexString.toUpperCase();
|
||||
int length = hexString.length() / 2;
|
||||
char[] hexChars = hexString.toCharArray();
|
||||
byte[] d = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int pos = i * 2;
|
||||
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private static byte charToByte(char c) {
|
||||
return (byte) "0123456789ABCDEF".indexOf(c);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 使用Spring自身提供的地址匹配工具匹配URL
|
||||
*
|
||||
* @author: smcp
|
||||
*/
|
||||
public class PathMatcherUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String url = "/sys/dict/loadDictOrderByValue/tree,s2,2";
|
||||
String p = "/sys/dict/loadDictOrderByValue/*";
|
||||
|
||||
System.out.println(PathMatcherUtil.match(p,url));
|
||||
}
|
||||
|
||||
/**
|
||||
* 实际验证路径匹配权限
|
||||
*
|
||||
* @param matchPath 权限url
|
||||
* @param path 访问路径
|
||||
* @return 是否拥有权限
|
||||
*/
|
||||
public static boolean match(String matchPath, String path) {
|
||||
SpringAntMatcher springAntMatcher = new SpringAntMatcher(matchPath, true);
|
||||
return springAntMatcher.matches(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实际验证路径匹配权限
|
||||
*
|
||||
* @param list 权限url
|
||||
* @param path 访问路径
|
||||
* @return 是否拥有权限
|
||||
*/
|
||||
public static boolean matches(Collection<String> list, String path) {
|
||||
for (String s : list) {
|
||||
SpringAntMatcher springAntMatcher = new SpringAntMatcher(s, true);
|
||||
if (springAntMatcher.matches(path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 地址表达式匹配工具
|
||||
*/
|
||||
private static class SpringAntMatcher implements Matcher {
|
||||
private final AntPathMatcher antMatcher;
|
||||
private final String pattern;
|
||||
|
||||
private SpringAntMatcher(String pattern, boolean caseSensitive) {
|
||||
this.pattern = pattern;
|
||||
this.antMatcher = createMatcher(caseSensitive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String path) {
|
||||
return this.antMatcher.match(this.pattern, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> extractUriTemplateVariables(String path) {
|
||||
return this.antMatcher.extractUriTemplateVariables(this.pattern, path);
|
||||
}
|
||||
|
||||
private static AntPathMatcher createMatcher(boolean caseSensitive) {
|
||||
AntPathMatcher matcher = new AntPathMatcher();
|
||||
matcher.setTrimTokens(false);
|
||||
matcher.setCaseSensitive(caseSensitive);
|
||||
return matcher;
|
||||
}
|
||||
}
|
||||
|
||||
private interface Matcher {
|
||||
|
||||
/**
|
||||
* 实际验证路径匹配权限
|
||||
* @param var1
|
||||
* @return
|
||||
*/
|
||||
boolean matches(String var1);
|
||||
|
||||
/**
|
||||
* 提取path中匹配到的部分
|
||||
* @param var1
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> extractUriTemplateVariables(String var1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package digital.util.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: PmsUtil
|
||||
* @author: smcp
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PmsUtil {
|
||||
|
||||
|
||||
private static String uploadPath;
|
||||
|
||||
@Value("${jeecg.path.upload}")
|
||||
public void setUploadPath(String uploadPath) {
|
||||
PmsUtil.uploadPath = uploadPath;
|
||||
}
|
||||
|
||||
public static String saveErrorTxtByList(List<String> msg, String name) {
|
||||
Date d = new Date();
|
||||
String saveDir = "logs" + File.separator + DateUtils.yyyyMMdd.get().format(d) + File.separator;
|
||||
String saveFullDir = uploadPath + File.separator + saveDir;
|
||||
|
||||
File saveFile = new File(saveFullDir);
|
||||
if (!saveFile.exists()) {
|
||||
saveFile.mkdirs();
|
||||
}
|
||||
name += DateUtils.yyyymmddhhmmss.get().format(d) + Math.round(Math.random() * 10000);
|
||||
String saveFilePath = saveFullDir + name + ".txt";
|
||||
|
||||
try {
|
||||
//封装目的地
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(saveFilePath));
|
||||
//遍历集合
|
||||
for (String s : msg) {
|
||||
//写数据
|
||||
if (s.indexOf("_") > 0) {
|
||||
String[] arr = s.split("_");
|
||||
bw.write("第" + arr[0] + "行:" + arr[1]);
|
||||
} else {
|
||||
bw.write(s);
|
||||
}
|
||||
//bw.newLine();
|
||||
bw.write("\r\n");
|
||||
}
|
||||
//释放资源
|
||||
bw.flush();
|
||||
bw.close();
|
||||
} catch (Exception e) {
|
||||
log.info("excel导入生成错误日志文件异常:" + e.getMessage());
|
||||
}
|
||||
return saveDir + name + ".txt";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
//package digital.util.util;
|
||||
//
|
||||
//import org.springframework.stereotype.Component;
|
||||
//import java.io.File;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//import java.util.Scanner;
|
||||
//
|
||||
///**
|
||||
// * @Description: 省市区
|
||||
// * @author: smcp
|
||||
// */
|
||||
//@Component("pca")
|
||||
//public class ProvinceCityArea {
|
||||
// List<Area> areaList;
|
||||
//
|
||||
// public String getText(String code) {
|
||||
// this.initAreaList();
|
||||
// if (this.areaList != null || this.areaList.size() > 0) {
|
||||
// List<String> ls = new ArrayList<String>();
|
||||
// getAreaByCode(code, ls);
|
||||
// return String.join("/", ls);
|
||||
// }
|
||||
// return "";
|
||||
// }
|
||||
//
|
||||
// public String getCode(String text) {
|
||||
// this.initAreaList();
|
||||
// if (areaList != null && areaList.size() > 0) {
|
||||
// for (int i = areaList.size() - 1; i >= 0; i--) {
|
||||
// if (text.indexOf(areaList.get(i).getText()) >= 0) {
|
||||
// return areaList.get(i).getId();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// // update-begin-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
|
||||
//
|
||||
// /**
|
||||
// * 获取省市区code,精准匹配
|
||||
// *
|
||||
// * @param texts 文本数组,省,市,区
|
||||
// * @return 返回 省市区的code
|
||||
// */
|
||||
// public String[] getCode(String[] texts) {
|
||||
// if (texts == null || texts.length == 0) {
|
||||
// return null;
|
||||
// }
|
||||
// this.initAreaList();
|
||||
// if (areaList == null || areaList.size() == 0) {
|
||||
// return null;
|
||||
// }
|
||||
// String[] codes = new String[texts.length];
|
||||
// String code = null;
|
||||
// for (int i = 0; i < texts.length; i++) {
|
||||
// String text = texts[i];
|
||||
// Area userFile;
|
||||
// if (code == null) {
|
||||
// userFile = getAreaByText(text);
|
||||
// } else {
|
||||
// userFile = getAreaByPidAndText(code, text);
|
||||
// }
|
||||
// if (userFile != null) {
|
||||
// code = userFile.id;
|
||||
// codes[i] = code;
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// return codes;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据text获取area
|
||||
// *
|
||||
// * @param text
|
||||
// * @return
|
||||
// */
|
||||
// public Area getAreaByText(String text) {
|
||||
// for (Area userFile : areaList) {
|
||||
// if (text.equals(userFile.getText())) {
|
||||
// return userFile;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 通过pid获取 userFile 对象
|
||||
// *
|
||||
// * @param pCode 父级编码
|
||||
// * @param text
|
||||
// * @return
|
||||
// */
|
||||
// public Area getAreaByPidAndText(String pCode, String text) {
|
||||
// this.initAreaList();
|
||||
// if (this.areaList != null && this.areaList.size() > 0) {
|
||||
// for (Area userFile : this.areaList) {
|
||||
// if (userFile.getPid().equals(pCode) && userFile.getText().equals(text)) {
|
||||
// return userFile;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
// // update-end-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
|
||||
//
|
||||
// public void getAreaByCode(String code, List<String> ls) {
|
||||
// for (Area userFile : areaList) {
|
||||
// if (userFile.getId().equals(code)) {
|
||||
// String pid = userFile.getPid();
|
||||
// ls.add(0, userFile.getText());
|
||||
// getAreaByCode(pid, ls);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
////
|
||||
//// private void initAreaList() {
|
||||
//// //System.out.println("=====================");
|
||||
//// if (this.areaList == null || this.areaList.size() == 0) {
|
||||
//// this.areaList = new ArrayList<Area>();
|
||||
//// try {
|
||||
//// String jsonData = oConvertUtils.readStatic("classpath:static/pca.json");
|
||||
//// JSONObject baseJson = JSONObject.parseObject(jsonData);
|
||||
//// //第一层 省
|
||||
//// JSONObject provinceJson = baseJson.getJSONObject("86");
|
||||
//// for (String provinceKey : provinceJson.keySet()) {
|
||||
//// //System.out.println("===="+provinceKey);
|
||||
//// Area province = new Area(provinceKey, provinceJson.getString(provinceKey), "86");
|
||||
//// this.areaList.add(province);
|
||||
//// //第二层 市
|
||||
//// JSONObject cityJson = baseJson.getJSONObject(provinceKey);
|
||||
//// for (String cityKey : cityJson.keySet()) {
|
||||
//// //System.out.println("-----"+cityKey);
|
||||
//// Area city = new Area(cityKey, cityJson.getString(cityKey), provinceKey);
|
||||
//// this.areaList.add(city);
|
||||
//// //第三层 区
|
||||
//// JSONObject areaJson = baseJson.getJSONObject(cityKey);
|
||||
//// if (areaJson != null) {
|
||||
//// for (String areaKey : areaJson.keySet()) {
|
||||
//// //System.out.println("········"+areaKey);
|
||||
//// Area userFile = new Area(areaKey, areaJson.getString(areaKey), cityKey);
|
||||
//// this.areaList.add(userFile);
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// } catch (Exception e) {
|
||||
//// e.printStackTrace();
|
||||
//// }
|
||||
//// }
|
||||
////
|
||||
//// }
|
||||
//
|
||||
//
|
||||
// private String jsonRead(File file) {
|
||||
// Scanner scanner = null;
|
||||
// StringBuilder buffer = new StringBuilder();
|
||||
// try {
|
||||
// scanner = new Scanner(file, "utf-8");
|
||||
// while (scanner.hasNextLine()) {
|
||||
// buffer.append(scanner.nextLine());
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
//
|
||||
// } finally {
|
||||
// if (scanner != null) {
|
||||
// scanner.close();
|
||||
// }
|
||||
// }
|
||||
// return buffer.toString();
|
||||
// }
|
||||
//
|
||||
// class Area {
|
||||
// String id;
|
||||
// String text;
|
||||
// String pid;
|
||||
//
|
||||
// public Area(String id, String text, String pid) {
|
||||
// this.id = id;
|
||||
// this.text = text;
|
||||
// this.pid = pid;
|
||||
// }
|
||||
//
|
||||
// public String getId() {
|
||||
// return id;
|
||||
// }
|
||||
//
|
||||
// public String getText() {
|
||||
// return text;
|
||||
// }
|
||||
//
|
||||
// public String getPid() {
|
||||
// return pid;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,255 @@
|
||||
package digital.util.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author 张代浩
|
||||
* @desc 通过反射来动态调用get 和 set 方法
|
||||
*/
|
||||
@Slf4j
|
||||
public class ReflectHelper {
|
||||
|
||||
private Class cls;
|
||||
|
||||
/**
|
||||
* 传过来的对象
|
||||
*/
|
||||
private Object obj;
|
||||
|
||||
/**
|
||||
* 存放get方法
|
||||
*/
|
||||
private Hashtable<String, Method> getMethods = null;
|
||||
/**
|
||||
* 存放set方法
|
||||
*/
|
||||
private Hashtable<String, Method> setMethods = null;
|
||||
|
||||
/**
|
||||
* 定义构造方法 -- 一般来说是个pojo
|
||||
*
|
||||
* @param o 目标对象
|
||||
*/
|
||||
public ReflectHelper(Object o) {
|
||||
obj = o;
|
||||
initMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 初始化
|
||||
*/
|
||||
public void initMethods() {
|
||||
getMethods = new Hashtable<String, Method>();
|
||||
setMethods = new Hashtable<String, Method>();
|
||||
cls = obj.getClass();
|
||||
Method[] methods = cls.getMethods();
|
||||
// 定义正则表达式,从方法中过滤出getter / setter 函数.
|
||||
String gs = "get(\\w+)";
|
||||
Pattern getM = Pattern.compile(gs);
|
||||
String ss = "set(\\w+)";
|
||||
Pattern setM = Pattern.compile(ss);
|
||||
// 把方法中的"set" 或者 "get" 去掉
|
||||
String rapl = "$1";
|
||||
String param;
|
||||
for (int i = 0; i < methods.length; ++i) {
|
||||
Method m = methods[i];
|
||||
String methodName = m.getName();
|
||||
if (Pattern.matches(gs, methodName)) {
|
||||
param = getM.matcher(methodName).replaceAll(rapl).toLowerCase();
|
||||
getMethods.put(param, m);
|
||||
} else if (Pattern.matches(ss, methodName)) {
|
||||
param = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
|
||||
setMethods.put(param, m);
|
||||
} else {
|
||||
// logger.info(methodName + " 不是getter,setter方法!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 调用set方法
|
||||
*/
|
||||
public boolean setMethodValue(String property, Object object) {
|
||||
Method m = setMethods.get(property.toLowerCase());
|
||||
if (m != null) {
|
||||
try {
|
||||
// 调用目标类的setter函数
|
||||
m.invoke(obj, object);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
log.info("invoke getter on " + property + " error: " + ex.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 调用set方法
|
||||
*/
|
||||
public Object getMethodValue(String property) {
|
||||
Object value = null;
|
||||
Method m = getMethods.get(property.toLowerCase());
|
||||
if (m != null) {
|
||||
try {
|
||||
/*
|
||||
* 调用obj类的setter函数
|
||||
*/
|
||||
value = m.invoke(obj, new Object[]{});
|
||||
|
||||
} catch (Exception ex) {
|
||||
log.info("invoke getter on " + property + " error: " + ex.toString());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把map中的内容全部注入到obj中
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public Object setAll(Map<String, Object> data) {
|
||||
if (data == null || data.keySet().size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (Entry<String, Object> entry : data.entrySet()) {
|
||||
this.setMethodValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把map中的内容全部注入到obj中
|
||||
*
|
||||
* @param o
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Object setAll(Object o, Map<String, Object> data) {
|
||||
ReflectHelper reflectHelper = new ReflectHelper(o);
|
||||
reflectHelper.setAll(data);
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把map中的内容全部注入到新实例中
|
||||
*
|
||||
* @param clazz
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T setAll(Class<T> clazz, Map<String, Object> data) {
|
||||
T o = null;
|
||||
try {
|
||||
o = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
o = null;
|
||||
return o;
|
||||
}
|
||||
return (T) setAll(o, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据传入的class将mapList转换为实体类list
|
||||
*
|
||||
* @param mapist
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> transList2Entrys(List<Map<String, Object>> mapist, Class<T> clazz) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
if (mapist != null && mapist.size() > 0) {
|
||||
for (Map<String, Object> data : mapist) {
|
||||
list.add(ReflectHelper.setAll(clazz, data));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据属性名获取属性值
|
||||
*/
|
||||
public static Object getFieldValueByName(String fieldName, Object o) {
|
||||
try {
|
||||
String firstLetter = fieldName.substring(0, 1).toUpperCase();
|
||||
String getter = "get" + firstLetter + fieldName.substring(1);
|
||||
Method method = o.getClass().getMethod(getter, new Class[]{});
|
||||
Object value = method.invoke(o, new Object[]{});
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性值
|
||||
*/
|
||||
public static Object getFieldVal(String fieldName, Object o) {
|
||||
try {
|
||||
// 暴力反射获取属性
|
||||
Field filed = o.getClass().getDeclaredField(fieldName);
|
||||
// 设置反射时取消Java的访问检查,暴力访问
|
||||
filed.setAccessible(true);
|
||||
Object val = filed.get(o);
|
||||
return val;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性名数组
|
||||
*/
|
||||
public static String[] getFiledName(Object o) {
|
||||
Field[] fields = o.getClass().getDeclaredFields();
|
||||
String[] fieldNames = new String[fields.length];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
//log.info(fields[i].getType());
|
||||
fieldNames[i] = fields[i].getName();
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
|
||||
*/
|
||||
public static List<Map> getFiledsInfo(Object o) {
|
||||
Field[] fields = o.getClass().getDeclaredFields();
|
||||
String[] fieldNames = new String[fields.length];
|
||||
List<Map> list = new ArrayList<Map>();
|
||||
Map<String, Object> infoMap = null;
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
infoMap = new HashMap<>(5);
|
||||
infoMap.put("type", fields[i].getType().toString());
|
||||
infoMap.put("name", fields[i].getName());
|
||||
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
|
||||
list.add(infoMap);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的所有属性值,返回一个对象数组
|
||||
*/
|
||||
public static Object[] getFiledValues(Object o) {
|
||||
String[] fieldNames = getFiledName(o);
|
||||
Object[] value = new Object[fieldNames.length];
|
||||
for (int i = 0; i < fieldNames.length; i++) {
|
||||
value[i] = getFieldValueByName(fieldNames[i], o);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import digital.base.vo.Result;
|
||||
|
||||
|
||||
/**
|
||||
* 通过 RESTful 风格的接口操纵 desform 里的数据
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
public class RestDesformUtil {
|
||||
|
||||
private static String domain = null;
|
||||
private static String path = null;
|
||||
|
||||
static {
|
||||
domain = SpringContextUtils.getDomain();
|
||||
path = oConvertUtils.getString(SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据
|
||||
*
|
||||
* @param desformCode
|
||||
* @param dataId
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public static Result queryOne(String desformCode, String dataId, String token) {
|
||||
String url = getBaseUrl(desformCode, dataId).toString();
|
||||
HttpHeaders headers = getHeaders(token);
|
||||
ResponseEntity<JSONObject> result = RestUtil.request(url, HttpMethod.GET, headers, null, null, JSONObject.class);
|
||||
return packageReturn(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增数据
|
||||
*
|
||||
* @param desformCode
|
||||
* @param formData
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public static Result addOne(String desformCode, JSONObject formData, String token) {
|
||||
return addOrEditOne(desformCode, formData, token, HttpMethod.POST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改数据
|
||||
*
|
||||
* @param desformCode
|
||||
* @param formData
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public static Result editOne(String desformCode, JSONObject formData, String token) {
|
||||
return addOrEditOne(desformCode, formData, token, HttpMethod.PUT);
|
||||
}
|
||||
|
||||
private static Result addOrEditOne(String desformCode, JSONObject formData, String token, HttpMethod method) {
|
||||
String url = getBaseUrl(desformCode).toString();
|
||||
HttpHeaders headers = getHeaders(token);
|
||||
ResponseEntity<JSONObject> result = RestUtil.request(url, method, headers, null, formData, JSONObject.class);
|
||||
return packageReturn(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*
|
||||
* @param desformCode
|
||||
* @param dataId
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public static Result removeOne(String desformCode, String dataId, String token) {
|
||||
String url = getBaseUrl(desformCode, dataId).toString();
|
||||
HttpHeaders headers = getHeaders(token);
|
||||
ResponseEntity<JSONObject> result = RestUtil.request(url, HttpMethod.DELETE, headers, null, null, JSONObject.class);
|
||||
return packageReturn(result);
|
||||
}
|
||||
|
||||
private static Result packageReturn(ResponseEntity<JSONObject> result) {
|
||||
if (result.getBody() != null) {
|
||||
return result.getBody().toJavaObject(Result.class);
|
||||
}
|
||||
return Result.error("操作失败");
|
||||
}
|
||||
|
||||
private static StringBuilder getBaseUrl() {
|
||||
StringBuilder builder = new StringBuilder(domain).append(path);
|
||||
builder.append("/desform/api");
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static StringBuilder getBaseUrl(String desformCode, String dataId) {
|
||||
StringBuilder builder = getBaseUrl();
|
||||
builder.append("/").append(desformCode);
|
||||
if (dataId != null) {
|
||||
builder.append("/").append(dataId);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static StringBuilder getBaseUrl(String desformCode) {
|
||||
return getBaseUrl(desformCode, null);
|
||||
}
|
||||
|
||||
private static HttpHeaders getHeaders(String token) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String mediaType = MediaType.APPLICATION_JSON_UTF8_VALUE;
|
||||
headers.setContentType(MediaType.parseMediaType(mediaType));
|
||||
headers.set("Accept", mediaType);
|
||||
headers.set("X-Access-Token", token);
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
package digital.util.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 调用 Restful 接口 Util
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Slf4j
|
||||
public class RestUtil {
|
||||
|
||||
private static String domain = null;
|
||||
|
||||
public static String getDomain() {
|
||||
if (domain == null) {
|
||||
domain = SpringContextUtils.getDomain();
|
||||
// issues/2959
|
||||
// 微服务版集成企业微信单点登录
|
||||
// 因为微服务版没有端口号,导致 SpringContextUtils.getDomain() 方法获取的域名的端口号变成了:-1所以出问题了,只需要把这个-1给去掉就可以了。
|
||||
String port=":-1";
|
||||
if (domain.endsWith(port)) {
|
||||
domain = domain.substring(0, domain.length() - 3);
|
||||
}
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
public static String path = null;
|
||||
|
||||
public static String getPath() {
|
||||
if (path == null) {
|
||||
path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path");
|
||||
}
|
||||
return oConvertUtils.getString(path);
|
||||
}
|
||||
|
||||
public static String getBaseUrl() {
|
||||
String basepath = getDomain() + getPath();
|
||||
log.info(" RestUtil.getBaseUrl: " + basepath);
|
||||
return basepath;
|
||||
}
|
||||
|
||||
/**
|
||||
* RestAPI 调用器
|
||||
*/
|
||||
@LoadBalanced
|
||||
private final static RestTemplate RT;
|
||||
|
||||
static {
|
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
requestFactory.setConnectTimeout(7200*1000);
|
||||
requestFactory.setReadTimeout(7200*1000);
|
||||
RT = new RestTemplate(requestFactory);
|
||||
// 解决乱码问题
|
||||
RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static RestTemplate getRestTemplate() {
|
||||
return RT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url) {
|
||||
return getNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url, JSONObject variables) {
|
||||
return getNative(url, variables, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url, JSONObject variables, JSONObject params) {
|
||||
return getNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> getNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.GET, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url) {
|
||||
return postNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url, JSONObject params) {
|
||||
return postNative(url, null, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url, JSONObject variables, JSONObject params) {
|
||||
return postNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 POST 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> postNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.POST, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url) {
|
||||
return putNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url, JSONObject params) {
|
||||
return putNative(url, null, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url, JSONObject variables, JSONObject params) {
|
||||
return putNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> putNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.PUT, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求
|
||||
*/
|
||||
public static JSONObject delete(String url) {
|
||||
return deleteNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求
|
||||
*/
|
||||
public static JSONObject delete(String url, JSONObject variables, JSONObject params) {
|
||||
return deleteNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> deleteNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.DELETE, null, variables, params, JSONObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> request(String url, HttpMethod method, JSONObject variables, JSONObject params) {
|
||||
return request(url, method, getHeaderApplicationJson(), variables, params, JSONObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param method 请求方式
|
||||
* @param headers 请求头 可空
|
||||
* @param variables 请求url参数 可空
|
||||
* @param params 请求body参数 可空
|
||||
* @param responseType 返回类型
|
||||
* @return ResponseEntity<responseType>
|
||||
*/
|
||||
public static <T> ResponseEntity<T> request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, Object params, Class<T> responseType) {
|
||||
log.info(" RestUtil --- request --- url = "+ url);
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
throw new RuntimeException("url 不能为空");
|
||||
}
|
||||
if (method == null) {
|
||||
throw new RuntimeException("method 不能为空");
|
||||
}
|
||||
if (headers == null) {
|
||||
headers = new HttpHeaders();
|
||||
}
|
||||
// 请求体
|
||||
String body = "";
|
||||
if (params != null) {
|
||||
if (params instanceof JSONObject) {
|
||||
body = ((JSONObject) params).toJSONString();
|
||||
|
||||
} else {
|
||||
body = params.toString();
|
||||
}
|
||||
}
|
||||
// 拼接 url 参数
|
||||
if (variables != null) {
|
||||
url += ("?" + asUrlVariables(variables));
|
||||
}
|
||||
// 发送请求
|
||||
HttpEntity<String> request = new HttpEntity<>(body, headers);
|
||||
return RT.exchange(url, method, request, responseType);
|
||||
}
|
||||
|
||||
public static <T> ResponseEntity<T> zitaRequest(String url, HttpMethod method,
|
||||
HttpHeaders headers ,JSONObject variables,
|
||||
Object params, Class<T> responseType) {
|
||||
log.info(" RestUtil --- request --- url = "+ url);
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
throw new RuntimeException("url 不能为空");
|
||||
}
|
||||
if (method == null) {
|
||||
throw new RuntimeException("method 不能为空");
|
||||
}
|
||||
// 请求体
|
||||
String body = "";
|
||||
if (params != null) {
|
||||
if (params instanceof JSONObject) {
|
||||
body = ((JSONObject) params).toJSONString();
|
||||
|
||||
} else {
|
||||
body = params.toString();
|
||||
}
|
||||
}
|
||||
// 拼接 url 参数
|
||||
if (variables != null) {
|
||||
url += ("?" + asUrlVariables(variables));
|
||||
}
|
||||
// 发送请求
|
||||
HttpEntity<String> request = new HttpEntity<>(body, headers);
|
||||
return RT.exchange(url, method, request, responseType);
|
||||
}
|
||||
|
||||
|
||||
public static <T> ResponseEntity<T> zitaRequest(String url, HttpMethod method ,JSONObject variables, Object params, Class<T> responseType) {
|
||||
log.info(" RestUtil --- request --- url = "+ url);
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
throw new RuntimeException("url 不能为空");
|
||||
}
|
||||
if (method == null) {
|
||||
throw new RuntimeException("method 不能为空");
|
||||
}
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Content-Type","application/json;charset=UTF-8");
|
||||
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
|
||||
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
|
||||
// 请求体
|
||||
String body = "";
|
||||
if (params != null) {
|
||||
if (params instanceof JSONObject) {
|
||||
body = ((JSONObject) params).toJSONString();
|
||||
|
||||
} else {
|
||||
body = params.toString();
|
||||
}
|
||||
}
|
||||
// 拼接 url 参数
|
||||
if (variables != null) {
|
||||
url += ("?" + asUrlVariables(variables));
|
||||
}
|
||||
// 发送请求
|
||||
HttpEntity<String> request = new HttpEntity<>(body, headers);
|
||||
return RT.exchange(url, method, request, responseType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取JSON请求头
|
||||
*/
|
||||
public static HttpHeaders getHeaderApplicationJson() {
|
||||
return getHeader(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头
|
||||
*/
|
||||
public static HttpHeaders getHeader(String mediaType) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType(mediaType));
|
||||
headers.add("Accept", mediaType);
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JSONObject 转为 a=1&b=2&c=3...&n=n 的形式
|
||||
*/
|
||||
public static String asUrlVariables(JSONObject variables) {
|
||||
Map<String, Object> source = variables.getInnerMap();
|
||||
Iterator<String> it = source.keySet().iterator();
|
||||
StringBuilder urlVariables = new StringBuilder();
|
||||
while (it.hasNext()) {
|
||||
String key = it.next();
|
||||
String value = "";
|
||||
Object object = source.get(key);
|
||||
if (object != null) {
|
||||
if (!StringUtils.isEmpty(object.toString())) {
|
||||
value = object.toString();
|
||||
}
|
||||
}
|
||||
urlVariables.append("&").append(key).append("=").append(value);
|
||||
}
|
||||
// 去掉第一个&
|
||||
return urlVariables.substring(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
package digital.util.util;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext.
|
||||
*
|
||||
* @author zyf
|
||||
*/
|
||||
@Slf4j
|
||||
public class SpringContextHolder implements ApplicationContextAware {
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
// NOSONAR
|
||||
SpringContextHolder.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得存储在静态变量中的ApplicationContext.
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
checkApplicationContext();
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(String name) {
|
||||
checkApplicationContext();
|
||||
return (T) applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getHandler(String name, Class<T> cls) {
|
||||
T t = null;
|
||||
if (ObjectUtil.isNotEmpty(name)) {
|
||||
checkApplicationContext();
|
||||
try {
|
||||
t = applicationContext.getBean(name, cls);
|
||||
} catch (Exception e) {
|
||||
log.warn("Customize redis listener handle [ " + name + " ], does not exist!");
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> clazz) {
|
||||
checkApplicationContext();
|
||||
return applicationContext.getBean(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除applicationContext静态变量.
|
||||
*/
|
||||
public static void cleanApplicationContext() {
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
private static void checkApplicationContext() {
|
||||
if (applicationContext == null) {
|
||||
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package digital.util.util;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import digital.base.constant.ServiceNameConstants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @Description: spring上下文工具类
|
||||
* @author: smcp
|
||||
*/
|
||||
@Component
|
||||
public class SpringContextUtils implements ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* 上下文对象实例
|
||||
*/
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SpringContextUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取applicationContext
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取HttpServletRequest
|
||||
*/
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
if (RequestContextHolder.getRequestAttributes() == null) {
|
||||
return null;
|
||||
}
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}
|
||||
/**
|
||||
* 获取HttpServletResponse
|
||||
*/
|
||||
public static HttpServletResponse getHttpServletResponse() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目根路径 basePath
|
||||
*/
|
||||
public static String getDomain(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
StringBuffer url = request.getRequestURL();
|
||||
//微服务情况下,获取gateway的basePath
|
||||
String basePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH);
|
||||
if(oConvertUtils.isNotEmpty(basePath)){
|
||||
return basePath;
|
||||
}else{
|
||||
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getOrigin(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
return request.getHeader("Origin");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过name获取 Bean.
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static Object getBean(String name) {
|
||||
return getApplicationContext().getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过class获取Bean.
|
||||
*
|
||||
* @param clazz
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getBean(Class<T> clazz) {
|
||||
return getApplicationContext().getBean(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过name,以及Clazz返回指定的Bean
|
||||
*
|
||||
* @param name
|
||||
* @param clazz
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getBean(String name, Class<T> clazz) {
|
||||
return getApplicationContext().getBean(name, clazz);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package digital.util.util;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import digital.util.exception.JeecgBootException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* sql注入处理工具类
|
||||
*
|
||||
* @author zhoujf
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlInjectionUtil {
|
||||
/**
|
||||
* sign 用于表字典加签的盐值【SQL漏洞】
|
||||
* (上线修改值 20200501,同步修改前端的盐值)
|
||||
*/
|
||||
private final static String TABLE_DICT_SIGN_SALT = "20200501";
|
||||
private final static String XSS_STR = " and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()";
|
||||
|
||||
/**show tables*/
|
||||
private final static String SHOW_TABLES = "show\\s+tables";
|
||||
|
||||
/**
|
||||
* 针对表字典进行额外的sign签名校验(增加安全机制)
|
||||
* @param dictCode:
|
||||
* @param sign:
|
||||
* @param request:
|
||||
* @Return: void
|
||||
*/
|
||||
public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) {
|
||||
//表字典SQL注入漏洞,签名校验
|
||||
String accessToken = request.getHeader("X-Access-Token");
|
||||
String signStr = dictCode + SqlInjectionUtil.TABLE_DICT_SIGN_SALT + accessToken;
|
||||
String javaSign = SecureUtil.md5(signStr);
|
||||
if (!javaSign.equals(sign)) {
|
||||
log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);
|
||||
throw new JeecgBootException("无权限访问!");
|
||||
}
|
||||
log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static void filterContent(String value) {
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
String[] xssArr = XSS_STR.split("\\|");
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
*
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static void filterContent(String[] values) {
|
||||
String[] xssArr = XSS_STR.split("\\|");
|
||||
for (String value : values) {
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【提醒:不通用】
|
||||
* 仅用于字典条件SQL参数,注入过滤
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
//@Deprecated
|
||||
public static void specialFilterContent(String value) {
|
||||
String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|";
|
||||
String[] xssArr = specialXssStr.split("\\|");
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【提醒:不通用】
|
||||
* 仅用于Online报表SQL解析,注入过滤
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
//@Deprecated
|
||||
public static void specialFilterContentForOnlineReport(String value) {
|
||||
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |";
|
||||
String[] xssArr = specialXssStr.split("\\|");
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package digital.util.util;
|
||||
|
||||
/**
|
||||
* 系统公告自定义跳转方式
|
||||
* @author: smcp
|
||||
*/
|
||||
public enum SysAnnmentTypeEnum {
|
||||
/**
|
||||
* 邮件跳转组件
|
||||
*/
|
||||
EMAIL("email", "component", "modules/eoa/email/modals/EoaEmailInForm"),
|
||||
/**
|
||||
* 工作流跳转链接我的办公
|
||||
*/
|
||||
BPM("bpm", "url", "/bpm/task/MyTaskList");
|
||||
|
||||
/**
|
||||
* 业务类型(email:邮件 bpm:流程)
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 打开方式 组件:component 路由:url
|
||||
*/
|
||||
private String openType;
|
||||
/**
|
||||
* 组件/路由 地址
|
||||
*/
|
||||
private String openPage;
|
||||
|
||||
SysAnnmentTypeEnum(String type, String openType, String openPage) {
|
||||
this.type = type;
|
||||
this.openType = openType;
|
||||
this.openPage = openPage;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getOpenType() {
|
||||
return openType;
|
||||
}
|
||||
|
||||
public void setOpenType(String openType) {
|
||||
this.openType = openType;
|
||||
}
|
||||
|
||||
public String getOpenPage() {
|
||||
return openPage;
|
||||
}
|
||||
|
||||
public void setOpenPage(String openPage) {
|
||||
this.openPage = openPage;
|
||||
}
|
||||
|
||||
public static SysAnnmentTypeEnum getByType(String type) {
|
||||
if (oConvertUtils.isEmpty(type)) {
|
||||
return null;
|
||||
}
|
||||
for (SysAnnmentTypeEnum val : values()) {
|
||||
if (val.getType().equals(type)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package digital.util.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 用户缓存信息
|
||||
* @author: smcp
|
||||
*/
|
||||
public class SysUserCacheInfo {
|
||||
|
||||
private String sysUserCode;
|
||||
|
||||
private String sysUserName;
|
||||
|
||||
private String sysOrgCode;
|
||||
|
||||
private List<String> sysMultiOrgCode;
|
||||
|
||||
private boolean oneDepart;
|
||||
|
||||
public boolean isOneDepart() {
|
||||
return oneDepart;
|
||||
}
|
||||
|
||||
public void setOneDepart(boolean oneDepart) {
|
||||
this.oneDepart = oneDepart;
|
||||
}
|
||||
|
||||
public String getSysDate() {
|
||||
return DateUtils.formatDate();
|
||||
}
|
||||
|
||||
public String getSysTime() {
|
||||
return DateUtils.now();
|
||||
}
|
||||
|
||||
public String getSysUserCode() {
|
||||
return sysUserCode;
|
||||
}
|
||||
|
||||
public void setSysUserCode(String sysUserCode) {
|
||||
this.sysUserCode = sysUserCode;
|
||||
}
|
||||
|
||||
public String getSysUserName() {
|
||||
return sysUserName;
|
||||
}
|
||||
|
||||
public void setSysUserName(String sysUserName) {
|
||||
this.sysUserName = sysUserName;
|
||||
}
|
||||
|
||||
public String getSysOrgCode() {
|
||||
return sysOrgCode;
|
||||
}
|
||||
|
||||
public void setSysOrgCode(String sysOrgCode) {
|
||||
this.sysOrgCode = sysOrgCode;
|
||||
}
|
||||
|
||||
public List<String> getSysMultiOrgCode() {
|
||||
return sysMultiOrgCode;
|
||||
}
|
||||
|
||||
public void setSysMultiOrgCode(List<String> sysMultiOrgCode) {
|
||||
this.sysMultiOrgCode = sysMultiOrgCode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package digital.util.util;
|
||||
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Author 张代浩
|
||||
*
|
||||
*/
|
||||
public class UUIDGenerator {
|
||||
|
||||
|
||||
/**
|
||||
* 产生一个32位的UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
public static String generate() {
|
||||
return new StringBuilder(32).append(format(getIp())).append(
|
||||
format(getJvm())).append(format(getHiTime())).append(
|
||||
format(getLoTime())).append(format(getCount())).toString();
|
||||
|
||||
}
|
||||
|
||||
private static final int IP;
|
||||
static {
|
||||
int ipadd;
|
||||
try {
|
||||
ipadd = toInt(InetAddress.getLocalHost().getAddress());
|
||||
} catch (Exception e) {
|
||||
ipadd = 0;
|
||||
}
|
||||
IP = ipadd;
|
||||
}
|
||||
|
||||
private static short counter = (short) 0;
|
||||
|
||||
private static final int JVM = (int) (System.currentTimeMillis() >>> 8);
|
||||
|
||||
private final static String format(int intval) {
|
||||
String formatted = Integer.toHexString(intval);
|
||||
StringBuilder buf = new StringBuilder("00000000");
|
||||
buf.replace(8 - formatted.length(), 8, formatted);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private final static String format(short shortval) {
|
||||
String formatted = Integer.toHexString(shortval);
|
||||
StringBuilder buf = new StringBuilder("0000");
|
||||
buf.replace(4 - formatted.length(), 4, formatted);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private final static int getJvm() {
|
||||
return JVM;
|
||||
}
|
||||
|
||||
private final static short getCount() {
|
||||
synchronized (UUIDGenerator.class) {
|
||||
if (counter < 0) {
|
||||
counter = 0;
|
||||
}
|
||||
return counter++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique in a local network
|
||||
*/
|
||||
private final static int getIp() {
|
||||
return IP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique down to millisecond
|
||||
*/
|
||||
private final static short getHiTime() {
|
||||
return (short) (System.currentTimeMillis() >>> 32);
|
||||
}
|
||||
|
||||
private final static int getLoTime() {
|
||||
return (int) System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private final static int toInt(byte[] bytes) {
|
||||
int result = 0;
|
||||
int length = 4;
|
||||
for (int i = 0; i < length; i++) {
|
||||
result = (result << 8) - Byte.MIN_VALUE + (int) bytes[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package digital.util.util;
|
||||
|
||||
|
||||
/**
|
||||
* 流水号生成规则(按默认规则递增,数字从1-99开始递增,数字到99,递增字母;位数不够增加位数)
|
||||
* A001
|
||||
* A001A002
|
||||
* @Author zhangdaihao
|
||||
*
|
||||
*/
|
||||
public class YouBianCodeUtil {
|
||||
|
||||
// 数字位数(默认生成3位的数字)
|
||||
|
||||
/**代表数字位数*/
|
||||
private static final int NUM_LENGTH = 2;
|
||||
|
||||
public static final int ZHANWEI_LENGTH = 1+ NUM_LENGTH;
|
||||
|
||||
public static final char LETTER= 'Z';
|
||||
|
||||
/**
|
||||
* 根据前一个code,获取同级下一个code
|
||||
* 例如:当前最大code为D01A04,下一个code为:D01A05
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getNextYouBianCode(String code) {
|
||||
String newcode = "";
|
||||
if (oConvertUtils.isEmpty(code)) {
|
||||
String zimu = "A";
|
||||
String num = getStrNum(1);
|
||||
newcode = zimu + num;
|
||||
} else {
|
||||
String beforeCode = code.substring(0, code.length() - 1- NUM_LENGTH);
|
||||
String afterCode = code.substring(code.length() - 1 - NUM_LENGTH,code.length());
|
||||
char afterCodeZimu = afterCode.substring(0, 1).charAt(0);
|
||||
Integer afterCodeNum = Integer.parseInt(afterCode.substring(1));
|
||||
// org.jeecgframework.core.util.LogUtil.info(after_code);
|
||||
// org.jeecgframework.core.util.LogUtil.info(after_code_zimu);
|
||||
// org.jeecgframework.core.util.LogUtil.info(after_code_num);
|
||||
|
||||
String nextNum = "";
|
||||
char nextZimu = 'A';
|
||||
// 先判断数字等于999*,则计数从1重新开始,递增
|
||||
if (afterCodeNum == getMaxNumByLength(NUM_LENGTH)) {
|
||||
nextNum = getNextStrNum(0);
|
||||
} else {
|
||||
nextNum = getNextStrNum(afterCodeNum);
|
||||
}
|
||||
// 先判断数字等于999*,则字母从A重新开始,递增
|
||||
if(afterCodeNum == getMaxNumByLength(NUM_LENGTH)) {
|
||||
nextZimu = getNextZiMu(afterCodeZimu);
|
||||
}else{
|
||||
nextZimu = afterCodeZimu;
|
||||
}
|
||||
|
||||
// 例如Z99,下一个code就是Z99A01
|
||||
if (LETTER == afterCodeZimu && getMaxNumByLength(NUM_LENGTH) == afterCodeNum) {
|
||||
newcode = code + (nextZimu + nextNum);
|
||||
} else {
|
||||
newcode = beforeCode + (nextZimu + nextNum);
|
||||
}
|
||||
}
|
||||
return newcode;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据父亲code,获取下级的下一个code
|
||||
*
|
||||
* 例如:父亲CODE:A01
|
||||
* 当前CODE:A01B03
|
||||
* 获取的code:A01B04
|
||||
*
|
||||
* @param parentCode 上级code
|
||||
* @param localCode 同级code
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getSubYouBianCode(String parentCode,String localCode) {
|
||||
if(localCode!=null && localCode!=""){
|
||||
|
||||
// return parentCode + getNextYouBianCode(localCode);
|
||||
return getNextYouBianCode(localCode);
|
||||
|
||||
}else{
|
||||
parentCode = parentCode + "A"+ getNextStrNum(0);
|
||||
}
|
||||
return parentCode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 将数字前面位数补零
|
||||
*
|
||||
* @param num
|
||||
* @return
|
||||
*/
|
||||
private static String getNextStrNum(int num) {
|
||||
return getStrNum(getNextNum(num));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数字前面位数补零
|
||||
*
|
||||
* @param num
|
||||
* @return
|
||||
*/
|
||||
private static String getStrNum(int num) {
|
||||
String s = String.format("%0" + NUM_LENGTH + "d", num);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递增获取下个数字
|
||||
*
|
||||
* @param num
|
||||
* @return
|
||||
*/
|
||||
private static int getNextNum(int num) {
|
||||
num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递增获取下个字母
|
||||
*
|
||||
* @param num
|
||||
* @return
|
||||
*/
|
||||
private static char getNextZiMu(char zimu) {
|
||||
if (zimu == LETTER) {
|
||||
return 'A';
|
||||
}
|
||||
zimu++;
|
||||
return zimu;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数字位数获取最大值
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
private static int getMaxNumByLength(int length){
|
||||
if(length==0){
|
||||
return 0;
|
||||
}
|
||||
StringBuilder maxNum = new StringBuilder();
|
||||
for (int i=0;i<length;i++){
|
||||
maxNum.append("9");
|
||||
}
|
||||
return Integer.parseInt(maxNum.toString());
|
||||
}
|
||||
// public static String[] cutYouBianCode(String code){
|
||||
// if(code==null || StringUtil.isNullOrEmpty(code)){
|
||||
// return null;
|
||||
// }else{
|
||||
// //获取标准长度为numLength+1,截取的数量为code.length/numLength+1
|
||||
// int c = code.length()/(NUM_LENGTH +1);
|
||||
// String[] cutcode = new String[c];
|
||||
// for(int i =0 ; i <c;i++){
|
||||
// cutcode[i] = code.substring(0,(i+1)*(NUM_LENGTH +1));
|
||||
// }
|
||||
// return cutcode;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// public static void main(String[] args) {
|
||||
// // org.jeecgframework.core.util.LogUtil.info(getNextZiMu('C'));
|
||||
// // org.jeecgframework.core.util.LogUtil.info(getNextNum(8));
|
||||
// // org.jeecgframework.core.util.LogUtil.info(cutYouBianCode("C99A01B01")[2]);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,689 @@
|
||||
package digital.util.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import digital.base.constant.CommonConstant;
|
||||
import digital.base.constant.SymbolConstant;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Author 张代浩
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
public class oConvertUtils {
|
||||
|
||||
public static String getCurrentTimestamp() {
|
||||
// 获取当前的UNIX时间戳(毫秒)
|
||||
long timestamp = Instant.now().getEpochSecond();
|
||||
// 转换为字符串
|
||||
String timestampString = Long.toString(timestamp);
|
||||
return timestampString;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Object object) {
|
||||
if (object == null) {
|
||||
return (true);
|
||||
}
|
||||
if ("".equals(object)) {
|
||||
return (true);
|
||||
}
|
||||
if (CommonConstant.STRING_NULL.equals(object)) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Object object) {
|
||||
if (object != null && !"".equals(object) && !object.equals(CommonConstant.STRING_NULL)) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
public static String decode(String strIn, String sourceCode, String targetCode) {
|
||||
String temp = code2code(strIn, sourceCode, targetCode);
|
||||
return temp;
|
||||
}
|
||||
|
||||
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
|
||||
public static String StrToUTF(String strIn, String sourceCode, String targetCode) {
|
||||
strIn = "";
|
||||
try {
|
||||
strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return strIn;
|
||||
|
||||
}
|
||||
|
||||
private static String code2code(String strIn, String sourceCode, String targetCode) {
|
||||
String strOut = null;
|
||||
if (strIn == null || "".equals(strIn.trim())) {
|
||||
return strIn;
|
||||
}
|
||||
try {
|
||||
byte[] b = strIn.getBytes(sourceCode);
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
System.out.print(b[i] + " ");
|
||||
}
|
||||
strOut = new String(b, targetCode);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return strOut;
|
||||
}
|
||||
|
||||
public static int getInt(String s, int defval) {
|
||||
if (s == null || s == "") {
|
||||
return (defval);
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return (defval);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(String s) {
|
||||
if (s == null || s == "") {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(String s, Integer df) {
|
||||
if (s == null || s == "") {
|
||||
return df;
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Integer[] getInts(String[] s) {
|
||||
Integer[] integer = new Integer[s.length];
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
integer[i] = Integer.parseInt(s[i]);
|
||||
}
|
||||
return integer;
|
||||
|
||||
}
|
||||
|
||||
public static double getDouble(String s, double defval) {
|
||||
if (s == null || s == "") {
|
||||
return (defval);
|
||||
}
|
||||
try {
|
||||
return (Double.parseDouble(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return (defval);
|
||||
}
|
||||
}
|
||||
|
||||
public static double getDou(Double s, double defval) {
|
||||
if (s == null) {
|
||||
return (defval);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*public static Short getShort(String s) {
|
||||
if (StringUtil.isNotEmpty(s)) {
|
||||
return (Short.parseShort(s));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
|
||||
public static int getInt(Object object, int defval) {
|
||||
if (isEmpty(object)) {
|
||||
return (defval);
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(object.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
return (defval);
|
||||
}
|
||||
}
|
||||
|
||||
public static Integer getInt(Object object) {
|
||||
if (isEmpty(object)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(object.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(BigDecimal s, int defval) {
|
||||
if (s == null) {
|
||||
return (defval);
|
||||
}
|
||||
return s.intValue();
|
||||
}
|
||||
|
||||
public static Integer[] getIntegerArry(String[] object) {
|
||||
int len = object.length;
|
||||
Integer[] result = new Integer[len];
|
||||
try {
|
||||
for (int i = 0; i < len; i++) {
|
||||
result[i] = new Integer(object[i].trim());
|
||||
}
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(String s) {
|
||||
return (getString(s, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转义成Unicode编码
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
/*public static String escapeJava(Object s) {
|
||||
return StringEscapeUtils.escapeJava(getString(s));
|
||||
}*/
|
||||
|
||||
public static String getString(Object object) {
|
||||
if (isEmpty(object)) {
|
||||
return "";
|
||||
}
|
||||
return (object.toString().trim());
|
||||
}
|
||||
|
||||
public static String getString(int i) {
|
||||
return (String.valueOf(i));
|
||||
}
|
||||
|
||||
public static String getString(float i) {
|
||||
return (String.valueOf(i));
|
||||
}
|
||||
|
||||
public static String getString(String s, String defval) {
|
||||
if (isEmpty(s)) {
|
||||
return (defval);
|
||||
}
|
||||
return (s.trim());
|
||||
}
|
||||
|
||||
public static String getString(Object s, String defval) {
|
||||
if (isEmpty(s)) {
|
||||
return (defval);
|
||||
}
|
||||
return (s.toString().trim());
|
||||
}
|
||||
|
||||
public static long stringToLong(String str) {
|
||||
Long test = new Long(0);
|
||||
try {
|
||||
test = Long.valueOf(str);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return test.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本机IP
|
||||
*/
|
||||
public static String getIp() {
|
||||
String ip = null;
|
||||
try {
|
||||
InetAddress address = InetAddress.getLocalHost();
|
||||
ip = address.getHostAddress();
|
||||
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个类是否为基本数据类型。
|
||||
*
|
||||
* @param clazz
|
||||
* 要判断的类。
|
||||
* @return true 表示为基本数据类型。
|
||||
*/
|
||||
private static boolean isBaseDataType(Class clazz) throws Exception {
|
||||
return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request
|
||||
* IP
|
||||
* @return IP Address
|
||||
*/
|
||||
public static String getIpAddrByRequest(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 本机IP
|
||||
* @throws SocketException
|
||||
*/
|
||||
public static String getRealIp() throws SocketException {
|
||||
// 本地IP,如果没有配置外网IP则返回它
|
||||
String localip = null;
|
||||
// 外网IP
|
||||
String netip = null;
|
||||
|
||||
Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
InetAddress ip = null;
|
||||
// 是否找到外网IP
|
||||
boolean finded = false;
|
||||
while (netInterfaces.hasMoreElements() && !finded) {
|
||||
NetworkInterface ni = netInterfaces.nextElement();
|
||||
Enumeration<InetAddress> address = ni.getInetAddresses();
|
||||
while (address.hasMoreElements()) {
|
||||
ip = address.nextElement();
|
||||
// 外网IP
|
||||
if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {
|
||||
netip = ip.getHostAddress();
|
||||
finded = true;
|
||||
break;
|
||||
} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {
|
||||
// 内网IP
|
||||
localip = ip.getHostAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (netip != null && !"".equals(netip)) {
|
||||
return netip;
|
||||
} else {
|
||||
return localip;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* java去除字符串中的空格、回车、换行符、制表符
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String replaceBlank(String str) {
|
||||
String dest = "";
|
||||
if (str != null) {
|
||||
String reg = "\\s*|\t|\r|\n";
|
||||
Pattern p = Pattern.compile(reg);
|
||||
Matcher m = p.matcher(str);
|
||||
dest = m.replaceAll("");
|
||||
}
|
||||
return dest;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断元素是否在数组内
|
||||
*
|
||||
* @param substring
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static boolean isIn(String substring, String[] source) {
|
||||
if (source == null || source.length == 0) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < source.length; i++) {
|
||||
String aSource = source[i];
|
||||
if (aSource.equals(substring)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map对象
|
||||
*/
|
||||
public static Map<Object, Object> getHashMap() {
|
||||
return new HashMap<>(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* SET转换MAP
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public static Map<Object, Object> setToMap(Set<Object> setobj) {
|
||||
Map<Object, Object> map = getHashMap();
|
||||
for (Iterator iterator = setobj.iterator(); iterator.hasNext();) {
|
||||
Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) iterator.next();
|
||||
map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim());
|
||||
}
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
public static boolean isInnerIp(String ipAddress) {
|
||||
boolean isInnerIp = false;
|
||||
long ipNum = getIpNum(ipAddress);
|
||||
/**
|
||||
* 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址
|
||||
**/
|
||||
long aBegin = getIpNum("10.0.0.0");
|
||||
long aEnd = getIpNum("10.255.255.255");
|
||||
long bBegin = getIpNum("172.16.0.0");
|
||||
long bEnd = getIpNum("172.31.255.255");
|
||||
long cBegin = getIpNum("192.168.0.0");
|
||||
long cEnd = getIpNum("192.168.255.255");
|
||||
String localIp = "127.0.0.1";
|
||||
isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || localIp.equals(ipAddress);
|
||||
return isInnerIp;
|
||||
}
|
||||
|
||||
private static long getIpNum(String ipAddress) {
|
||||
String[] ip = ipAddress.split("\\.");
|
||||
long a = Integer.parseInt(ip[0]);
|
||||
long b = Integer.parseInt(ip[1]);
|
||||
long c = Integer.parseInt(ip[2]);
|
||||
long d = Integer.parseInt(ip[3]);
|
||||
|
||||
long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
|
||||
return ipNum;
|
||||
}
|
||||
|
||||
private static boolean isInner(long userIp, long begin, long end) {
|
||||
return (userIp >= begin) && (userIp <= end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。
|
||||
* 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
|
||||
* 例如:hello_world->helloWorld
|
||||
*
|
||||
* @param name
|
||||
* 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String camelName(String name) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
// 快速检查
|
||||
if (name == null || name.isEmpty()) {
|
||||
// 没必要转换
|
||||
return "";
|
||||
} else if (!name.contains(SymbolConstant.UNDERLINE)) {
|
||||
// 不含下划线,仅将首字母小写
|
||||
//update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
//update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase();
|
||||
//update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
}
|
||||
// 用下划线将原始字符串分割
|
||||
String[] camels = name.split("_");
|
||||
for (String camel : camels) {
|
||||
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||
if (camel.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// 处理真正的驼峰片段
|
||||
if (result.length() == 0) {
|
||||
// 第一个驼峰片段,全部字母都小写
|
||||
result.append(camel.toLowerCase());
|
||||
} else {
|
||||
// 其他的驼峰片段,首字母大写
|
||||
result.append(camel.substring(0, 1).toUpperCase());
|
||||
result.append(camel.substring(1).toLowerCase());
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。
|
||||
* 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
|
||||
* 例如:hello_world,test_id->helloWorld,testId
|
||||
*
|
||||
* @param names
|
||||
* 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String camelNames(String names) {
|
||||
if(names==null||"".equals(names)){
|
||||
return null;
|
||||
}
|
||||
StringBuffer sf = new StringBuffer();
|
||||
String[] fs = names.split(",");
|
||||
for (String field : fs) {
|
||||
field = camelName(field);
|
||||
sf.append(field + ",");
|
||||
}
|
||||
String result = sf.toString();
|
||||
return result.substring(0, result.length() - 1);
|
||||
}
|
||||
|
||||
//update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。(首字母写)
|
||||
* 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
|
||||
* 例如:hello_world->HelloWorld
|
||||
*
|
||||
* @param name
|
||||
* 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String camelNameCapFirst(String name) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
// 快速检查
|
||||
if (name == null || name.isEmpty()) {
|
||||
// 没必要转换
|
||||
return "";
|
||||
} else if (!name.contains(SymbolConstant.UNDERLINE)) {
|
||||
// 不含下划线,仅将首字母小写
|
||||
return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
|
||||
}
|
||||
// 用下划线将原始字符串分割
|
||||
String[] camels = name.split("_");
|
||||
for (String camel : camels) {
|
||||
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||
if (camel.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// 其他的驼峰片段,首字母大写
|
||||
result.append(camel.substring(0, 1).toUpperCase());
|
||||
result.append(camel.substring(1).toLowerCase());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
//update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
|
||||
/**
|
||||
* 将驼峰命名转化成下划线
|
||||
* @param para
|
||||
* @return
|
||||
*/
|
||||
public static String camelToUnderline(String para){
|
||||
int length = 3;
|
||||
if(para.length()<length){
|
||||
return para.toLowerCase();
|
||||
}
|
||||
StringBuilder sb=new StringBuilder(para);
|
||||
//定位
|
||||
int temp=0;
|
||||
//从第三个字符开始 避免命名不规范
|
||||
for(int i=2;i<para.length();i++){
|
||||
if(Character.isUpperCase(para.charAt(i))){
|
||||
sb.insert(i+temp, "_");
|
||||
temp+=1;
|
||||
}
|
||||
}
|
||||
return sb.toString().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机数
|
||||
* @param place 定义随机数的位数
|
||||
*/
|
||||
public static String randomGen(int place) {
|
||||
String base = "qwertyuioplkjhgfdsazxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789";
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Random rd = new Random();
|
||||
for(int i=0;i<place;i++) {
|
||||
sb.append(base.charAt(rd.nextInt(base.length())));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类的所有属性,包括父类
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static Field[] getAllFields(Object object) {
|
||||
Class<?> clazz = object.getClass();
|
||||
List<Field> fieldList = new ArrayList<>();
|
||||
while (clazz != null) {
|
||||
fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
Field[] fields = new Field[fieldList.size()];
|
||||
fieldList.toArray(fields);
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将map的key全部转成小写
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static List<Map<String, Object>> toLowerCasePageList(List<Map<String, Object>> list){
|
||||
List<Map<String, Object>> select = new ArrayList<>();
|
||||
for (Map<String, Object> row : list) {
|
||||
Map<String, Object> resultMap = new HashMap<>(5);
|
||||
Set<String> keySet = row.keySet();
|
||||
for (String key : keySet) {
|
||||
String newKey = key.toLowerCase();
|
||||
resultMap.put(newKey, row.get(key));
|
||||
}
|
||||
select.add(resultMap);
|
||||
}
|
||||
return select;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将entityList转换成modelList
|
||||
* @param fromList
|
||||
* @param tClass
|
||||
* @param <F>
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static<F,T> List<T> entityListToModelList(List<F> fromList, Class<T> tClass){
|
||||
if(fromList == null || fromList.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
List<T> tList = new ArrayList<>();
|
||||
for(F f : fromList){
|
||||
T t = entityToModel(f, tClass);
|
||||
tList.add(t);
|
||||
}
|
||||
return tList;
|
||||
}
|
||||
|
||||
public static<F,T> T entityToModel(F entity, Class<T> modelClass) {
|
||||
log.debug("entityToModel : Entity属性的值赋值到Model");
|
||||
Object model = null;
|
||||
if (entity == null || modelClass ==null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
model = modelClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
log.error("entityToModel : 实例化异常", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("entityToModel : 安全权限异常", e);
|
||||
}
|
||||
BeanUtils.copyProperties(entity, model);
|
||||
return (T)model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 list 是否为空
|
||||
*
|
||||
* @param list
|
||||
* @return true or false
|
||||
* list == null : true
|
||||
* list.size() == 0 : true
|
||||
*/
|
||||
public static boolean listIsEmpty(Collection list) {
|
||||
return (list == null || list.size() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 list 是否不为空
|
||||
*
|
||||
* @param list
|
||||
* @return true or false
|
||||
* list == null : false
|
||||
* list.size() == 0 : false
|
||||
*/
|
||||
public static boolean listIsNotEmpty(Collection list) {
|
||||
return !listIsEmpty(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取静态文本内容
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
// public static String readStatic(String url) {
|
||||
// String json = "";
|
||||
// try {
|
||||
// //换个写法,解决springboot读取jar包中文件的问题
|
||||
// InputStream stream = oConvertUtils.class.getClassLoader().getResourceAsStream(url.replace("classpath:", ""));
|
||||
// json = IOUtils.toString(stream,"UTF-8");
|
||||
// } catch (IOException e) {
|
||||
// log.error(e.getMessage(),e);
|
||||
// }
|
||||
// return json;
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user