dev分支 各种工具类提交
This commit is contained in:
parent
fc636d6b78
commit
7371fda1f2
|
|
@ -101,6 +101,12 @@
|
|||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>tk.mybatis</groupId>
|
||||
<artifactId>mapper-spring-boot-starter</artifactId>
|
||||
<version>2.0.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ruoyi.common.tkmapper;
|
||||
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
import tk.mybatis.mapper.common.MySqlMapper;
|
||||
|
||||
/**
|
||||
* 自定义通用mapper
|
||||
*
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import java.lang.management.ManagementFactory;
|
|||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -152,4 +154,13 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
|||
// long sec = diff % nd % nh % nm / ns;
|
||||
return day + "天" + hour + "小时" + min + "分钟";
|
||||
}
|
||||
|
||||
public static String dateToString(Date date, String pattern) {
|
||||
if (date != null && StringUtils.isNotEmpty(pattern)) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(pattern);
|
||||
return format.format(date);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.ruoyi.common.utils.buildform;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 构建一个form表单提交
|
||||
*/
|
||||
public class BuildFormUtils {
|
||||
|
||||
/**
|
||||
* 构造提交表单HTML数据
|
||||
*
|
||||
* @param sParaTemp 请求参数数组
|
||||
* @param gateway 网关地址
|
||||
* @param strMethod 提交方式。两个值可选:post、get
|
||||
* @param strButtonName 确认按钮显示文字
|
||||
* @return 提交表单HTML文本
|
||||
*/
|
||||
public static String buildForm(Map<String, String> sParaTemp, String gateway, String strMethod,
|
||||
String strButtonName) {
|
||||
// 待请求参数数组
|
||||
List<String> keys = new ArrayList<String>(sParaTemp.keySet());
|
||||
StringBuffer sbHtml = new StringBuffer();
|
||||
sbHtml.append("<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>正在请求处理中</title>" +
|
||||
"<script>function myformSub(){mysubmit.submit();} </script></head><body onload=\"myformSub();\">");
|
||||
sbHtml.append("<form id=\"mysubmit\" name=\"mysubmit\" action=\"" + gateway + "\" method=\""
|
||||
+ strMethod + "\">");
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
String name = (String) keys.get(i);
|
||||
String value = (String) sParaTemp.get(name);
|
||||
sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
|
||||
}
|
||||
// submit按钮控件请不要含有name属性
|
||||
sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
|
||||
return sbHtml.toString();
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,131 @@
|
|||
package com.ruoyi.common.utils.captchautil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 验证码生成工具
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public class CaptchaUtil {
|
||||
private BufferedImage image;// 图像
|
||||
private String str;// 验证码
|
||||
private static char code[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789".toCharArray();
|
||||
private static Integer code_num=10;
|
||||
public static final String SESSION_CODE_NAME="code";
|
||||
|
||||
private CaptchaUtil() {
|
||||
init();// 初始化属性
|
||||
}
|
||||
|
||||
/*
|
||||
* 取得RandomNumUtil实例
|
||||
*/
|
||||
public static CaptchaUtil Instance() {
|
||||
return new CaptchaUtil();
|
||||
}
|
||||
|
||||
/*
|
||||
* 取得验证码图片
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/*
|
||||
* 取得图片的验证码
|
||||
*/
|
||||
public String getString() {
|
||||
return this.str;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// 在内存中创建图象
|
||||
int width = 85, height = 20;
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
// 获取图形上下文
|
||||
Graphics g = image.getGraphics();
|
||||
// 生成随机类
|
||||
Random random = new Random();
|
||||
g.setFont(new Font("LucidaBrightItalic", Font.BOLD, 20));
|
||||
// 设定背景色
|
||||
g.setColor(getRandColor(200, 250));
|
||||
g.fillRect(0, 0, width, height);
|
||||
// 设定字体
|
||||
g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
|
||||
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
|
||||
g.setColor(getRandColor(160, 200));
|
||||
for (int i = 0; i < 155; i++) {
|
||||
int x = random.nextInt(width);
|
||||
int y = random.nextInt(height);
|
||||
int xl = random.nextInt(12);
|
||||
int yl = random.nextInt(12);
|
||||
g.drawLine(x, y, x + xl, y + yl);
|
||||
}
|
||||
// 取随机产生的认证码(4位数字)
|
||||
String sRand = "";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// String rand = String.valueOf(code[random.nextInt(code.length)]);
|
||||
String rand = String.valueOf(random.nextInt(code_num));
|
||||
sRand += rand;
|
||||
// 将认证码显示到图象中
|
||||
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
|
||||
// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
|
||||
g.drawString(rand, 13 * i + 6, 16);
|
||||
}
|
||||
// 赋值验证码
|
||||
this.str = sRand;
|
||||
|
||||
// 图象生效
|
||||
g.dispose();
|
||||
// ByteArrayInputStream input = null;
|
||||
// ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
// try {
|
||||
// ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
|
||||
// ImageIO.write(image, "JPEG", imageOut);
|
||||
// imageOut.close();
|
||||
// input = new ByteArrayInputStream(output.toByteArray());
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("验证码图片产生出现错误:" + e.toString());
|
||||
// }
|
||||
// this.image = input
|
||||
this.image = image;/* 赋值图像 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 给定范围获得随机颜色
|
||||
*/
|
||||
private Color getRandColor(int fc, int bc) {
|
||||
Random random = new Random();
|
||||
if (fc > 255)
|
||||
fc = 255;
|
||||
if (bc > 255)
|
||||
bc = 255;
|
||||
int r = fc + random.nextInt(bc - fc);
|
||||
int g = fc + random.nextInt(bc - fc);
|
||||
int b = fc + random.nextInt(bc - fc);
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码验证
|
||||
* @param session
|
||||
* @param code
|
||||
*/
|
||||
public static boolean checkCode(HttpSession session, String code) {
|
||||
String codeSession = (String) session.getAttribute("code");
|
||||
if (StringUtils.isEmpty(codeSession)) {
|
||||
return false;
|
||||
}
|
||||
if (StringUtils.isEmpty(code)) {
|
||||
return false;
|
||||
}
|
||||
session.setAttribute("code", "");
|
||||
return codeSession.equalsIgnoreCase(code);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
package com.ruoyi.common.utils.captchautil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 验证码生成器
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public class ValidateCode {
|
||||
// 图片的宽度。
|
||||
private int width = 160;
|
||||
// 图片的高度。
|
||||
private int height = 40;
|
||||
// 验证码字符个数
|
||||
private int codeCount = 5;
|
||||
// 验证码干扰线数
|
||||
private int lineCount = 150;
|
||||
// 验证码
|
||||
private String code = null;
|
||||
// 验证码图片Buffer
|
||||
private BufferedImage buffImg = null;
|
||||
|
||||
// 验证码范围,去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了)
|
||||
private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||
|
||||
/**
|
||||
* 默认构造函数,设置默认参数
|
||||
*/
|
||||
public ValidateCode() {
|
||||
this.createCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param width 图片宽
|
||||
* @param height 图片高
|
||||
*/
|
||||
public ValidateCode(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.createCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param width 图片宽
|
||||
* @param height 图片高
|
||||
* @param codeCount 字符个数
|
||||
* @param lineCount 干扰线条数
|
||||
*/
|
||||
public ValidateCode(int width, int height, int codeCount, int lineCount) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.codeCount = codeCount;
|
||||
this.lineCount = lineCount;
|
||||
this.createCode();
|
||||
}
|
||||
|
||||
public void createCode() {
|
||||
int x = 0, fontHeight = 0, codeY = 0;
|
||||
int red = 0, green = 0, blue = 0;
|
||||
|
||||
x = width / (codeCount + 2);//每个字符的宽度(左右各空出一个字符)
|
||||
fontHeight = height - 2;//字体的高度
|
||||
codeY = height - 4;
|
||||
|
||||
// 图像buffer
|
||||
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = buffImg.createGraphics();
|
||||
// 生成随机数
|
||||
Random random = new Random();
|
||||
// 将图像填充为白色
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, width, height);
|
||||
// 创建字体,可以修改为其它的
|
||||
Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
|
||||
// Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);
|
||||
g.setFont(font);
|
||||
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
// 设置随机开始和结束坐标
|
||||
int xs = random.nextInt(width);//x坐标开始
|
||||
int ys = random.nextInt(height);//y坐标开始
|
||||
int xe = xs + random.nextInt(width / 8);//x坐标结束
|
||||
int ye = ys + random.nextInt(height / 8);//y坐标结束
|
||||
|
||||
// 产生随机的颜色值,让输出的每个干扰线的颜色值都将不同。
|
||||
red = random.nextInt(255);
|
||||
green = random.nextInt(255);
|
||||
blue = random.nextInt(255);
|
||||
g.setColor(new Color(red, green, blue));
|
||||
g.drawLine(xs, ys, xe, ye);
|
||||
}
|
||||
|
||||
// randomCode记录随机产生的验证码
|
||||
StringBuffer randomCode = new StringBuffer();
|
||||
// 随机产生codeCount个字符的验证码。
|
||||
for (int i = 0; i < codeCount; i++) {
|
||||
String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
|
||||
// 产生随机的颜色值,让输出的每个字符的颜色值都将不同。
|
||||
red = random.nextInt(255);
|
||||
green = random.nextInt(255);
|
||||
blue = random.nextInt(255);
|
||||
g.setColor(new Color(red, green, blue));
|
||||
g.drawString(strRand, (i + 1) * x, codeY);
|
||||
// 将产生的四个随机数组合在一起。
|
||||
randomCode.append(strRand);
|
||||
}
|
||||
// 将四位数字的验证码保存到Session中。
|
||||
System.out.println("随机验证码"+randomCode.toString());
|
||||
code = randomCode.toString();
|
||||
}
|
||||
|
||||
public void write(String path) throws IOException {
|
||||
OutputStream sos = new FileOutputStream(path);
|
||||
this.write(sos);
|
||||
}
|
||||
|
||||
public void write(OutputStream sos) throws IOException {
|
||||
ImageIO.write(buffImg, "png", sos);
|
||||
sos.close();
|
||||
}
|
||||
|
||||
public BufferedImage getBuffImg() {
|
||||
return buffImg;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证码验证
|
||||
* @param session
|
||||
* @param code
|
||||
*/
|
||||
public static boolean checkCode(HttpSession session, String code) {
|
||||
String codeSession = (String) session.getAttribute("code");
|
||||
if (StringUtils.isEmpty(codeSession)) {
|
||||
return false;
|
||||
}
|
||||
if (StringUtils.isEmpty(code)) {
|
||||
return false;
|
||||
}
|
||||
if (codeSession.equalsIgnoreCase(code)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试函数,默认生成到d盘
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
ValidateCode vCode = new ValidateCode(160,40,5,150);
|
||||
try {
|
||||
String path="D:/"+new Date().getTime()+".png";
|
||||
System.out.println(vCode.getCode()+" >"+path);
|
||||
vCode.write(path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
/**
|
||||
* Base64字符串编码工具类
|
||||
*
|
||||
* @author Administrator
|
||||
*/
|
||||
public class Base64Util {
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param data 待加密的字节数组
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String encode(byte[] data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
Base64 base64 = new Base64();
|
||||
return new String(base64.encode(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param data 待加密的字符串
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String encode(String data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
return encode(data.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param str 待解密的字符串
|
||||
* @return 解密后的字符串,如果str是null或长度为0,返回str
|
||||
*/
|
||||
public static byte[] decode(String str) {
|
||||
Base64 base64 = new Base64();
|
||||
return base64.decode(str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
|
|
@ -18,6 +17,16 @@ public class FileUtils
|
|||
{
|
||||
public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
|
||||
|
||||
/**
|
||||
* 创建多级目录
|
||||
*
|
||||
* @param directory 目录文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
private static boolean createDirectory(File directory) {
|
||||
return directory.exists() || directory.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出指定文件的byte数组
|
||||
*
|
||||
|
|
@ -139,4 +148,206 @@ public class FileUtils
|
|||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Buffer的大小
|
||||
*/
|
||||
private static final Integer BUFFER_SIZE = 1024 * 1024 * 10;
|
||||
|
||||
|
||||
/**
|
||||
* 复制文件
|
||||
*
|
||||
* @param resourcePath 源文件
|
||||
* @param targetPath 目标文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean copy(String resourcePath, String targetPath) {
|
||||
File file = new File(resourcePath);
|
||||
return copy(file, targetPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制文件
|
||||
* 通过该方式复制文件文件越大速度越是明显
|
||||
*
|
||||
* @param file 需要处理的文件
|
||||
* @param targetFile 目标文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean copy(File file, String targetFile) {
|
||||
try (
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
FileOutputStream fout = new FileOutputStream(new File(targetFile))
|
||||
) {
|
||||
FileChannel in = fin.getChannel();
|
||||
FileChannel out = fout.getChannel();
|
||||
//设定缓冲区
|
||||
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
|
||||
while (in.read(buffer) != -1) {
|
||||
//准备写入,防止其他读取,锁住文件
|
||||
buffer.flip();
|
||||
out.write(buffer);
|
||||
//准备读取。将缓冲区清理完毕,移动文件内部指针
|
||||
buffer.clear();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建多级目录
|
||||
*
|
||||
* @param paths 需要创建的目录
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean createPaths(String paths) {
|
||||
File dir = new File(paths);
|
||||
return !dir.exists() && dir.mkdir();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件支持多级目录
|
||||
*
|
||||
* @param filePath 需要创建的文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean createFiles(String filePath) {
|
||||
File file = new File(filePath);
|
||||
File dir = file.getParentFile();
|
||||
if (!dir.exists()) {
|
||||
if (dir.mkdirs()) {
|
||||
try {
|
||||
return file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个文件
|
||||
*
|
||||
* @param file 需要处理的文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean deleteFile(File file) {
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个目录
|
||||
*
|
||||
* @param file 需要处理的文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean deleteDir(File file) {
|
||||
List<File> files = listFileAll(file);
|
||||
if (files == null) {
|
||||
return true;
|
||||
}
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
deleteDir(f);
|
||||
} else {
|
||||
deleteFile(f);
|
||||
}
|
||||
}
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速清空一个超大的文件
|
||||
*
|
||||
* @param file 需要处理的文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean cleanFile(File file) {
|
||||
try (
|
||||
FileWriter fw = new FileWriter(file)
|
||||
) {
|
||||
fw.write("");
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速的删除超大的文件
|
||||
*
|
||||
* @param file 需要处理的文件
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean deleteBigFile(File file) {
|
||||
return cleanFile(file) && file.delete();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 复制目录
|
||||
*
|
||||
* @param filePath 需要处理的文件
|
||||
* @param targetPath 目标文件
|
||||
*/
|
||||
public static void copyDir(String filePath, String targetPath) {
|
||||
File file = new File(filePath);
|
||||
copyDir(file, targetPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制目录
|
||||
*
|
||||
* @param filePath 需要处理的文件
|
||||
* @param targetPath 目标文件
|
||||
*/
|
||||
public static void copyDir(File filePath, String targetPath) {
|
||||
File targetFile = new File(targetPath);
|
||||
if (!targetFile.exists()) {
|
||||
createPaths(targetPath);
|
||||
}
|
||||
File[] files = filePath.listFiles();
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
for (File file : files) {
|
||||
String path = file.getName();
|
||||
if (file.isDirectory()) {
|
||||
copyDir(file, targetPath + File.separator + path);
|
||||
} else {
|
||||
copy(file, targetPath + File.separator + path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 罗列指定路径下的全部文件包括文件夹
|
||||
*
|
||||
* @param path 需要处理的文件
|
||||
* @return 返回文件列表
|
||||
*/
|
||||
public static List<File> listFileAll(File path) {
|
||||
List<File> list = new ArrayList<>();
|
||||
File[] files = path.listFiles();
|
||||
if (files == null) {
|
||||
return list;
|
||||
}
|
||||
for (File file : files) {
|
||||
list.add(file);
|
||||
if (file.isDirectory()) {
|
||||
list.addAll(listFileAll(file));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
* <br>
|
||||
* <b>功能:</b>文件工具类<br>
|
||||
* <b>作者:</b>Pan.ShiJu<br>
|
||||
* <b>日期:</b>2017/4/11 23:27<br>
|
||||
*
|
||||
* @author Administrator
|
||||
*/
|
||||
public class UploadFileUtil {
|
||||
|
||||
private static final String BACKSLASH_REGEX = "\\\\";
|
||||
private static final String SLASH = "/";
|
||||
private static final String SPOT = ".";
|
||||
private static final String COMMA = ",";
|
||||
private static final String SEMICOLON = ";";
|
||||
|
||||
private static final String BASE64_START_FLAG = "data:";
|
||||
private static final Integer BASE64_SPLIT_ARRAY_LENGTH = 2;
|
||||
|
||||
/**
|
||||
* base64字符串转化成图片
|
||||
*/
|
||||
public static String writeImageBase64ToFile(String base64ImgData, String rootPath, String urlPrefix) {
|
||||
// 截取前面的标志,逗号分割
|
||||
String[] arr = base64ImgData.split(COMMA);
|
||||
if (arr.length != BASE64_SPLIT_ARRAY_LENGTH) {
|
||||
return null;
|
||||
}
|
||||
// UUID文件名
|
||||
String uuidFileName = getFileName();
|
||||
// 文件后缀
|
||||
String fileSuffix = SPOT + getImageSuffixByBase64(arr[0]);
|
||||
String fileName = uuidFileName + fileSuffix;
|
||||
byte[] fileBytes = Base64Util.decode(arr[1]);
|
||||
return writeSingleFileToDisk(fileBytes, fileName, rootPath, urlPrefix);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文件写入磁盘
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 文件访问url
|
||||
*/
|
||||
public static String writeSingleFileToDisk(MultipartFile file, String rootPath, String urlPrefix) {
|
||||
// UUID文件名
|
||||
String uuidFileName = getFileName();
|
||||
// 文件后缀
|
||||
String fileSuffix = getFileSuffix(file.getOriginalFilename());
|
||||
String fileName = uuidFileName + fileSuffix;
|
||||
byte[] fileBytes;
|
||||
try {
|
||||
fileBytes = file.getBytes();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
return writeSingleFileToDisk(fileBytes, fileName, rootPath, urlPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件后缀名
|
||||
*
|
||||
* @param fileName 原始文件名
|
||||
*/
|
||||
public static String getFileSuffix(String fileName) {
|
||||
if (fileName == null) {
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf(SPOT)).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有图片
|
||||
*/
|
||||
public static boolean checkIsBase64Image(String base64) {
|
||||
return base64 != null && base64.startsWith(UploadFileUtil.BASE64_START_FLAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节数组写入磁盘
|
||||
*
|
||||
* @param fileBytes 文件字节
|
||||
* @param fileName 文件名
|
||||
* @param rootPath 文件存放物理全路径
|
||||
* @param urlPrefix 文件访问前缀
|
||||
* @return 文件访问url
|
||||
*/
|
||||
private static String writeSingleFileToDisk(byte[] fileBytes, String fileName, String rootPath, String urlPrefix) {
|
||||
// 相对路径
|
||||
String relativePath = getRelativePath(rootPath);
|
||||
// 文件存储路径
|
||||
String fullPath = rootPath + relativePath + fileName;
|
||||
try (
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(new File(fullPath));
|
||||
BufferedOutputStream out = new BufferedOutputStream(fileOutputStream);
|
||||
) {
|
||||
out.write(fileBytes);
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
// 访问的url
|
||||
String fileUrl = urlPrefix + relativePath + fileName;
|
||||
// 转换url的分隔符
|
||||
return fileUrl.replaceAll(BACKSLASH_REGEX, SLASH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名称
|
||||
*/
|
||||
private static String getFileName() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件的根目录,不存在就创建
|
||||
*/
|
||||
private static String getRelativePath(String rootPath) {
|
||||
// 图片上传的相对路径
|
||||
String relativePath = File.separator + DateUtils.dateToString(new Date(), DateUtils.YYYY_MM_DD) + File.separator;
|
||||
// 图片上传的完整路径
|
||||
String fullPath = rootPath + relativePath;
|
||||
File rootPathFile = new File(fullPath);
|
||||
if (!rootPathFile.exists() && !rootPathFile.isDirectory()) {
|
||||
if (!rootPathFile.mkdirs()) {
|
||||
return File.separator;
|
||||
}
|
||||
}
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件后缀
|
||||
*
|
||||
* @param base64Str base64字符串
|
||||
* @return 文件后缀
|
||||
*/
|
||||
private static String getImageSuffixByBase64(String base64Str) {
|
||||
return base64Str.substring(base64Str.lastIndexOf(SLASH) + 1, base64Str.lastIndexOf(SEMICOLON));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
package com.ruoyi.common.utils.http;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.*;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
|
|
@ -16,6 +12,12 @@ import javax.net.ssl.SSLContext;
|
|||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -245,4 +247,113 @@ public class HttpUtils
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载excel
|
||||
*
|
||||
* @param workbook
|
||||
* @param response
|
||||
* @param fileName
|
||||
*/
|
||||
public static void downLoadStream(HSSFWorkbook workbook, HttpServletResponse response, HttpServletRequest request, String fileName) {
|
||||
OutputStream out = null;
|
||||
try {
|
||||
out = response.getOutputStream();
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
if ("IE".equals(getBrowser(request))) {
|
||||
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + fileName+ ".xls");
|
||||
}else{
|
||||
fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + fileName+ ".xls");
|
||||
}
|
||||
response.setCharacterEncoding("utf-8");
|
||||
workbook.write(out);
|
||||
} catch (Exception e) {
|
||||
log.error("file write error", e);
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("file io error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断客户端浏览器类型
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
private static String getBrowser(HttpServletRequest request) {
|
||||
String UserAgent = request.getHeader("User-Agent").toLowerCase();
|
||||
if (UserAgent.indexOf("firefox") >= 0){
|
||||
return "FF";
|
||||
}else if(UserAgent.indexOf("safari") >= 0 ){
|
||||
return "Chrome";
|
||||
}else{
|
||||
return "IE";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是非当前服务本身请求
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static boolean csrfJudge(HttpServletRequest request) {
|
||||
try {
|
||||
boolean isCsrf = false;
|
||||
String reqUrl = request.getRequestURL().toString().toLowerCase();
|
||||
//取出ServerName
|
||||
String url = request.getServerName().toLowerCase();
|
||||
//取出referer
|
||||
String referer = request.getHeader("referer").toLowerCase();
|
||||
String xreq = request.getHeader("X-Requested-With");
|
||||
// 判断referer是不是为空
|
||||
if (StringUtils.isNotEmpty(referer)) {
|
||||
//线上入金通知接口不做拦截判断,特殊处理
|
||||
if (reqUrl.indexOf("/notice/inMoneySuccessNotice") > 0) {
|
||||
return false;
|
||||
}
|
||||
// referer不为空,判断referer和当前请求是否同站点
|
||||
if (!referer.startsWith(url, 8) && !referer.startsWith(url, 7)) {
|
||||
// 不同站点--跨站请求
|
||||
isCsrf = true;
|
||||
log.error("CSRF--跨站请求伪造。reqUri:" + reqUrl + ",referer:" + referer
|
||||
+ ",X-Requested-With:" + xreq + ",url:" + url);
|
||||
}
|
||||
}
|
||||
return isCsrf;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 清空cookie
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static void clearCookie(HttpServletRequest request) {
|
||||
try {
|
||||
javax.servlet.http.Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null && cookies.length > 0) {
|
||||
Cookie cookie = cookies[0];
|
||||
cookie.setMaxAge(0);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("清空cookie出现异常:{}",e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
package com.ruoyi.common.utils.idgenerator;
|
||||
|
||||
|
||||
|
||||
|
||||
import java.text.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* uuid生成工具类,主要用一些数据表主键生成
|
||||
*
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public class UUIDUtils {
|
||||
|
||||
private static final FieldPosition HELPER_POSITION = new FieldPosition(0);
|
||||
|
||||
/** This Format for format the data to special format. */
|
||||
private final static Format dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
|
||||
|
||||
/** This Format for format the number to special format. */
|
||||
private final static NumberFormat numberFormat = new DecimalFormat("000000");
|
||||
/**
|
||||
* 序列
|
||||
*/
|
||||
private static int seq = 0;
|
||||
|
||||
/**
|
||||
* 最大值
|
||||
*/
|
||||
private static final int MAX = 999999;
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
System.out.println(getStringRandom(8));
|
||||
}
|
||||
/**
|
||||
* 获取一个长度为32的uuid
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getUUID32() {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取一个uuid
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getToken() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成序列编号
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getSequenceNo() {
|
||||
Calendar rightNow = Calendar.getInstance();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
dateFormat.format(rightNow.getTime(), sb, HELPER_POSITION);
|
||||
numberFormat.format(seq, sb, HELPER_POSITION);
|
||||
if (seq == MAX) {
|
||||
seq = 0;
|
||||
} else {
|
||||
seq++;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取一个长度为16的uuid
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized String getUUID16() {
|
||||
int machineId = 1;
|
||||
int hashCodeV = UUID.randomUUID().toString().hashCode();
|
||||
if (hashCodeV < 0) {
|
||||
hashCodeV = -hashCodeV;
|
||||
}
|
||||
return machineId + String.format("%015d", hashCodeV);
|
||||
}
|
||||
|
||||
//生成随机用户名,数字和字母组成,
|
||||
public static String getStringRandom(int length) {
|
||||
String val = "";
|
||||
Random random = new Random();
|
||||
//参数length,表示生成几位随机数
|
||||
for(int i = 0; i < length; i++) {
|
||||
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
|
||||
//输出字母还是数字
|
||||
if( "char".equalsIgnoreCase(charOrNum) ) {
|
||||
//输出是大写字母还是小写字母
|
||||
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
|
||||
val += (char)(random.nextInt(26) + temp);
|
||||
} else if( "num".equalsIgnoreCase(charOrNum) ) {
|
||||
val += String.valueOf(random.nextInt(10));
|
||||
}
|
||||
}
|
||||
return val.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.ruoyi.common.utils.jsonutils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 金操作工具类
|
||||
*
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
**/
|
||||
public class JsonUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 判断是不是ajax请求
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static boolean isAjax(HttpServletRequest request) {
|
||||
return (request.getHeader("X-Requested-With") != null
|
||||
&& "XMLHttpRequest".equals(request.getHeader("X-Requested-With").toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个字符串是不是json格式
|
||||
*
|
||||
* @param jsonString
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject isGoodJson(String jsonString) {
|
||||
try {
|
||||
if (StringUtils.isEmpty(jsonString)) {
|
||||
return null;
|
||||
}
|
||||
return (JSONObject) JSONObject.parse(jsonString);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断一个字符串是不是json格式
|
||||
*
|
||||
* @param jsonString
|
||||
* @return
|
||||
*/
|
||||
public static boolean isJson(String jsonString) {
|
||||
try {
|
||||
if (StringUtils.isEmpty(jsonString)) {
|
||||
return false;
|
||||
}
|
||||
JSONObject.parse(jsonString);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.ruoyi.common.utils.random;
|
||||
|
||||
/**
|
||||
* 生成随机数
|
||||
*
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public class RandomUtil {
|
||||
/**
|
||||
* 随机生成6位数的验证码
|
||||
* @param min
|
||||
* @param max
|
||||
* @return
|
||||
*/
|
||||
public static String getRandNum(int min, int max) {
|
||||
int randNum = min + (int)(Math.random() * ((max - min) + 1));
|
||||
return String.valueOf(randNum);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package com.ruoyi.common.utils.random;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 邀请码生成器,算法原理:<br/>
|
||||
* 1) 获取id: 1127738 <br/>
|
||||
* 2) 使用自定义进制转为:gpm6 <br/>
|
||||
* 3) 转为字符串,并在后面加'o'字符:gpm6o <br/>
|
||||
* 4)在后面随机产生若干个随机数字字符:gpm6o7 <br/>
|
||||
* 转为自定义进制后就不会出现o这个字符,然后在后面加个'o',这样就能确定唯一性。最后在后面产生一些随机字符进行补全。<br/>
|
||||
*
|
||||
* @author jiayu.qiu
|
||||
*/
|
||||
public class ShareCodeUtil {
|
||||
|
||||
/**
|
||||
* 自定义进制
|
||||
*/
|
||||
private static final char[] DIGITS = new char[]{'q', 'w', 'e', '8', 'a', 's', '2', 'd', 'z', 'x', '9', 'c', '7', 'p', '5', 'i', 'k', '3', 'm', 'j', 'u', 'f', 'r', '4', 'v', 'y', 'l', 't', 'n', '6', 'b', 'g', 'h'};
|
||||
|
||||
/**
|
||||
* 进制长度
|
||||
*/
|
||||
private static final int DIGITS_LENGTH = DIGITS.length;
|
||||
|
||||
/**
|
||||
* 序列最小长度
|
||||
*/
|
||||
private static final int MIN_LENGTH = 6;
|
||||
|
||||
|
||||
public static String toSerialCode(String uuid) {
|
||||
if (uuid == null) {
|
||||
uuid = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : uuid.getBytes()) {
|
||||
sb.append(b);
|
||||
}
|
||||
|
||||
Random random = new Random();
|
||||
int mod = random.nextInt(19);
|
||||
mod = mod < 8 ? 8 : mod;
|
||||
|
||||
Long sum = 0L;
|
||||
int l = sb.length() / mod;
|
||||
for (int i = 0; i < l; i++) {
|
||||
int start = i * mod;
|
||||
int end = (i + 1) * mod;
|
||||
sum += Long.parseLong(sb.substring(start, end));
|
||||
}
|
||||
return toSerialCode(sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID生成六位随机码
|
||||
*
|
||||
* @param id ID
|
||||
* @return 随机码
|
||||
*/
|
||||
public static String toSerialCode(long id) {
|
||||
char[] buf = new char[32];
|
||||
int charPos = 32;
|
||||
|
||||
while ((id / DIGITS_LENGTH) > 0) {
|
||||
int ind = (int) (id % DIGITS_LENGTH);
|
||||
buf[--charPos] = DIGITS[ind];
|
||||
id /= DIGITS_LENGTH;
|
||||
}
|
||||
buf[--charPos] = DIGITS[(int) (id % DIGITS_LENGTH)];
|
||||
String str = new String(buf, charPos, (32 - charPos));
|
||||
// 不够长度的自动随机补全
|
||||
if (str.length() < MIN_LENGTH) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('o');
|
||||
Random rnd = new Random();
|
||||
for (int i = 1; i < MIN_LENGTH - str.length(); i++) {
|
||||
sb.append(DIGITS[rnd.nextInt(DIGITS_LENGTH)]);
|
||||
}
|
||||
str += sb.toString();
|
||||
}
|
||||
return str.substring(0, MIN_LENGTH).toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成指定长度的随机数,全数字
|
||||
* @param codeLen
|
||||
* @return
|
||||
*/
|
||||
public static String getNewRandomCode(int codeLen) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String str = "0123456789";
|
||||
Random r = new Random();
|
||||
for(int i=0;i<codeLen;i++){
|
||||
int num = r.nextInt(str.length());
|
||||
sb.append(str.charAt(num));
|
||||
str = str.replace((str.charAt(num)+""), "");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getNewRandomCode(4));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
package com.ruoyi.common.utils.regexutil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author solo
|
||||
* @date 2019/08/16
|
||||
*/
|
||||
public class RegexUtil {
|
||||
public static final String SAFE_PASS = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,15}$";
|
||||
|
||||
/**
|
||||
* 判断一个字符串是不是在另一个字符串中
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public static boolean isStrindexOf(String str, String strof) {
|
||||
if (str.indexOf(strof) != -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否为数字类型
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNumber(String str) {
|
||||
String pattern = "^[0-9]*$";
|
||||
Pattern r = Pattern.compile(pattern);
|
||||
Matcher m = r.matcher(str);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断金额格式
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMoney(String str){
|
||||
String reg = "^[0-9]+([.]{1}[0-9]{1,2})?$";
|
||||
if(str.matches(reg)){
|
||||
if(Double.valueOf(str)>0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有特殊字符
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isSpecialString(String str){
|
||||
if(StringUtils.isEmpty(str)){
|
||||
return true;
|
||||
}
|
||||
String reg = "^[\\u4E00-\\u9FA5a-zA-Z0-9]*$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return !m.matches();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否有特殊字符
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isSpecialString1(String str){
|
||||
String reg = "^[\\u4E00-\\u9FA5a-zA-Z0-9_【】]*$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否有特殊字符
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isSpecialAccount(String str){
|
||||
if(StringUtils.isEmpty(str)){
|
||||
return true;
|
||||
}
|
||||
String reg = "^[\\u4E00-\\u9FA5a-zA-Z0-9@._-]*$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return !m.matches();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 只能输入英文数字组合 长度在5-20之间
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEN(String str){
|
||||
if(StringUtils.isEmpty(str)){
|
||||
return false;
|
||||
}
|
||||
String reg = "^(?!([a-zA-Z]+|\\d+)$)[a-zA-Z\\d]{5,20}$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能输入英文和数字 长度在2-32之间
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEnNumber(String str){
|
||||
if(StringUtils.isEmpty(str)){
|
||||
return false;
|
||||
}
|
||||
String reg = "^[a-zA-Z0-9]{2,32}$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能输入英文和数字 长度在6-32之间 主要针对提现密码
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEnNumberForPassword(String str){
|
||||
if(StringUtils.isEmpty(str)){
|
||||
return false;
|
||||
}
|
||||
String reg = "^[a-zA-Z0-9]{6,32}$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信号格式数字字母下划线减号@和.
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkWeChatNOIsOk(String str){
|
||||
if(StringUtils.isBlank(str)){
|
||||
return false;
|
||||
}
|
||||
String reg = "^[a-zA-Z0-9_\\-@.]{5,20}$";
|
||||
Pattern r = Pattern.compile(reg);
|
||||
Matcher m = r.matcher(str);
|
||||
return m.matches();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.print(isEnNumberForPassword("23456"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,19 @@
|
|||
package com.ruoyi.common.utils.security;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Md5加密方法
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author solo
|
||||
*/
|
||||
public class Md5Utils
|
||||
{
|
||||
|
|
@ -63,4 +69,77 @@ public class Md5Utils
|
|||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int HASH_ITERATIONS = 3;
|
||||
|
||||
/**
|
||||
* 加密解密算法 执行一次加密,两次解密
|
||||
*/
|
||||
public final static String convertMD5(String inStr) {
|
||||
char[] a = inStr.toCharArray();
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
a[i] = (char) (a[i] ^ '1');
|
||||
}
|
||||
String s = new String(a);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD532加密
|
||||
*
|
||||
* @param readyEncryptStr
|
||||
* @param saltKey
|
||||
* @return
|
||||
*/
|
||||
public static String MD532(String readyEncryptStr, String saltKey) {
|
||||
if (StringUtils.isNotEmpty(readyEncryptStr) && saltKey != null) {
|
||||
readyEncryptStr = readyEncryptStr + saltKey;
|
||||
//Get MD5 digest algorithm's MessageDigest's instance.
|
||||
MessageDigest md = null;
|
||||
try {
|
||||
md = MessageDigest.getInstance("MD5");
|
||||
//Use specified byte update digest.
|
||||
md.update(readyEncryptStr.getBytes());
|
||||
//Get cipher text
|
||||
byte[] b = md.digest();
|
||||
//The cipher text converted to hexadecimal string
|
||||
StringBuilder su = new StringBuilder();
|
||||
//byte array switch hexadecimal number.
|
||||
for (byte aB : b) {
|
||||
String haxHex = Integer.toHexString(aB & 0xFF);
|
||||
if (haxHex.length() < 2) {
|
||||
su.append("0");
|
||||
}
|
||||
su.append(haxHex);
|
||||
}
|
||||
return su.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* shiro MD5 加密
|
||||
* @param password
|
||||
* @param userToken
|
||||
* @return
|
||||
*/
|
||||
public static String ShiroMD5(String password, String userToken) {
|
||||
SimpleHash hash = new SimpleHash("md5", password,
|
||||
userToken, HASH_ITERATIONS);
|
||||
return hash.toHex();
|
||||
}
|
||||
|
||||
public static String createToken(){
|
||||
SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator();
|
||||
return secureRandomNumberGenerator.nextBytes().toHex();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
log.debug(new BigDecimal(832232).setScale(2, BigDecimal.ROUND_HALF_UP)+"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,144 @@
|
|||
package com.ruoyi.common.utils.stringutils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 字符串操作工具类
|
||||
*/
|
||||
public class StrUtils {
|
||||
private static final String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
|
||||
private static final String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式
|
||||
private static final String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
|
||||
private static final String regEx_space = "\\s*|\t|\r|\n";//定义空格回车换行符
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String strhours = "23232323";
|
||||
System.out.println(hideStr(strhours, 2,3));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param htmlStr
|
||||
* @return
|
||||
* 删除script标签
|
||||
*/
|
||||
public static String delScriptTag(String htmlStr) {
|
||||
if(StringUtils.isEmpty(htmlStr)){
|
||||
return "";
|
||||
}
|
||||
String regEx_script0 = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
|
||||
String regEx_script1 = "<script[^>]*?>[\\s\\S]*?"; // 定义script的正则表达式
|
||||
String regEx_script2 = "<[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
|
||||
Pattern p_script0 = Pattern.compile(regEx_script0, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_script0 = p_script0.matcher(htmlStr);
|
||||
htmlStr = m_script0.replaceAll(""); // 过滤script标签
|
||||
|
||||
Pattern p_script1 = Pattern.compile(regEx_script1, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_script1 = p_script1.matcher(htmlStr);
|
||||
htmlStr = m_script1.replaceAll(""); // 过滤script标签
|
||||
|
||||
Pattern p_script2 = Pattern.compile(regEx_script2, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_script2 = p_script2.matcher(htmlStr);
|
||||
htmlStr = m_script2.replaceAll(""); // 过滤script标签
|
||||
return htmlStr.trim(); // 返回文本字符串
|
||||
}
|
||||
|
||||
/**
|
||||
* @param htmlStr
|
||||
* @return
|
||||
* 删除Html标签
|
||||
*/
|
||||
public static String delHTMLTag(String htmlStr) {
|
||||
if(StringUtils.isEmpty(htmlStr)){
|
||||
return "";
|
||||
}
|
||||
Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_script = p_script.matcher(htmlStr);
|
||||
htmlStr = m_script.replaceAll(""); // 过滤script标签
|
||||
|
||||
Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_style = p_style.matcher(htmlStr);
|
||||
htmlStr = m_style.replaceAll(""); // 过滤style标签
|
||||
|
||||
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_html = p_html.matcher(htmlStr);
|
||||
htmlStr = m_html.replaceAll(""); // 过滤html标签
|
||||
|
||||
Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_space = p_space.matcher(htmlStr);
|
||||
htmlStr = m_space.replaceAll(""); // 过滤空格回车标签
|
||||
return htmlStr.trim(); // 返回文本字符串
|
||||
}
|
||||
|
||||
/**
|
||||
* 从字符串末尾截取字符串
|
||||
*
|
||||
* @param str
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static String subStringByEnd(String str, Integer length) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
return "";
|
||||
}
|
||||
if (str.length() < length) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(str.length() - length, str.length());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 448 * 替换字符串
|
||||
* 449 * @param args
|
||||
* 450 * @throws IOException
|
||||
* 451
|
||||
*/
|
||||
public static String strReplaceAll(String name,String str1,String str2) {
|
||||
if (name != null && !"".equals(name)) {
|
||||
if(StringUtils.isBlank(str2)){
|
||||
str2 = "";
|
||||
}
|
||||
return name.replaceAll(str1, str2);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 安全性隐藏,字符串指定位置中间的字符通过*代替
|
||||
* @param str
|
||||
* @param front
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public static String hideStr(String str, int front, int end) {
|
||||
//字符串不能为空
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
return "";
|
||||
}
|
||||
//需要截取的长度不能大于身份证号长度
|
||||
if ((front + end) > str.length()) {
|
||||
return str;
|
||||
}
|
||||
//需要截取的不能小于0
|
||||
if (front < 0 || end < 0) {
|
||||
return str;
|
||||
}
|
||||
//计算*的数量
|
||||
int asteriskCount = str.length() - (front + end);
|
||||
StringBuilder asteriskStr = new StringBuilder();
|
||||
for (int i = 0; i < asteriskCount; i++) {
|
||||
asteriskStr.append("*");
|
||||
}
|
||||
String regex = "(\\w{" + String.valueOf(front) + "})(\\w+)(\\w{" + String.valueOf(end) + "})";
|
||||
return str.replaceAll(regex, "$1" + asteriskStr + "$3");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
package com.ruoyi.common.utils.tree;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* tree结构
|
||||
*
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public class Ztree {
|
||||
private String id;
|
||||
private String text;
|
||||
private String state;
|
||||
private boolean isParent;
|
||||
private boolean checked;;
|
||||
private int locked;
|
||||
private List<Ztree> children;
|
||||
private String iconCls;
|
||||
private String pid;
|
||||
private Map<String, Object> attributes = new HashMap<String, Object>();
|
||||
private String comment;
|
||||
private String link;
|
||||
private String url;
|
||||
private String target;
|
||||
private Integer types;
|
||||
private String code;
|
||||
private String path;
|
||||
private Date createtime;
|
||||
private Date updatetime;
|
||||
private String object_class;
|
||||
private String title;
|
||||
private String name;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@JsonProperty(value = "isParent")
|
||||
public boolean getIsParent() {
|
||||
return isParent;
|
||||
}
|
||||
|
||||
public void setIsParent(boolean isParent) {
|
||||
this.isParent = isParent;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public int getLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(int locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public List<Ztree> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Ztree> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public String getIconCls() {
|
||||
return iconCls;
|
||||
}
|
||||
|
||||
public void setIconCls(String iconCls) {
|
||||
this.iconCls = iconCls;
|
||||
}
|
||||
|
||||
public String getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
public void setPid(String pid) {
|
||||
this.pid = pid;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(String link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public Integer getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(Integer types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public Date getCreatetime() {
|
||||
return createtime;
|
||||
}
|
||||
|
||||
public void setCreatetime(Date createtime) {
|
||||
this.createtime = createtime;
|
||||
}
|
||||
|
||||
public Date getUpdatetime() {
|
||||
return updatetime;
|
||||
}
|
||||
|
||||
public void setUpdatetime(Date updatetime) {
|
||||
this.updatetime = updatetime;
|
||||
}
|
||||
|
||||
public String getObject_class() {
|
||||
return object_class;
|
||||
}
|
||||
|
||||
public void setObject_class(String object_class) {
|
||||
this.object_class = object_class;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.ruoyi.common.utils.tree;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* tree结构工具类
|
||||
*
|
||||
* @author solo
|
||||
* @date 2019/08/16.
|
||||
*/
|
||||
public class ZtreeUtil {
|
||||
|
||||
public static List<Ztree> ztreeList(List<Ztree> list,String pid) {
|
||||
List<Ztree> returnList = new ArrayList<Ztree>();
|
||||
for (Ztree t : list) {
|
||||
if (StringUtils.equals(t.getPid(), pid)) {
|
||||
recursionFn(list, t);
|
||||
returnList.add(t);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private static void recursionFn(List<Ztree> list, Ztree t) {
|
||||
List<Ztree> childList = getChildList(list, t);// 得到子节点列表
|
||||
t.setChildren(childList);
|
||||
t.setState("open");
|
||||
t.setIsParent(false);
|
||||
for (Ztree tChild : childList) {
|
||||
t.setState("closed");
|
||||
t.setIsParent(true);
|
||||
if (hasChild(list, tChild)) {// 判断是否有子节点
|
||||
for (Ztree n : childList) {
|
||||
recursionFn(list, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 得到子节点列表
|
||||
private static List<Ztree> getChildList(List<Ztree> list, Ztree t) {
|
||||
List<Ztree> tlist = new ArrayList<Ztree>();
|
||||
for (Ztree n : list) {
|
||||
if (StringUtils.equals(n.getPid(), t.getId())) {
|
||||
tlist.add(n);
|
||||
}
|
||||
}
|
||||
return tlist;
|
||||
}
|
||||
|
||||
// 判断是否有子节点
|
||||
private static boolean hasChild(List<Ztree> list, Ztree t) {
|
||||
return getChildList(list, t).size() > 0;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue