脚本内容压缩
This commit is contained in:
parent
2c70faf180
commit
3ce09effdb
|
@ -122,6 +122,11 @@
|
|||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package io.metersphere.commons.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Inherited
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface FuzzyQuery {
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import io.metersphere.commons.annotations.FuzzyQuery;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BeanUtils {
|
||||
|
||||
public static <T> T copyBean(T target, Object source) {
|
||||
try {
|
||||
org.springframework.beans.BeanUtils.copyProperties(source, target);
|
||||
return target;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to copy object: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T copyBean(T target, Object source, String... ignoreProperties) {
|
||||
try {
|
||||
org.springframework.beans.BeanUtils.copyProperties(source, target, ignoreProperties);
|
||||
return target;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to copy object: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getFieldValueByName(String fieldName, Object bean) {
|
||||
try {
|
||||
if (StringUtils.isBlank(fieldName)) {
|
||||
return null;
|
||||
}
|
||||
String firstLetter = fieldName.substring(0, 1).toUpperCase();
|
||||
String getter = "get" + firstLetter + fieldName.substring(1);
|
||||
Method method = bean.getClass().getMethod(getter);
|
||||
return method.invoke(bean);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("failed to getFieldValueByName. ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFieldValueByName(Object bean, String fieldName, Object value, Class<?> type) {
|
||||
try {
|
||||
if (StringUtils.isBlank(fieldName)) {
|
||||
return;
|
||||
}
|
||||
String firstLetter = fieldName.substring(0, 1).toUpperCase();
|
||||
String setter = "set" + firstLetter + fieldName.substring(1);
|
||||
Method method = bean.getClass().getMethod(setter, type);
|
||||
method.invoke(bean, value);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("failed to setFieldValueByName. ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Method getMethod(Object bean, String fieldName, Class<?> type) {
|
||||
try {
|
||||
if (StringUtils.isBlank(fieldName)) {
|
||||
return null;
|
||||
}
|
||||
String firstLetter = fieldName.substring(0, 1).toUpperCase();
|
||||
String setter = "set" + firstLetter + fieldName.substring(1);
|
||||
return bean.getClass().getMethod(setter, type);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> objectToMap(Object obj) {
|
||||
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
if (obj != null) {
|
||||
ReflectionUtils.doWithFields(obj.getClass(), field -> {
|
||||
boolean accessFlag = field.isAccessible();
|
||||
try {
|
||||
String varName = field.getName();
|
||||
field.setAccessible(true);
|
||||
Object o = field.get(obj);
|
||||
if (o != null) {
|
||||
if (field.isAnnotationPresent(FuzzyQuery.class) && o instanceof String) {
|
||||
String value = "%" + o + "%";
|
||||
map.put(varName, value);
|
||||
} else {
|
||||
map.put(varName, field.get(obj));
|
||||
}
|
||||
}
|
||||
field.setAccessible(accessFlag);
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
field.setAccessible(accessFlag);
|
||||
}
|
||||
});
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* 加密解密工具
|
||||
*
|
||||
* @author kun.mo
|
||||
*/
|
||||
public class CodingUtil {
|
||||
|
||||
private static final String UTF_8 = "UTF-8";
|
||||
|
||||
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param src 要加密的串
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String md5(String src) {
|
||||
return md5(src, UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param src 要加密的串
|
||||
* @param charset 加密字符集
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String md5(String src, String charset) {
|
||||
try {
|
||||
byte[] strTemp = StringUtils.isEmpty(charset) ? src.getBytes() : src.getBytes(charset);
|
||||
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
|
||||
mdTemp.update(strTemp);
|
||||
|
||||
byte[] md = mdTemp.digest();
|
||||
int j = md.length;
|
||||
char[] str = new char[j * 2];
|
||||
int k = 0;
|
||||
|
||||
for (byte byte0 : md) {
|
||||
str[k++] = HEX_DIGITS[byte0 >>> 4 & 0xf];
|
||||
str[k++] = HEX_DIGITS[byte0 & 0xf];
|
||||
}
|
||||
|
||||
return new String(str);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("MD5 encrypt error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BASE64解密
|
||||
*
|
||||
* @param src 待解密的字符串
|
||||
* @return 解密后的字符串
|
||||
*/
|
||||
public static String base64Decoding(String src) {
|
||||
byte[] b;
|
||||
String result = null;
|
||||
if (src != null) {
|
||||
try {
|
||||
b = Base64.decodeBase64(src);
|
||||
result = new String(b, UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("BASE64 decoding error:", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* BASE64加密
|
||||
*
|
||||
* @param src 待加密的字符串
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String base64Encoding(String src) {
|
||||
String result = null;
|
||||
if (src != null) {
|
||||
try {
|
||||
result = Base64.encodeBase64String(src.getBytes(UTF_8));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("BASE64 encoding error:", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
*
|
||||
* @param src 待加密字符串
|
||||
* @param secretKey 密钥
|
||||
* @param iv 向量
|
||||
* @return 加密后字符串
|
||||
*/
|
||||
public static String aesEncrypt(String src, String secretKey, String iv) {
|
||||
if (StringUtils.isBlank(secretKey)) {
|
||||
throw new RuntimeException("secretKey is empty");
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] raw = secretKey.getBytes(UTF_8);
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
|
||||
// "算法/模式/补码方式" ECB
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
IvParameterSpec iv1 = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv1);
|
||||
byte[] encrypted = cipher.doFinal(src.getBytes(UTF_8));
|
||||
return Base64.encodeBase64String(encrypted);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("AES encrypt error:", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AES 解密
|
||||
*
|
||||
* @param src 待解密字符串
|
||||
* @param secretKey 密钥
|
||||
* @param iv 向量
|
||||
* @return 解密后字符串
|
||||
*/
|
||||
public static String aesDecrypt(String src, String secretKey, String iv) {
|
||||
if (StringUtils.isBlank(secretKey)) {
|
||||
throw new RuntimeException("secretKey is empty");
|
||||
}
|
||||
try {
|
||||
byte[] raw = secretKey.getBytes(UTF_8);
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
IvParameterSpec iv1 = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv1);
|
||||
byte[] encrypted1 = Base64.decodeBase64(src);
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
return new String(original, UTF_8);
|
||||
} catch (BadPaddingException | IllegalBlockSizeException e) {
|
||||
// 解密的原字符串为非加密字符串,则直接返回原字符串
|
||||
return src;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("decrypt error,please check parameters", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String secretKey() {
|
||||
try {
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
|
||||
keyGen.init(128);
|
||||
SecretKey secretKey = keyGen.generateKey();
|
||||
return Base64.encodeBase64String(secretKey.getEncoded());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("generate secretKey error", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class CompressUtils {
|
||||
|
||||
/***
|
||||
* 压缩Zip
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Object zip(Object data) {
|
||||
if (!(data instanceof byte[]) && !(data instanceof String)) {
|
||||
return data;
|
||||
}
|
||||
boolean isString = false;
|
||||
if (data instanceof String) {
|
||||
isString = true;
|
||||
data = ((String) data).getBytes();
|
||||
}
|
||||
|
||||
byte[] temp = (byte[]) data;
|
||||
byte[] b = (byte[]) data;
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ZipOutputStream zip = new ZipOutputStream(bos);
|
||||
ZipEntry entry = new ZipEntry("zip");
|
||||
entry.setSize(temp.length);
|
||||
zip.putNextEntry(entry);
|
||||
zip.write(temp);
|
||||
zip.closeEntry();
|
||||
zip.close();
|
||||
b = bos.toByteArray();
|
||||
bos.close();
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex);
|
||||
}
|
||||
|
||||
if (isString) {
|
||||
return new String(b);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/***
|
||||
* 解压Zip
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Object unzip(Object data) {
|
||||
if (!(data instanceof byte[])) {
|
||||
return data;
|
||||
}
|
||||
byte[] temp = (byte[]) data;
|
||||
byte[] b = (byte[]) data;
|
||||
try {
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(temp);
|
||||
ZipInputStream zip = new ZipInputStream(bis);
|
||||
while (zip.getNextEntry() != null) {
|
||||
byte[] buf = new byte[1024];
|
||||
int num;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
while ((num = zip.read(buf, 0, buf.length)) != -1) {
|
||||
baos.write(buf, 0, num);
|
||||
}
|
||||
b = baos.toByteArray();
|
||||
baos.flush();
|
||||
baos.close();
|
||||
}
|
||||
zip.close();
|
||||
bis.close();
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DBCompressConfig implements MybatisInterceptorConfigHolder {
|
||||
@Override
|
||||
public List<MybatisInterceptorConfig> interceptorConfig() {
|
||||
return Arrays.asList(
|
||||
new MybatisInterceptorConfig("io.metersphere.base.domain.FileContent", "file", "io.metersphere.commons.utils.CompressUtils", "zip", "unzip")
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DBEncryptConfig implements MybatisInterceptorConfigHolder {
|
||||
@Override
|
||||
public List<MybatisInterceptorConfig> interceptorConfig() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EncryptUtils extends CodingUtil {
|
||||
|
||||
private static final String secretKey = "www.fit2cloud.co";
|
||||
private static final String iv = "1234567890123456";
|
||||
|
||||
|
||||
public static Object aesEncrypt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return aesEncrypt(o.toString(), secretKey, iv);
|
||||
}
|
||||
|
||||
public static Object aesDecrypt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return aesDecrypt(o.toString(), secretKey, iv);
|
||||
}
|
||||
|
||||
public static <T> Object aesDecrypt(List<T> o, String attrName) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return o.stream()
|
||||
.filter(element -> BeanUtils.getFieldValueByName(attrName, element) != null)
|
||||
.peek(element -> BeanUtils.setFieldValueByName(element, attrName, aesDecrypt(BeanUtils.getFieldValueByName(attrName, element).toString(), secretKey, iv), String.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static Object md5Encrypt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return md5(o.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
public class LogUtil {
|
||||
//日志工具类
|
||||
// public static final Log Logger = LogFactory.getLog(LogUtil.class);
|
||||
|
||||
private static final String DEBUG = "DEBUG";
|
||||
private static final String INFO = "INFO";
|
||||
private static final String WARN = "WARN";
|
||||
private static final String ERROR = "ERROR";
|
||||
|
||||
/**
|
||||
* 初始化日志
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Logger getLogger() {
|
||||
return LoggerFactory.getLogger(LogUtil.getLogClass());
|
||||
}
|
||||
|
||||
public static void writeLog(Object msg, String level) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
|
||||
if (DEBUG.equals(level)) {
|
||||
if (logger != null && logger.isDebugEnabled()) {
|
||||
logger.debug(LogUtil.getMsg(msg));
|
||||
}
|
||||
} else if (INFO.equals(level)) {
|
||||
if (logger != null && logger.isInfoEnabled()) {
|
||||
logger.info(LogUtil.getMsg(msg));
|
||||
}
|
||||
} else if (WARN.equals(level)) {
|
||||
if (logger != null && logger.isWarnEnabled()) {
|
||||
logger.warn(LogUtil.getMsg(msg));
|
||||
}
|
||||
} else if (ERROR.equals(level)) {
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error(LogUtil.getMsg(msg));
|
||||
}
|
||||
} else {
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void info(Object msg) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isInfoEnabled()) {
|
||||
logger.info(LogUtil.getMsg(msg));
|
||||
}
|
||||
}
|
||||
|
||||
public static void info(Object msg, Object o1) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isInfoEnabled()) {
|
||||
logger.info(LogUtil.getMsg(msg), o1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void info(Object msg, Object o1, Object o2) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isInfoEnabled()) {
|
||||
logger.info(LogUtil.getMsg(msg), o1, o2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void info(Object msg, Object[] obj) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isInfoEnabled()) {
|
||||
logger.info(LogUtil.getMsg(msg), obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void debug(Object msg) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isDebugEnabled()) {
|
||||
logger.debug(LogUtil.getMsg(msg));
|
||||
}
|
||||
}
|
||||
|
||||
public static void debug(Object msg, Object o) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isDebugEnabled()) {
|
||||
logger.debug(LogUtil.getMsg(msg), o);
|
||||
}
|
||||
}
|
||||
|
||||
public static void debug(Object msg, Object o1, Object o2) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isDebugEnabled()) {
|
||||
logger.debug(LogUtil.getMsg(msg), o1, o2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void debug(Object msg, Object[] obj) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isDebugEnabled()) {
|
||||
logger.debug(LogUtil.getMsg(msg), obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void warn(Object msg) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isWarnEnabled()) {
|
||||
logger.warn(LogUtil.getMsg(msg));
|
||||
}
|
||||
}
|
||||
|
||||
public static void warn(Object msg, Object o) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isWarnEnabled()) {
|
||||
logger.warn(LogUtil.getMsg(msg), o);
|
||||
}
|
||||
}
|
||||
|
||||
public static void warn(Object msg, Object o1, Object o2) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isWarnEnabled()) {
|
||||
logger.warn(LogUtil.getMsg(msg), o1, o2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void warn(Object msg, Object[] obj) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isWarnEnabled()) {
|
||||
logger.warn(LogUtil.getMsg(msg), obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void error(Object msg) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error(LogUtil.getMsg(msg));// 并追加方法名称
|
||||
}
|
||||
}
|
||||
|
||||
public static void error(Object msg, Object o) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error(LogUtil.getMsg(msg), o);
|
||||
}
|
||||
}
|
||||
|
||||
public static void error(Object msg, Object o1, Object o2) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error(LogUtil.getMsg(msg), o1, o2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void error(Object msg, Object[] obj) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error(LogUtil.getMsg(msg), obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void error(Object msg, Throwable ex) {
|
||||
Logger logger = LogUtil.getLogger();
|
||||
if (logger != null && logger.isErrorEnabled()) {
|
||||
logger.error(LogUtil.getMsg(msg), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMsg(Object msg, Throwable ex) {
|
||||
String str = "";
|
||||
|
||||
if (msg != null) {
|
||||
str = LogUtil.getLogMethod() + "[" + msg.toString() + "]";
|
||||
} else {
|
||||
str = LogUtil.getLogMethod() + "[null]";
|
||||
}
|
||||
if (ex != null) {
|
||||
str += "[" + ex.getMessage() + "]";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String getMsg(Object msg) {
|
||||
return LogUtil.getMsg(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到调用类名称
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static String getLogClass() {
|
||||
String str = "";
|
||||
|
||||
StackTraceElement[] stack = (new Throwable()).getStackTrace();
|
||||
if (stack.length > 3) {
|
||||
StackTraceElement ste = stack[3];
|
||||
str = ste.getClassName();// 类名称
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到调用方法名称
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static String getLogMethod() {
|
||||
String str = "";
|
||||
|
||||
StackTraceElement[] stack = (new Throwable()).getStackTrace();
|
||||
if (stack.length > 4) {
|
||||
StackTraceElement ste = stack[4];
|
||||
str = "Method[" + ste.getMethodName() + "]";// 方法名称
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String toString(Throwable e) {
|
||||
StringWriter sw = null;
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
sw = new StringWriter();
|
||||
pw = new PrintWriter(sw);
|
||||
//将出错的栈信息输出到printWriter中
|
||||
e.printStackTrace(pw);
|
||||
pw.flush();
|
||||
sw.flush();
|
||||
} finally {
|
||||
if (sw != null) {
|
||||
try {
|
||||
sw.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (pw != null) {
|
||||
pw.close();
|
||||
}
|
||||
}
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static String getExceptionDetailsToStr(Exception e) {
|
||||
StringBuilder sb = new StringBuilder(e.toString());
|
||||
StackTraceElement[] stackElements = e.getStackTrace();
|
||||
for (StackTraceElement stackTraceElement : stackElements) {
|
||||
sb.append(stackTraceElement.toString());
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.cache.CacheKey;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.thymeleaf.util.MapUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Intercepts({
|
||||
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
|
||||
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
|
||||
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
|
||||
})
|
||||
public class MybatisInterceptor implements Interceptor {
|
||||
|
||||
private List<MybatisInterceptorConfig> interceptorConfigList;
|
||||
|
||||
private ConcurrentHashMap<String, Class> classMap = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<String, Map<String, Map<String, MybatisInterceptorConfig>>> interceptorConfigMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
String methodName = invocation.getMethod().getName();
|
||||
Object parameter = invocation.getArgs()[1];
|
||||
if (parameter != null && methodName.equals("update")) {
|
||||
invocation.getArgs()[1] = process(parameter);
|
||||
}
|
||||
Object returnValue = invocation.proceed();
|
||||
Object result = returnValue;
|
||||
if (returnValue instanceof ArrayList<?>) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
boolean isDecrypted = false;
|
||||
for (Object val : (ArrayList<?>) returnValue) {
|
||||
Object a = undo(val);
|
||||
if (a != val) {
|
||||
isDecrypted = true;
|
||||
list.add(a);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isDecrypted) {
|
||||
result = list;
|
||||
}
|
||||
} else {
|
||||
result = undo(returnValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Map<String, MybatisInterceptorConfig>> getConfig(Object p) {
|
||||
Map<String, Map<String, MybatisInterceptorConfig>> result = new HashMap<>();
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
String pClassName = p.getClass().getName();
|
||||
if (interceptorConfigMap.get(pClassName) != null) {
|
||||
return interceptorConfigMap.get(pClassName);
|
||||
}
|
||||
Map<String, List<MybatisInterceptorConfig>> m = new HashMap<>();
|
||||
for (MybatisInterceptorConfig interceptorConfig : interceptorConfigList) {
|
||||
String className = interceptorConfig.getModelName();
|
||||
String attrName = interceptorConfig.getAttrName();
|
||||
if (StringUtils.isNotBlank(className)) {
|
||||
Class c = classMap.get(className);
|
||||
if (c == null) {
|
||||
try {
|
||||
c = Class.forName(className);
|
||||
classMap.put(className, c);
|
||||
} catch (ClassNotFoundException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (c.isInstance(p)) {
|
||||
if (result.get(attrName) == null) {
|
||||
result.put(attrName, new HashMap<>());
|
||||
}
|
||||
if (StringUtils.isNotBlank(interceptorConfig.getInterceptorMethod())) {
|
||||
result.get(attrName).put(Methods.encrypt.name(), interceptorConfig);
|
||||
}
|
||||
if (StringUtils.isNotBlank(interceptorConfig.getInterceptorMethod())) {
|
||||
result.get(attrName).put(Methods.decrypt.name(), interceptorConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
interceptorConfigMap.put(pClassName, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object process(Object obj) throws Throwable {
|
||||
if (obj instanceof Map) {
|
||||
Map paramMap = (Map) obj;
|
||||
for (Object key : paramMap.keySet()) {
|
||||
if (paramMap.get(key) != null) {
|
||||
paramMap.put(key, process(paramMap.get(key)));
|
||||
}
|
||||
}
|
||||
return paramMap;
|
||||
}
|
||||
Map<String, Map<String, MybatisInterceptorConfig>> localInterceptorConfigMap = getConfig(obj);
|
||||
if (MapUtils.isEmpty(localInterceptorConfigMap)) {
|
||||
return obj;
|
||||
}
|
||||
Object newObject = obj.getClass().newInstance();
|
||||
BeanUtils.copyBean(newObject, obj);
|
||||
for (String attrName : localInterceptorConfigMap.keySet()) {
|
||||
if (MapUtils.isEmpty(localInterceptorConfigMap.get(attrName))) {
|
||||
continue;
|
||||
}
|
||||
MybatisInterceptorConfig interceptorConfig = localInterceptorConfigMap.get(attrName).get(Methods.encrypt.name());
|
||||
if (interceptorConfig == null || StringUtils.isBlank(interceptorConfig.getInterceptorClass())
|
||||
|| StringUtils.isBlank(interceptorConfig.getInterceptorMethod())) {
|
||||
continue;
|
||||
}
|
||||
Object fieldValue = BeanUtils.getFieldValueByName(interceptorConfig.getAttrName(), newObject);
|
||||
if (fieldValue != null) {
|
||||
Class<?> processClazz = Class.forName(interceptorConfig.getInterceptorClass());
|
||||
Method method = processClazz.getMethod(interceptorConfig.getInterceptorMethod(), Object.class);
|
||||
Object processedValue = method.invoke(null, fieldValue);
|
||||
if (processedValue instanceof byte[]) {
|
||||
BeanUtils.setFieldValueByName(newObject, interceptorConfig.getAttrName(), processedValue, byte[].class);
|
||||
} else {
|
||||
BeanUtils.setFieldValueByName(newObject, interceptorConfig.getAttrName(), processedValue, fieldValue.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
private Object undo(Object obj) throws Throwable {
|
||||
Map<String, Map<String, MybatisInterceptorConfig>> localDecryptConfigMap = getConfig(obj);
|
||||
Object result;
|
||||
if (MapUtils.isEmpty(localDecryptConfigMap)) {
|
||||
return obj;
|
||||
}
|
||||
result = obj.getClass().newInstance();
|
||||
BeanUtils.copyBean(result, obj);
|
||||
for (String attrName : localDecryptConfigMap.keySet()) {
|
||||
if (MapUtils.isEmpty(localDecryptConfigMap.get(attrName))) {
|
||||
continue;
|
||||
}
|
||||
MybatisInterceptorConfig interceptorConfig = localDecryptConfigMap.get(attrName).get(Methods.decrypt.name());
|
||||
if (interceptorConfig == null || StringUtils.isBlank(interceptorConfig.getUndoClass())
|
||||
|| StringUtils.isBlank(interceptorConfig.getUndoMethod())) {
|
||||
continue;
|
||||
}
|
||||
Object fieldValue = BeanUtils.getFieldValueByName(interceptorConfig.getAttrName(), result);
|
||||
if (fieldValue != null) {
|
||||
Class<?> processClazz = Class.forName(interceptorConfig.getUndoClass());
|
||||
Object undoValue;
|
||||
if (fieldValue instanceof List) {
|
||||
Method method = processClazz.getMethod(interceptorConfig.getUndoMethod(), List.class, String.class);
|
||||
//fieldValue获取的是list的引用,所以list类型的属性不需要再调用setFieldValueByName了
|
||||
method.invoke(null, fieldValue, interceptorConfig.getAttrNameForList());
|
||||
} else {
|
||||
Method method = processClazz.getMethod(interceptorConfig.getUndoMethod(), Object.class);
|
||||
undoValue = method.invoke(null, fieldValue);
|
||||
if (undoValue instanceof byte[]) {
|
||||
BeanUtils.setFieldValueByName(result, interceptorConfig.getAttrName(), undoValue, byte[].class);
|
||||
} else {
|
||||
BeanUtils.setFieldValueByName(result, interceptorConfig.getAttrName(), undoValue, fieldValue.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public List<MybatisInterceptorConfig> getInterceptorConfigList() {
|
||||
return interceptorConfigList;
|
||||
}
|
||||
|
||||
public void setInterceptorConfigList(List<MybatisInterceptorConfig> interceptorConfigList) {
|
||||
this.interceptorConfigList = interceptorConfigList;
|
||||
}
|
||||
|
||||
private enum Methods {
|
||||
encrypt, decrypt
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
public class MybatisInterceptorConfig {
|
||||
private String modelName;
|
||||
private String attrName;
|
||||
private String attrNameForList;
|
||||
private String interceptorClass;
|
||||
private String interceptorMethod;
|
||||
private String undoClass;
|
||||
private String undoMethod;
|
||||
|
||||
|
||||
public MybatisInterceptorConfig() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 用时需谨慎!!!!!
|
||||
* 主要配置多个的时候,参数少一点
|
||||
*
|
||||
* @param modelName
|
||||
* @param attrName
|
||||
*/
|
||||
public MybatisInterceptorConfig(String modelName, String attrName) {
|
||||
this.modelName = modelName;
|
||||
this.attrName = attrName;
|
||||
this.interceptorClass = "io.metersphere.commons.utils.EncryptUtils";
|
||||
this.interceptorMethod = "aesEncrypt";
|
||||
this.undoClass = "io.metersphere.commons.utils.EncryptUtils";
|
||||
this.undoMethod = "aesDecrypt";
|
||||
}
|
||||
|
||||
public MybatisInterceptorConfig(String modelName, String attrName, String attrNameForList) {
|
||||
this.modelName = modelName;
|
||||
this.attrName = attrName;
|
||||
this.attrNameForList = attrNameForList;
|
||||
this.interceptorClass = "io.metersphere.commons.utils.EncryptUtils";
|
||||
this.interceptorMethod = "aesEncrypt";
|
||||
this.undoClass = "io.metersphere.commons.utils.EncryptUtils";
|
||||
this.undoMethod = "aesDecrypt";
|
||||
}
|
||||
|
||||
public MybatisInterceptorConfig(String modelName, String attrName, String interceptorClass, String interceptorMethod, String undoMethod) {
|
||||
this.modelName = modelName;
|
||||
this.attrName = attrName;
|
||||
this.interceptorClass = interceptorClass;
|
||||
this.interceptorMethod = interceptorMethod;
|
||||
this.undoClass = interceptorClass;
|
||||
this.undoMethod = undoMethod;
|
||||
}
|
||||
|
||||
public MybatisInterceptorConfig(String modelName, String attrName, String attrNameForList, String interceptorClass, String interceptorMethod, String undoMethod) {
|
||||
this.modelName = modelName;
|
||||
this.attrName = attrName;
|
||||
this.attrNameForList = attrNameForList;
|
||||
this.interceptorClass = interceptorClass;
|
||||
this.interceptorMethod = interceptorMethod;
|
||||
this.undoClass = interceptorClass;
|
||||
this.undoMethod = undoMethod;
|
||||
}
|
||||
|
||||
public String getModelName() {
|
||||
return modelName;
|
||||
}
|
||||
|
||||
public void setModelName(String modelName) {
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public String getAttrName() {
|
||||
return attrName;
|
||||
}
|
||||
|
||||
public void setAttrName(String attrName) {
|
||||
this.attrName = attrName;
|
||||
}
|
||||
|
||||
public String getAttrNameForList() {
|
||||
return attrNameForList;
|
||||
}
|
||||
|
||||
public void setAttrNameForList(String attrNameForList) {
|
||||
this.attrNameForList = attrNameForList;
|
||||
}
|
||||
|
||||
public String getInterceptorMethod() {
|
||||
return interceptorMethod;
|
||||
}
|
||||
|
||||
public void setInterceptorMethod(String interceptorMethod) {
|
||||
this.interceptorMethod = interceptorMethod;
|
||||
}
|
||||
|
||||
public String getUndoMethod() {
|
||||
return undoMethod;
|
||||
}
|
||||
|
||||
public void setUndoMethod(String undoMethod) {
|
||||
this.undoMethod = undoMethod;
|
||||
}
|
||||
|
||||
public String getInterceptorClass() {
|
||||
return interceptorClass;
|
||||
}
|
||||
|
||||
public void setInterceptorClass(String interceptorClass) {
|
||||
this.interceptorClass = interceptorClass;
|
||||
}
|
||||
|
||||
public String getUndoClass() {
|
||||
return undoClass;
|
||||
}
|
||||
|
||||
public void setUndoClass(String undoClass) {
|
||||
this.undoClass = undoClass;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface MybatisInterceptorConfigHolder {
|
||||
default List<MybatisInterceptorConfig> interceptorConfig() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -1,13 +1,24 @@
|
|||
package io.metersphere.config;
|
||||
|
||||
import com.github.pagehelper.PageInterceptor;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.MybatisInterceptor;
|
||||
import io.metersphere.commons.utils.MybatisInterceptorConfig;
|
||||
import io.metersphere.commons.utils.MybatisInterceptorConfigHolder;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@Configuration
|
||||
|
@ -30,4 +41,32 @@ public class MybatisConfig {
|
|||
return pageInterceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MybatisInterceptor dbInterceptor() {
|
||||
MybatisInterceptor interceptor = new MybatisInterceptor();
|
||||
List<MybatisInterceptorConfig> configList = new ArrayList<>();
|
||||
interceptor.setInterceptorConfigList(configList);
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 等到ApplicationContext 加载完成之后 装配MybatisInterceptorConfigHolder
|
||||
*/
|
||||
@EventListener
|
||||
public void handleContextRefresh(ContextRefreshedEvent event) {
|
||||
try {
|
||||
ApplicationContext context = event.getApplicationContext();
|
||||
MybatisInterceptor dBEncryptInterceptor = context.getBean(MybatisInterceptor.class);
|
||||
Map<String, MybatisInterceptorConfigHolder> beansOfType = context.getBeansOfType(MybatisInterceptorConfigHolder.class);
|
||||
for (MybatisInterceptorConfigHolder config : beansOfType.values()) {
|
||||
if (!CollectionUtils.isEmpty(config.interceptorConfig())) {
|
||||
dBEncryptInterceptor.getInterceptorConfigList().addAll(config.interceptorConfig());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("装配Mybatis插件拦截配置错误,错误:" + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue