first commit
This commit is contained in:
133
src/main/java/com/sqx/modules/utils/AliPayOrderUtil.java
Normal file
133
src/main/java/com/sqx/modules/utils/AliPayOrderUtil.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class AliPayOrderUtil {
|
||||
|
||||
/**
|
||||
* 将request中的参数转换成Map
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
|
||||
Map<String, String> retMap = new HashMap<>();
|
||||
Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
|
||||
for (Map.Entry<String, String[]> entry : entrySet) {
|
||||
String name = entry.getKey();
|
||||
String[] values = entry.getValue();
|
||||
int valLen = values.length;
|
||||
if (valLen == 1) {
|
||||
retMap.put(name, values[0]);
|
||||
} else if (valLen > 1) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String val : values) {
|
||||
sb.append(",").append(val);
|
||||
}
|
||||
retMap.put(name, sb.toString().substring(1));
|
||||
} else {
|
||||
retMap.put(name, "");
|
||||
}
|
||||
}
|
||||
return retMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 计算两个经纬度之间的距离
|
||||
* @param lat1
|
||||
* @param lng1
|
||||
* @param lat2
|
||||
* @param lng2
|
||||
* @return
|
||||
*/
|
||||
|
||||
|
||||
private static double EARTH_RADIUS = 6371.393;
|
||||
private static double rad(double d)
|
||||
{
|
||||
return d * Math.PI / 180.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成随机订单编号
|
||||
* @return
|
||||
*/
|
||||
public static String createOrderId() {
|
||||
int machineId = 1;//最大支持1-9个集群机器部署
|
||||
int hashCodeV = UUID.randomUUID().toString().hashCode();
|
||||
if(hashCodeV < 0) {//有可能是负数
|
||||
hashCodeV = - hashCodeV;
|
||||
}
|
||||
// 0 代表前面补充0
|
||||
// 4 代表长度为4
|
||||
// d 代表参数为正数型
|
||||
return machineId+String.format("%015d", hashCodeV);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前日期是星期几<br>
|
||||
*
|
||||
* @param date
|
||||
* @return 当前日期是星期几
|
||||
*/
|
||||
public static String getWeekOfDate(Date date) {
|
||||
String[] weekDays = { "日", "一", "二", "三", "四", "五", "六" };
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (w < 0)
|
||||
w = 0;
|
||||
return weekDays[w];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期是星期几<br>
|
||||
*
|
||||
* @param date
|
||||
* @return 当前日期是星期几
|
||||
*/
|
||||
public static String getWeekOfDates(Date date) {
|
||||
String[] weekDays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (w < 0)
|
||||
w = 0;
|
||||
return weekDays[w];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取最近一周的时间
|
||||
*
|
||||
* @param date
|
||||
* @return 返回起始时间
|
||||
*/
|
||||
public static String getStartTime(Date date) {
|
||||
String weekOfDate = getWeekOfDate(date);
|
||||
Integer day=0;
|
||||
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
switch (weekOfDate){
|
||||
case "日": day=6;break;
|
||||
case "一": day=0;break;
|
||||
case "二": day=1;break;
|
||||
case "三": day=2;break;
|
||||
case "四": day=3;break;
|
||||
case "五": day=4;break;
|
||||
case "六": day=5;break;
|
||||
}
|
||||
Calendar cal=Calendar.getInstance();
|
||||
if(!day.equals(0)){
|
||||
cal.add(Calendar.DATE,-day);
|
||||
}
|
||||
return sdf.format(cal.getTime());
|
||||
}
|
||||
|
||||
}
|
||||
76
src/main/java/com/sqx/modules/utils/AmountCalUtils.java
Normal file
76
src/main/java/com/sqx/modules/utils/AmountCalUtils.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* 金豆计算工具类
|
||||
* @author fang
|
||||
* @date 2020-04-17
|
||||
*/
|
||||
public class AmountCalUtils {
|
||||
|
||||
|
||||
//金豆计算 加法
|
||||
public static BigDecimal add(BigDecimal b1,BigDecimal b2){
|
||||
return b1.add(b2);
|
||||
}
|
||||
|
||||
//金豆计算 减法
|
||||
public static BigDecimal sub(BigDecimal n1, BigDecimal n2) {
|
||||
formater.setMaximumFractionDigits(2);
|
||||
formater.setGroupingSize(0);
|
||||
formater.setRoundingMode(RoundingMode.FLOOR);
|
||||
double v = n1.subtract(n2).doubleValue();
|
||||
return new BigDecimal(formater.format(v));
|
||||
}
|
||||
|
||||
//金豆计算 乘法
|
||||
public static Double mul(double v1, double v2) {
|
||||
BigDecimal n1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal n2 = new BigDecimal(Double.toString(v2));
|
||||
return n1.multiply(n2).doubleValue();
|
||||
}
|
||||
|
||||
//金豆计算 乘法
|
||||
public static BigDecimal mulMoney(BigDecimal n1, BigDecimal n2) {
|
||||
formater.setMaximumFractionDigits(2);
|
||||
formater.setGroupingSize(0);
|
||||
formater.setRoundingMode(RoundingMode.FLOOR);
|
||||
BigDecimal multiply = n1.multiply(n2);
|
||||
return new BigDecimal(formater.format(multiply));
|
||||
}
|
||||
|
||||
//金豆计算 除法
|
||||
public static Double divide(double v1, double v2) {
|
||||
BigDecimal n1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal n2 = new BigDecimal(Double.toString(v2));
|
||||
return n1.divide(n2, 10, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||
}
|
||||
|
||||
private final static DecimalFormat formater = new DecimalFormat();
|
||||
|
||||
//金豆计算除法,保留小数点后两位
|
||||
public static Double moneyDivide(BigDecimal n1, BigDecimal n2){
|
||||
BigDecimal v = n1.divide(n2, 10, BigDecimal.ROUND_HALF_UP);
|
||||
System.out.println(v);
|
||||
formater.setMaximumFractionDigits(2);
|
||||
formater.setGroupingSize(0);
|
||||
formater.setRoundingMode(RoundingMode.FLOOR);
|
||||
return Double.parseDouble(formater.format(v));
|
||||
}
|
||||
|
||||
public static Double moneyDivides(BigDecimal n1, BigDecimal n2){
|
||||
BigDecimal v = n1.divide(n2, 10, BigDecimal.ROUND_HALF_UP);
|
||||
System.out.println(v);
|
||||
formater.setMaximumFractionDigits(2);
|
||||
formater.setGroupingSize(0);
|
||||
formater.setRoundingMode(RoundingMode.FLOOR);
|
||||
return Double.parseDouble(formater.format(v));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
313
src/main/java/com/sqx/modules/utils/Base64Utils.java
Normal file
313
src/main/java/com/sqx/modules/utils/Base64Utils.java
Normal file
@@ -0,0 +1,313 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class Base64Utils {
|
||||
public Base64Utils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:编码字符串
|
||||
*
|
||||
* @author jiangshuai
|
||||
* @date 2016年10月03日
|
||||
* @param data
|
||||
* 源字符串
|
||||
* @return String
|
||||
*/
|
||||
public static String encode(String data) {
|
||||
return encode(data.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:解码字符串
|
||||
*
|
||||
* @author jiangshuai
|
||||
* @date 2016年10月03日
|
||||
* @param data
|
||||
* 源字符串
|
||||
* @return String
|
||||
*/
|
||||
public static String decode(String data) {
|
||||
return new String(decode(data.toCharArray()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 功能:编码byte[]
|
||||
*
|
||||
* @author jiangshuai
|
||||
* @date 2016年10月03日
|
||||
* @param data
|
||||
* 源
|
||||
* @return char[]
|
||||
*/
|
||||
public static String encode(byte[] data) {
|
||||
char[] out = new char[((data.length + 2) / 3) * 4];
|
||||
for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
|
||||
boolean quad = false;
|
||||
boolean trip = false;
|
||||
|
||||
int val = (0xFF & (int) data[i]);
|
||||
val <<= 8;
|
||||
if ((i + 1) < data.length) {
|
||||
val |= (0xFF & (int) data[i + 1]);
|
||||
trip = true;
|
||||
}
|
||||
val <<= 8;
|
||||
if ((i + 2) < data.length) {
|
||||
val |= (0xFF & (int) data[i + 2]);
|
||||
quad = true;
|
||||
}
|
||||
out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
|
||||
val >>= 6;
|
||||
out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
|
||||
val >>= 6;
|
||||
out[index + 1] = alphabet[val & 0x3F];
|
||||
val >>= 6;
|
||||
out[index + 0] = alphabet[val & 0x3F];
|
||||
}
|
||||
return new String(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:解码
|
||||
*
|
||||
* @author jiangshuai
|
||||
* @date 2016年10月03日
|
||||
* @param data
|
||||
* 编码后的字符数组
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] decode(char[] data) {
|
||||
|
||||
int tempLen = data.length;
|
||||
for (int ix = 0; ix < data.length; ix++) {
|
||||
if ((data[ix] > 255) || codes[data[ix]] < 0) {
|
||||
--tempLen; // ignore non-valid chars and padding
|
||||
}
|
||||
}
|
||||
// calculate required length:
|
||||
// -- 3 bytes for every 4 valid base64 chars
|
||||
// -- plus 2 bytes if there are 3 extra base64 chars,
|
||||
// or plus 1 byte if there are 2 extra.
|
||||
|
||||
int len = (tempLen / 4) * 3;
|
||||
if ((tempLen % 4) == 3) {
|
||||
len += 2;
|
||||
}
|
||||
if ((tempLen % 4) == 2) {
|
||||
len += 1;
|
||||
|
||||
}
|
||||
byte[] out = new byte[len];
|
||||
|
||||
int shift = 0; // # of excess bits stored in accum
|
||||
int accum = 0; // excess bits
|
||||
int index = 0;
|
||||
|
||||
// we now go through the entire array (NOT using the 'tempLen' value)
|
||||
for (int ix = 0; ix < data.length; ix++) {
|
||||
int value = (data[ix] > 255) ? -1 : codes[data[ix]];
|
||||
|
||||
if (value >= 0) { // skip over non-code
|
||||
accum <<= 6; // bits shift up by 6 each time thru
|
||||
shift += 6; // loop, with new bits being put in
|
||||
accum |= value; // at the bottom.
|
||||
if (shift >= 8) { // whenever there are 8 or more shifted in,
|
||||
shift -= 8; // write them out (from the top, leaving any
|
||||
out[index++] = // excess at the bottom for next iteration.
|
||||
(byte) ((accum >> shift) & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is STILL something wrong we just have to throw up now!
|
||||
if (index != out.length) {
|
||||
throw new Error("Miscalculated data length (wrote " + index
|
||||
+ " instead of " + out.length + ")");
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:编码文件
|
||||
*
|
||||
* @author jiangshuai
|
||||
* @date 2016年10月03日
|
||||
* @param file
|
||||
* 源文件
|
||||
*/
|
||||
public static void encode(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
else {
|
||||
byte[] decoded = readBytes(file);
|
||||
String encoded = encode(decoded);
|
||||
writeChars(file, encoded.toCharArray());
|
||||
}
|
||||
file = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:解码文件。
|
||||
*
|
||||
* @author jiangshuai
|
||||
* @date 2016年10月03日
|
||||
* @param file
|
||||
* 源文件
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void decode(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
System.exit(0);
|
||||
} else {
|
||||
char[] encoded = readChars(file);
|
||||
byte[] decoded = decode(encoded);
|
||||
writeBytes(file, decoded);
|
||||
}
|
||||
file = null;
|
||||
}
|
||||
|
||||
//
|
||||
// code characters for values 0..63
|
||||
//
|
||||
private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
.toCharArray();
|
||||
|
||||
//
|
||||
// lookup table for converting base64 characters to value in range 0..63
|
||||
//
|
||||
private static byte[] codes = new byte[256];
|
||||
static {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
codes[i] = -1;
|
||||
// LoggerUtil.debug(i + "&" + codes[i] + " ");
|
||||
}
|
||||
for (int i = 'A'; i <= 'Z'; i++) {
|
||||
codes[i] = (byte) (i - 'A');
|
||||
// LoggerUtil.debug(i + "&" + codes[i] + " ");
|
||||
}
|
||||
|
||||
for (int i = 'a'; i <= 'z'; i++) {
|
||||
codes[i] = (byte) (26 + i - 'a');
|
||||
// LoggerUtil.debug(i + "&" + codes[i] + " ");
|
||||
}
|
||||
for (int i = '0'; i <= '9'; i++) {
|
||||
codes[i] = (byte) (52 + i - '0');
|
||||
// LoggerUtil.debug(i + "&" + codes[i] + " ");
|
||||
}
|
||||
codes['+'] = 62;
|
||||
codes['/'] = 63;
|
||||
}
|
||||
|
||||
private static byte[] readBytes(File file) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] b = null;
|
||||
InputStream fis = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
is = new BufferedInputStream(fis);
|
||||
int count = 0;
|
||||
byte[] buf = new byte[16384];
|
||||
while ((count = is.read(buf)) != -1) {
|
||||
if (count > 0) {
|
||||
baos.write(buf, 0, count);
|
||||
}
|
||||
}
|
||||
b = baos.toByteArray();
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null)
|
||||
fis.close();
|
||||
if (is != null)
|
||||
is.close();
|
||||
if (baos != null)
|
||||
baos.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
private static char[] readChars(File file) throws IOException {
|
||||
CharArrayWriter caw = new CharArrayWriter();
|
||||
Reader fr = null;
|
||||
Reader in = null;
|
||||
try {
|
||||
fr = new FileReader(file);
|
||||
in = new BufferedReader(fr);
|
||||
int count = 0;
|
||||
char[] buf = new char[16384];
|
||||
while ((count = in.read(buf)) != -1) {
|
||||
if (count > 0) {
|
||||
caw.write(buf, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (caw != null)
|
||||
caw.close();
|
||||
if (in != null)
|
||||
in.close();
|
||||
if (fr != null)
|
||||
fr.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
return caw.toCharArray();
|
||||
}
|
||||
|
||||
private static void writeBytes(File file, byte[] data) throws IOException {
|
||||
OutputStream fos = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
os = new BufferedOutputStream(fos);
|
||||
os.write(data);
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (os != null)
|
||||
os.close();
|
||||
if (fos != null)
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeChars(File file, char[] data) throws IOException {
|
||||
Writer fos = null;
|
||||
Writer os = null;
|
||||
try {
|
||||
fos = new FileWriter(file);
|
||||
os = new BufferedWriter(fos);
|
||||
os.write(data);
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (os != null)
|
||||
os.close();
|
||||
if (fos != null)
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
892
src/main/java/com/sqx/modules/utils/CertificateUtils.java
Normal file
892
src/main/java/com/sqx/modules/utils/CertificateUtils.java
Normal file
@@ -0,0 +1,892 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.*;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数字签名/加密解密工具包
|
||||
* </p>
|
||||
*/
|
||||
public class CertificateUtils {
|
||||
|
||||
/**
|
||||
* Java密钥库(Java 密钥库,JKS)KEY_STORE
|
||||
*/
|
||||
public static final String KEY_STORE = "JKS";
|
||||
|
||||
public static final String X509 = "X.509";
|
||||
|
||||
/**
|
||||
* 文件读取缓冲区大小
|
||||
*/
|
||||
private static final int CACHE_SIZE = 2048;
|
||||
|
||||
/**
|
||||
* 最大文件加密块
|
||||
*/
|
||||
private static final int MAX_ENCRYPT_BLOCK = 117;
|
||||
|
||||
/**
|
||||
* 最大文件解密块
|
||||
*/
|
||||
private static final int MAX_DECRYPT_BLOCK = 128;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 根据密钥库获得私钥
|
||||
* </p>
|
||||
*
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
static PrivateKey getPrivateKey(String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
KeyStore keyStore = getKeyStore(keyStorePath, password);
|
||||
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 获得密钥库
|
||||
* </p>
|
||||
*
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static KeyStore getKeyStore(String keyStorePath, String password)
|
||||
throws Exception {
|
||||
//FileInputStream in = new FileInputStream(keyStorePath);
|
||||
ClassPathResource classPathResource = new ClassPathResource("keystore/PTTEST17.keystore");
|
||||
InputStream certStream = classPathResource.getInputStream();
|
||||
KeyStore keyStore = KeyStore.getInstance(KEY_STORE);
|
||||
keyStore.load(certStream, password.toCharArray());
|
||||
certStream.close();
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 根据证书获得公钥
|
||||
* </p>
|
||||
*
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
static PublicKey getPublicKey(String certificatePath) throws CertificateException, IOException {
|
||||
Certificate certificate = getCertificate(certificatePath);
|
||||
PublicKey publicKey = certificate.getPublicKey();
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 根据证书获得公钥
|
||||
* </p>
|
||||
*
|
||||
* @param certificateInStream 证书输入流
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
static PublicKey getPublicKey(InputStream certificateInStream) throws CertificateException, IOException {
|
||||
Certificate certificate = getCertificate(certificateInStream);
|
||||
PublicKey publicKey = certificate.getPublicKey();
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 获得证书
|
||||
* </p>
|
||||
*
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Certificate getCertificate(String certificatePath) throws CertificateException, IOException {
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);
|
||||
FileInputStream in = new FileInputStream(certificatePath);
|
||||
Certificate certificate = certificateFactory.generateCertificate(in);
|
||||
in.close();
|
||||
return certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 获得证书
|
||||
* </p>
|
||||
*
|
||||
* @param certificateInStream 证书输入流
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Certificate getCertificate(InputStream certificateInStream) throws CertificateException, IOException {
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);
|
||||
Certificate certificate = certificateFactory.generateCertificate(certificateInStream);
|
||||
certificateInStream.close();
|
||||
return certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 根据密钥库获得证书
|
||||
* </p>
|
||||
*
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Certificate getCertificate(String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
KeyStore keyStore = getKeyStore(keyStorePath, password);
|
||||
Certificate certificate = keyStore.getCertificate(alias);
|
||||
return certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 私钥加密
|
||||
* </p>
|
||||
*
|
||||
* @param data 源数据
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
// 取得私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
|
||||
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
|
||||
System.out.print("\n=========="+privateKey.getAlgorithm()+"\n==========");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件私钥加密
|
||||
* </p>
|
||||
* <p>
|
||||
* 过大的文件可能会导致内存溢出
|
||||
* </>
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptFileByPrivateKey(String filePath, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
byte[] data = fileToByte(filePath);
|
||||
return encryptByPrivateKey(data, keyStorePath, alias, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件加密
|
||||
* </p>
|
||||
*
|
||||
* @param srcFilePath 源文件
|
||||
* @param destFilePath 加密后文件
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void encryptFileByPrivateKey(String srcFilePath, String destFilePath, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
// 取得私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
|
||||
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
File srcFile = new File(srcFilePath);
|
||||
FileInputStream in = new FileInputStream(srcFile);
|
||||
File destFile = new File(destFilePath);
|
||||
if (!destFile.getParentFile().exists()) {
|
||||
destFile.getParentFile().mkdirs();
|
||||
}
|
||||
destFile.createNewFile();
|
||||
OutputStream out = new FileOutputStream(destFile);
|
||||
byte[] data = new byte[MAX_ENCRYPT_BLOCK];
|
||||
byte[] encryptedData; // 加密块
|
||||
while (in.read(data) != -1) {
|
||||
encryptedData = cipher.doFinal(data);
|
||||
out.write(encryptedData, 0, encryptedData.length);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件加密成BASE64编码的字符串
|
||||
* </p>
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
// public static String encryptFileToBase64ByPrivateKey(String filePath, String keyStorePath, String alias, String password)
|
||||
// throws Exception {
|
||||
// byte[] encryptedData = encryptFileByPrivateKey(filePath, keyStorePath, alias, password);
|
||||
// return Base64Utils.encode(encryptedData);
|
||||
// }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 私钥解密
|
||||
* </p>
|
||||
*
|
||||
* @param encryptedData 已加密数据
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPrivateKey(byte[] encryptedData, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
// 取得私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
|
||||
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
// 解密byte数组最大长度限制: 128
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公钥加密
|
||||
* </p>
|
||||
*
|
||||
* @param data 源数据
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPublicKey(byte[] data, String certificatePath)
|
||||
throws Exception {
|
||||
// 取得公钥
|
||||
PublicKey publicKey = getPublicKey(certificatePath);
|
||||
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公钥解密
|
||||
* </p>
|
||||
*
|
||||
* @param encryptedData 已加密数据
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPublicKey(byte[] encryptedData, String certificatePath)
|
||||
throws Exception {
|
||||
PublicKey publicKey = getPublicKey(certificatePath);
|
||||
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件解密
|
||||
* </p>
|
||||
*
|
||||
* @param srcFilePath 源文件
|
||||
* @param destFilePath 目标文件
|
||||
* @param certificatePath 证书存储路径
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void decryptFileByPublicKey(String srcFilePath, String destFilePath, String certificatePath)
|
||||
throws Exception {
|
||||
PublicKey publicKey = getPublicKey(certificatePath);
|
||||
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
File srcFile = new File(srcFilePath);
|
||||
FileInputStream in = new FileInputStream(srcFile);
|
||||
File destFile = new File(destFilePath);
|
||||
if (!destFile.getParentFile().exists()) {
|
||||
destFile.getParentFile().mkdirs();
|
||||
}
|
||||
destFile.createNewFile();
|
||||
OutputStream out = new FileOutputStream(destFile);
|
||||
byte[] data = new byte[MAX_DECRYPT_BLOCK];
|
||||
byte[] decryptedData; // 解密块
|
||||
while (in.read(data) != -1) {
|
||||
decryptedData = cipher.doFinal(data);
|
||||
out.write(decryptedData, 0, decryptedData.length);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成数据签名
|
||||
* </p>
|
||||
*
|
||||
* @param data 源数据
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] sign(byte[] data, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
// 获得证书
|
||||
X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);
|
||||
// 获取私钥
|
||||
KeyStore keyStore = getKeyStore(keyStorePath, password);
|
||||
// 取得私钥
|
||||
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
|
||||
// 构建签名
|
||||
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
|
||||
signature.initSign(privateKey);
|
||||
signature.update(data);
|
||||
return signature.sign();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成数据签名并以BASE64编码
|
||||
* </p>
|
||||
*
|
||||
* @param data 源数据
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String signToBase64(byte[] data, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
return Base64.getEncoder().encodeToString(sign(data, keyStorePath, alias, password));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成文件数据签名(BASE64)
|
||||
* </p>
|
||||
* <p>
|
||||
* 需要先将文件私钥加密,再根据加密后的数据生成签名(BASE64),适用于小文件
|
||||
* </p>
|
||||
*
|
||||
* @param filePath 源文件
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String signFileToBase64WithEncrypt(String filePath, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
byte[] encryptedData = encryptFileByPrivateKey(filePath, keyStorePath, alias, password);
|
||||
return signToBase64(encryptedData, keyStorePath, alias, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成文件签名
|
||||
* </p>
|
||||
* <p>
|
||||
* 注意:<br>
|
||||
* 方法中使用了FileChannel,其巨大Bug就是不会释放文件句柄,导致签名的文件无法操作(移动或删除等)<br>
|
||||
* 该方法已被generateFileSign取代
|
||||
* </p>
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
public static byte[] signFile(String filePath, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
byte[] sign = new byte[0];
|
||||
// 获得证书
|
||||
X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);
|
||||
// 获取私钥
|
||||
KeyStore keyStore = getKeyStore(keyStorePath, password);
|
||||
// 取得私钥
|
||||
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
|
||||
// 构建签名
|
||||
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
|
||||
signature.initSign(privateKey);
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
FileChannel fileChannel = in.getChannel();
|
||||
MappedByteBuffer byteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
|
||||
signature.update(byteBuffer);
|
||||
fileChannel.close();
|
||||
in.close();
|
||||
sign = signature.sign();
|
||||
}
|
||||
return sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成文件数字签名
|
||||
* </p>
|
||||
*
|
||||
* @param filePath
|
||||
* @param keyStorePath
|
||||
* @param alias
|
||||
* @param password
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] generateFileSign(String filePath, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
byte[] sign = new byte[0];
|
||||
// 获得证书
|
||||
X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);
|
||||
// 获取私钥
|
||||
KeyStore keyStore = getKeyStore(keyStorePath, password);
|
||||
// 取得私钥
|
||||
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
|
||||
// 构建签名
|
||||
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
|
||||
signature.initSign(privateKey);
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
byte[] cache = new byte[CACHE_SIZE];
|
||||
int nRead = 0;
|
||||
while ((nRead = in.read(cache)) != -1) {
|
||||
signature.update(cache, 0, nRead);
|
||||
}
|
||||
in.close();
|
||||
sign = signature.sign();
|
||||
}
|
||||
return sign;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件签名成BASE64编码字符串
|
||||
* </p>
|
||||
*
|
||||
* @param filePath
|
||||
* @param keyStorePath
|
||||
* @param alias
|
||||
* @param password
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String signFileToBase64(String filePath, String keyStorePath, String alias, String password)
|
||||
throws Exception {
|
||||
return Base64.getEncoder().encodeToString(generateFileSign(filePath, keyStorePath, alias, password));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证签名
|
||||
* </p>
|
||||
*
|
||||
* @param data 已加密数据
|
||||
* @param sign 数据签名[BASE64]
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean verifySign(byte[] data, String sign, String certificatePath)
|
||||
throws Exception {
|
||||
// 获得证书
|
||||
X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);
|
||||
// 获得公钥
|
||||
PublicKey publicKey = x509Certificate.getPublicKey();
|
||||
// 构建签名
|
||||
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(data);
|
||||
return signature.verify(Base64.getDecoder().decode(sign));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证签名
|
||||
* </p>
|
||||
*
|
||||
* @param data 已加密数据
|
||||
* @param sign 数据签名[BASE64]
|
||||
* @param certificate 证书
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean verifySign(byte[] data, String sign, byte[] certificate)
|
||||
throws Exception {
|
||||
// 获得证书
|
||||
X509Certificate x509Certificate = (X509Certificate) getCertificate(new ByteArrayInputStream(certificate));
|
||||
// 获得公钥
|
||||
PublicKey publicKey = x509Certificate.getPublicKey();
|
||||
// 构建签名
|
||||
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(data);
|
||||
return signature.verify(Base64.getDecoder().decode(sign));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 校验文件签名
|
||||
* </p>
|
||||
*
|
||||
* @param filePath
|
||||
* @param sign
|
||||
* @param certificatePath
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
// public static boolean validateFileSign(String filePath, String sign, String certificatePath)
|
||||
// throws Exception {
|
||||
// boolean result = false;
|
||||
// // 获得证书
|
||||
// X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);
|
||||
// // 获得公钥
|
||||
// PublicKey publicKey = x509Certificate.getPublicKey();
|
||||
//// System.out.print("测试私钥");
|
||||
//// System.out.print(publicKey);
|
||||
//// System.out.print("测试私钥");
|
||||
//// System.out.print("\n");
|
||||
//
|
||||
// // 构建签名
|
||||
// Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
|
||||
// signature.initVerify(publicKey);
|
||||
// File file = new File(filePath);
|
||||
// if (file.exists()) {
|
||||
// byte[] decodedSign = Base64Utils.decode(sign);
|
||||
// FileInputStream in = new FileInputStream(file);
|
||||
// byte[] cache = new byte[CACHE_SIZE];
|
||||
// int nRead = 0;
|
||||
// while ((nRead = in.read(cache)) != -1) {
|
||||
// signature.update(cache, 0, nRead);
|
||||
// }
|
||||
// in.close();
|
||||
// result = signature.verify(decodedSign);
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BASE64解码->签名校验
|
||||
* </p>
|
||||
*
|
||||
* @param base64String BASE64编码字符串
|
||||
* @param sign 数据签名[BASE64]
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
// public static boolean verifyBase64Sign(String base64String, String sign, String certificatePath)
|
||||
// throws Exception {
|
||||
// byte[] data = Base64Utils.decode(base64String);
|
||||
// return verifySign(data, sign, certificatePath);
|
||||
// }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BASE64解码->公钥解密-签名校验
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param base64String BASE64编码字符串
|
||||
* @param sign 数据签名[BASE64]
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
// public static boolean verifyBase64SignWithDecrypt(String base64String, String sign, String certificatePath)
|
||||
// throws Exception {
|
||||
// byte[] encryptedData = Base64Utils.decode(base64String);
|
||||
// byte[] data = decryptByPublicKey(encryptedData, certificatePath);
|
||||
// return verifySign(data, sign, certificatePath);
|
||||
// }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件公钥解密->签名校验
|
||||
* </p>
|
||||
*
|
||||
* @param encryptedFilePath 加密文件路径
|
||||
* @param sign 数字证书[BASE64]
|
||||
* @param certificatePath
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
// public static boolean verifyFileSignWithDecrypt(String encryptedFilePath, String sign, String certificatePath)
|
||||
// throws Exception {
|
||||
// byte[] encryptedData = fileToByte(encryptedFilePath);
|
||||
// byte[] data = decryptByPublicKey(encryptedData, certificatePath);
|
||||
// return verifySign(data, sign, certificatePath);
|
||||
// }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 校验证书当前是否有效
|
||||
* </p>
|
||||
*
|
||||
* @param certificate 证书
|
||||
* @return
|
||||
*/
|
||||
public static boolean verifyCertificate(Certificate certificate) {
|
||||
return verifyCertificate(new Date(), certificate);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证证书是否过期或无效
|
||||
* </p>
|
||||
*
|
||||
* @param date 日期
|
||||
* @param certificate 证书
|
||||
* @return
|
||||
*/
|
||||
public static boolean verifyCertificate(Date date, Certificate certificate) {
|
||||
boolean isValid = true;
|
||||
try {
|
||||
X509Certificate x509Certificate = (X509Certificate) certificate;
|
||||
x509Certificate.checkValidity(date);
|
||||
} catch (Exception e) {
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证数字证书是在给定的日期是否有效
|
||||
* </p>
|
||||
*
|
||||
* @param date 日期
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
*/
|
||||
public static boolean verifyCertificate(Date date, String certificatePath) {
|
||||
Certificate certificate;
|
||||
try {
|
||||
certificate = getCertificate(certificatePath);
|
||||
return verifyCertificate(certificate);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证数字证书是在给定的日期是否有效
|
||||
* </p>
|
||||
*
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
*/
|
||||
public static boolean verifyCertificate(Date date, String keyStorePath, String alias, String password) {
|
||||
Certificate certificate;
|
||||
try {
|
||||
certificate = getCertificate(keyStorePath, alias, password);
|
||||
return verifyCertificate(certificate);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证数字证书当前是否有效
|
||||
* </p>
|
||||
*
|
||||
* @param keyStorePath 密钥库存储路径
|
||||
* @param alias 密钥库别名
|
||||
* @param password 密钥库密码
|
||||
* @return
|
||||
*/
|
||||
public static boolean verifyCertificate(String keyStorePath, String alias, String password) {
|
||||
return verifyCertificate(new Date(), keyStorePath, alias, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 验证数字证书当前是否有效
|
||||
* </p>
|
||||
*
|
||||
* @param certificatePath 证书存储路径
|
||||
* @return
|
||||
*/
|
||||
public static boolean verifyCertificate(String certificatePath) {
|
||||
return verifyCertificate(new Date(), certificatePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件转换为byte数组
|
||||
* </p>
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] fileToByte(String filePath) throws Exception {
|
||||
byte[] data = new byte[0];
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
|
||||
byte[] cache = new byte[CACHE_SIZE];
|
||||
int nRead = 0;
|
||||
while ((nRead = in.read(cache)) != -1) {
|
||||
out.write(cache, 0, nRead);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
data = out.toByteArray();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 二进制数据写文件
|
||||
* </p>
|
||||
*
|
||||
* @param bytes 二进制数据
|
||||
* @param filePath 文件生成目录
|
||||
*/
|
||||
public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
|
||||
InputStream in = new ByteArrayInputStream(bytes);
|
||||
File destFile = new File(filePath);
|
||||
if (!destFile.getParentFile().exists()) {
|
||||
destFile.getParentFile().mkdirs();
|
||||
}
|
||||
destFile.createNewFile();
|
||||
OutputStream out = new FileOutputStream(destFile);
|
||||
byte[] cache = new byte[CACHE_SIZE];
|
||||
int nRead = 0;
|
||||
while ((nRead = in.read(cache)) != -1) {
|
||||
out.write(cache, 0, nRead);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
}
|
||||
88
src/main/java/com/sqx/modules/utils/CusAccessObjectUtil.java
Normal file
88
src/main/java/com/sqx/modules/utils/CusAccessObjectUtil.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 获取对象的IP地址等信息
|
||||
* @author fang
|
||||
* @date 2020/9/23
|
||||
*/
|
||||
public class CusAccessObjectUtil {
|
||||
|
||||
/**
|
||||
* 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
|
||||
*
|
||||
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
|
||||
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
|
||||
*
|
||||
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
|
||||
* 192.168.1.100
|
||||
*
|
||||
* 用户真实IP为: 192.168.1.110
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static String getIpAddrs( HttpServletRequest request)
|
||||
throws Exception {
|
||||
if (request == null) {
|
||||
throw (new Exception("getIpAddr method HttpServletRequest Object is null"));
|
||||
}
|
||||
String ipString = request.getHeader("x-forwarded-for");
|
||||
if (StringUtils.isBlank(ipString) || "unknown".equalsIgnoreCase(ipString)) {
|
||||
ipString = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ipString) || "unknown".equalsIgnoreCase(ipString)) {
|
||||
ipString = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isBlank(ipString) || "unknown".equalsIgnoreCase(ipString)) {
|
||||
ipString = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
// 多个路由时,取第一个非unknown的ip
|
||||
String[] arr = ipString.split(",");
|
||||
for (String str : arr) {
|
||||
if (!"unknown".equalsIgnoreCase(str)) {
|
||||
ipString = str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ipString;
|
||||
}
|
||||
|
||||
public static String getAddress(String ip) {
|
||||
String url = "http://ip.ws.126.net/ipquery?ip=" + ip;
|
||||
String str = HttpClientUtil.doGet(url);
|
||||
if(!StrUtil.hasBlank(str)){
|
||||
String substring = str.substring(str.indexOf("{"), str.indexOf("}")+1);
|
||||
System.out.println(substring);
|
||||
JSONObject jsonObject = JSONUtil.parseObj(substring);
|
||||
String province = jsonObject.getStr("province");
|
||||
String city = jsonObject.getStr("city");
|
||||
return province+city;
|
||||
}
|
||||
return "未知";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// // 测试
|
||||
public static void main(String[] args) {
|
||||
String ip = "111.121.72.101";
|
||||
String address = getAddress(ip);
|
||||
System.out.println(address);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
180
src/main/java/com/sqx/modules/utils/EasyPoi/ExcelStyleUtil.java
Normal file
180
src/main/java/com/sqx/modules/utils/EasyPoi/ExcelStyleUtil.java
Normal file
@@ -0,0 +1,180 @@
|
||||
package com.sqx.modules.utils.EasyPoi;
|
||||
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams;
|
||||
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
|
||||
public class ExcelStyleUtil implements IExcelExportStyler {
|
||||
private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
|
||||
private static final short FONT_SIZE_TEN = 9; //字体大小
|
||||
private static final short FONT_SIZE_ELEVEN = 12;//列大小
|
||||
private static final short FONT_SIZE_TWELVE = 15;//大标题
|
||||
/**
|
||||
* 大标题样式
|
||||
*/
|
||||
private CellStyle headerStyle;
|
||||
/**
|
||||
* 每列标题样式
|
||||
*/
|
||||
private CellStyle titleStyle;
|
||||
/**
|
||||
* 数据行样式
|
||||
*/
|
||||
private CellStyle styles;
|
||||
|
||||
public ExcelStyleUtil(Workbook workbook) {
|
||||
this.init(workbook);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化样式
|
||||
*
|
||||
* @param workbook
|
||||
*/
|
||||
private void init(Workbook workbook) {
|
||||
this.headerStyle = initHeaderStyle(workbook);
|
||||
this.titleStyle = initTitleStyle(workbook);
|
||||
this.styles = initStyles(workbook);
|
||||
}
|
||||
|
||||
/**
|
||||
* 大标题样式
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CellStyle getHeaderStyle(short color) {
|
||||
return headerStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每列标题样式
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CellStyle getTitleStyle(short color) {
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据行样式 (控制全部行的样式)
|
||||
*
|
||||
* @param parity 表示奇偶行
|
||||
* @param entity 数据内容
|
||||
* @return 样式
|
||||
*/
|
||||
@Override
|
||||
public CellStyle getStyles(boolean parity, ExcelExportEntity entity) {
|
||||
return styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取样式方法
|
||||
*
|
||||
* @param dataRow 数据行
|
||||
* @param obj 对象
|
||||
* @param data 数据
|
||||
*/
|
||||
@Override
|
||||
public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) {
|
||||
return getStyles(true, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板使用的样式设置
|
||||
*/
|
||||
@Override
|
||||
public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化--大标题样式
|
||||
*
|
||||
* @param workbook
|
||||
* @return
|
||||
*/
|
||||
private CellStyle initHeaderStyle(Workbook workbook) {
|
||||
CellStyle style = getBaseCellStyle(workbook);
|
||||
style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化--每列标题样式
|
||||
*
|
||||
* @param workbook
|
||||
* @return
|
||||
*/
|
||||
private CellStyle initTitleStyle(Workbook workbook) {
|
||||
CellStyle style = getBaseCellStyle(workbook);
|
||||
style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false));
|
||||
//背景色
|
||||
// style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); //灰色
|
||||
// style.setFillForegroundColor(IndexedColors.AQUA.getIndex()); //浅蓝色
|
||||
style.setFillForegroundColor(IndexedColors.SEA_GREEN.getIndex()); //海藻绿
|
||||
|
||||
|
||||
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化--数据行样式
|
||||
*
|
||||
* @param workbook
|
||||
* @return
|
||||
*/
|
||||
private CellStyle initStyles(Workbook workbook) {
|
||||
CellStyle style = getBaseCellStyle(workbook);
|
||||
style.setFont(getFont(workbook, FONT_SIZE_TEN, false));
|
||||
style.setDataFormat(STRING_FORMAT);
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础样式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private CellStyle getBaseCellStyle(Workbook workbook) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
//下边框
|
||||
style.setBorderBottom(BorderStyle.THIN);
|
||||
//左边框
|
||||
style.setBorderLeft(BorderStyle.THIN);
|
||||
//上边框
|
||||
style.setBorderTop(BorderStyle.THIN);
|
||||
//右边框
|
||||
style.setBorderRight(BorderStyle.THIN);
|
||||
//水平居中
|
||||
style.setAlignment(HorizontalAlignment.CENTER);
|
||||
//上下居中
|
||||
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
//设置自动换行
|
||||
style.setWrapText(true);
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字体样式
|
||||
*
|
||||
* @param size 字体大小
|
||||
* @param isBold 是否加粗
|
||||
* @return
|
||||
*/
|
||||
private Font getFont(Workbook workbook, short size, boolean isBold) {
|
||||
Font font = workbook.createFont();
|
||||
//字体样式
|
||||
font.setFontName("宋体");
|
||||
//是否加粗
|
||||
font.setBold(isBold);
|
||||
//字体大小
|
||||
font.setFontHeightInPoints(size);
|
||||
return font;
|
||||
}
|
||||
}
|
||||
261
src/main/java/com/sqx/modules/utils/EasyPoi/ExcelUtils.java
Normal file
261
src/main/java/com/sqx/modules/utils/EasyPoi/ExcelUtils.java
Normal file
@@ -0,0 +1,261 @@
|
||||
package com.sqx.modules.utils.EasyPoi;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||
import cn.afterturn.easypoi.excel.ExcelImportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import com.sqx.modules.app.entity.UserEntity;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class ExcelUtils {
|
||||
|
||||
/**
|
||||
* 允许导出的最大条数
|
||||
*/
|
||||
private static final Integer EXPORT_EXCEL_MAX_NUM = 10000;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* excel 导出 (本地)
|
||||
* @param list 数据列表
|
||||
* @param excelType HSSF, XSSF
|
||||
*
|
||||
*/
|
||||
public static <T> void exportExcel(File file, List<T> list, ExcelType excelType) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null,file.getName(), excelType),
|
||||
UserEntity.class, list);
|
||||
|
||||
workbook.write(fos);
|
||||
workbook.close();
|
||||
}
|
||||
/**
|
||||
* excel 导出
|
||||
*
|
||||
* @param list 数据列表
|
||||
* @param fileName 导出时的excel名称
|
||||
* @param response
|
||||
*/
|
||||
public static void exportExcel(List<Map<String, Object>> list, String fileName, ExcelType excelType, HttpServletResponse response) throws IOException {
|
||||
defaultExport(list, fileName,excelType, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认的 excel 导出
|
||||
*
|
||||
* @param list 数据列表
|
||||
* @param fileName 导出时的excel名称
|
||||
* @param response
|
||||
*/
|
||||
private static void defaultExport(List<Map<String, Object>> list, String fileName,ExcelType excelType, HttpServletResponse response) throws IOException {
|
||||
|
||||
//把数据添加到excel表格中
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(list, excelType);
|
||||
downLoadExcel(fileName, response, workbook);
|
||||
}
|
||||
|
||||
/**
|
||||
* excel 导出
|
||||
*
|
||||
* @param list 数据列表
|
||||
* @param pojoClass pojo类型
|
||||
* @param fileName 导出时的excel名称
|
||||
* @param response
|
||||
* @param exportParams 导出参数(标题、sheet名称、是否创建表头,表格类型)
|
||||
*/
|
||||
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws IOException {
|
||||
//把数据添加到excel表格中
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
|
||||
downLoadExcel(fileName, response, workbook);
|
||||
}
|
||||
|
||||
/**
|
||||
* excel 导出
|
||||
*
|
||||
* @param list 数据列表
|
||||
* @param pojoClass pojo类型
|
||||
* @param fileName 导出时的excel名称
|
||||
* @param exportParams 导出参数(标题、sheet名称、是否创建表头,表格类型)
|
||||
* @param response
|
||||
*/
|
||||
public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams, HttpServletResponse response) throws IOException {
|
||||
defaultExport(list, pojoClass, fileName, response, exportParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* excel 导出
|
||||
*
|
||||
* @param list 数据列表
|
||||
* @param title 表格内数据标题
|
||||
* @param sheetName sheet名称
|
||||
* @param pojoClass pojo类型
|
||||
* @param fileName 导出时的excel名称
|
||||
* @param response
|
||||
*/
|
||||
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws IOException {
|
||||
//给文件名拼接上日期
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String dateString = formatter.format(new Date());
|
||||
fileName = fileName + dateString;
|
||||
//判断导出数据是否为空
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
//判断导出数据数量是否超过限定值
|
||||
if (list.size() > EXPORT_EXCEL_MAX_NUM) {
|
||||
title = "导出数据行数超过:" + EXPORT_EXCEL_MAX_NUM + "条,无法导出、请添加导出条件!";
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
//获取导出参数
|
||||
ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);
|
||||
//设置导出样式
|
||||
exportParams.setStyle(ExcelStyleUtil.class);
|
||||
//设置行高
|
||||
exportParams.setHeight((short) 6);
|
||||
|
||||
|
||||
defaultExport(list, pojoClass, fileName, response, exportParams);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据模板生成excel后导出
|
||||
*
|
||||
* @param templatePath 模板路径
|
||||
* @param map 数据集合
|
||||
* @param fileName 文件名
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void exportExcel(TemplateExportParams templatePath, Map<String, Object> map, String fileName, HttpServletResponse response) throws IOException {
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(templatePath, map);
|
||||
downLoadExcel(fileName, response, workbook);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* excel下载
|
||||
*
|
||||
* @param fileName 下载时的文件名称
|
||||
* @param response
|
||||
* @param workbook excel数据
|
||||
*/
|
||||
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
|
||||
try {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("content-Type", "application/vnd.ms-excel");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
|
||||
workbook.setForceFormulaRecalculation(true); //强制开启excel公式计算
|
||||
workbook.write(response.getOutputStream());
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* excel 导入
|
||||
*
|
||||
* @param file excel文件
|
||||
* @param pojoClass pojo类型
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> importExcel(MultipartFile file, Class<T> pojoClass) throws IOException {
|
||||
return importExcel(file, 1, 1, pojoClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* excel 导入
|
||||
*
|
||||
* @param filePath excel文件路径
|
||||
* @param titleRows 表格内数据标题行
|
||||
* @param headerRows 表头行
|
||||
* @param pojoClass pojo类型
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
|
||||
if (StringUtils.isBlank(filePath)) {
|
||||
return null;
|
||||
}
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(titleRows);
|
||||
params.setHeadRows(headerRows);
|
||||
params.setNeedSave(false);
|
||||
params.setSaveUrl("/excel/");
|
||||
try {
|
||||
return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new IOException("模板不能为空");
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* excel 导入
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @param titleRows 表格内数据标题行
|
||||
* @param headerRows 表头行
|
||||
* @param pojoClass pojo类型
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return importExcel(file.getInputStream(), titleRows, headerRows, pojoClass);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* excel 导入
|
||||
*
|
||||
* @param inputStream 文件输入流
|
||||
* @param titleRows 表格内数据标题行
|
||||
* @param headerRows 表头行
|
||||
* @param pojoClass pojo类型
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
|
||||
if (inputStream == null) {
|
||||
return null;
|
||||
}
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(titleRows);
|
||||
params.setHeadRows(headerRows);
|
||||
//excel模板必须包含的字段校验
|
||||
// params.setImportFields(new String[]{"短剧分类","是否收费","状态","是否完结","是否是推荐"});
|
||||
params.setNeedSave(false);
|
||||
try {
|
||||
return ExcelImportUtil.importExcel(inputStream, pojoClass, params);
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new IOException("excel文件不能为空");
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
63
src/main/java/com/sqx/modules/utils/FileUtils.java
Normal file
63
src/main/java/com/sqx/modules/utils/FileUtils.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileItemFactory;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
/**
|
||||
* 文件工具类
|
||||
* @author fang
|
||||
* @date 2021-03-4
|
||||
*/
|
||||
public class FileUtils {
|
||||
|
||||
/**
|
||||
* 根据文件地址下载文件
|
||||
* @param url 文件地址
|
||||
* @param fileName 文件名
|
||||
* @return
|
||||
*/
|
||||
public static MultipartFile createFileItem(String url, String fileName) {
|
||||
FileItem item = null;
|
||||
try {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setReadTimeout(30000);
|
||||
conn.setConnectTimeout(30000);
|
||||
//设置应用程序要从网络连接读取数据
|
||||
conn.setDoInput(true);
|
||||
conn.setRequestMethod("GET");
|
||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
InputStream is = conn.getInputStream();
|
||||
|
||||
FileItemFactory factory = new DiskFileItemFactory(16, null);
|
||||
String textFieldName = "uploadfile";
|
||||
item = factory.createItem(textFieldName, ContentType.APPLICATION_OCTET_STREAM.toString(), false, fileName);
|
||||
OutputStream os = item.getOutputStream();
|
||||
|
||||
int bytesRead = 0;
|
||||
byte[] buffer = new byte[8192];
|
||||
while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
|
||||
os.write(buffer, 0, bytesRead);
|
||||
}
|
||||
os.close();
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("文件下载失败", e);
|
||||
}
|
||||
|
||||
return new CommonsMultipartFile(item);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
257
src/main/java/com/sqx/modules/utils/HttpClientUtil.java
Normal file
257
src/main/java/com/sqx/modules/utils/HttpClientUtil.java
Normal file
@@ -0,0 +1,257 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class HttpClientUtil {
|
||||
|
||||
public static String doGet(String url, Map<String, String> param) {
|
||||
|
||||
// 创建Httpclient对象
|
||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||
|
||||
String resultString = "";
|
||||
CloseableHttpResponse response = null;
|
||||
try {
|
||||
// 创建uri
|
||||
URIBuilder builder = new URIBuilder(url);
|
||||
if (param != null) {
|
||||
for (String key : param.keySet()) {
|
||||
builder.addParameter(key, param.get(key));
|
||||
}
|
||||
}
|
||||
URI uri = builder.build();
|
||||
|
||||
// 创建http GET请求
|
||||
HttpGet httpGet = new HttpGet(uri);
|
||||
// 执行请求
|
||||
response = httpclient.execute(httpGet);
|
||||
// 判断返回状态是否为200
|
||||
if (response.getStatusLine().getStatusCode() == 200) {
|
||||
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
httpclient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
public static String doGet(String url) {
|
||||
return doGet(url, null);
|
||||
}
|
||||
|
||||
public static String doPost(String url, Map<String, String> param) {
|
||||
// 创建Httpclient对象
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
CloseableHttpResponse response = null;
|
||||
String resultString = "";
|
||||
try {
|
||||
// 创建Http Post请求
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
// 创建参数列表
|
||||
if (param != null) {
|
||||
List<NameValuePair> paramList = new ArrayList<>();
|
||||
for (String key : param.keySet()) {
|
||||
paramList.add(new BasicNameValuePair(key, param.get(key)));
|
||||
}
|
||||
// 模拟表单
|
||||
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
// 执行http请求
|
||||
response = httpClient.execute(httpPost);
|
||||
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
public static String doPost(String url) {
|
||||
return doPost(url, null);
|
||||
}
|
||||
|
||||
public static String doPostJson(String url, String json,String dyToken) {
|
||||
// 创建Httpclient对象
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
CloseableHttpResponse response = null;
|
||||
String resultString = "";
|
||||
try {
|
||||
// 创建Http Post请求
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setHeader("access-token",dyToken);
|
||||
// 创建请求内容
|
||||
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
|
||||
httpPost.setEntity(entity);
|
||||
// 执行http请求
|
||||
response = httpClient.execute(httpPost);
|
||||
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
public static String doPostJson(String url, String json) {
|
||||
// 创建Httpclient对象
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
CloseableHttpResponse response = null;
|
||||
String resultString = "";
|
||||
try {
|
||||
// 创建Http Post请求
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setHeader("Content-Type","application/json");
|
||||
// 创建请求内容
|
||||
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
|
||||
httpPost.setEntity(entity);
|
||||
// 执行http请求
|
||||
response = httpClient.execute(httpPost);
|
||||
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
/* 发送 post请求 用HTTPclient 发送请求*/
|
||||
public static byte[] post(String URL, String json) {
|
||||
String obj = null;
|
||||
InputStream inputStream = null;
|
||||
Buffer reader = null;
|
||||
byte[] data = null;
|
||||
// 创建默认的httpClient实例.
|
||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||
// 创建httppost
|
||||
HttpPost httppost = new HttpPost(URL);
|
||||
httppost.addHeader("Content-type", "application/json; charset=utf-8");
|
||||
httppost.setHeader("Accept", "application/json");
|
||||
try {
|
||||
StringEntity s = new StringEntity(json, Charset.forName("UTF-8"));
|
||||
s.setContentEncoding("UTF-8");
|
||||
httppost.setEntity(s);
|
||||
CloseableHttpResponse response = httpclient.execute(httppost);
|
||||
try {
|
||||
// 获取相应实体
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (entity != null) {
|
||||
inputStream = entity.getContent();
|
||||
data = readInputStream(inputStream);
|
||||
}
|
||||
return data;
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// 关闭连接,释放资源
|
||||
try {
|
||||
httpclient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/** 将流 保存为数据数组
|
||||
* @param inStream
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] readInputStream(InputStream inStream) throws Exception {
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
// 创建一个Buffer字符串
|
||||
byte[] buffer = new byte[1024];
|
||||
// 每次读取的字符串长度,如果为-1,代表全部读取完毕
|
||||
int len = 0;
|
||||
// 使用一个输入流从buffer里把数据读取出来
|
||||
while ((len = inStream.read(buffer)) != -1) {
|
||||
// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
|
||||
outStream.write(buffer, 0, len);
|
||||
}
|
||||
// 关闭输入流
|
||||
inStream.close();
|
||||
// 把outStream里的数据写入内存
|
||||
return outStream.toByteArray();
|
||||
}
|
||||
|
||||
public static void downloadImage(String imageUrl, String destinationFile) {
|
||||
try {
|
||||
URL url = new URL(imageUrl);
|
||||
InputStream inputStream = url.openStream();
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(destinationFile);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = inputStream.read(buffer)) > 0) {
|
||||
fileOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
fileOutputStream.close();
|
||||
inputStream.close();
|
||||
|
||||
log.info("图片已成功下载并保存到: " + destinationFile);
|
||||
} catch (IOException e) {
|
||||
log.error("下载图片时出错: " + e.getMessage(),e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
223
src/main/java/com/sqx/modules/utils/HttpUtil.java
Normal file
223
src/main/java/com/sqx/modules/utils/HttpUtil.java
Normal file
@@ -0,0 +1,223 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* 进行http访问的基本类
|
||||
*/
|
||||
public class HttpUtil {
|
||||
|
||||
private static final String DEFAULT_CHARSET = "UTF-8";
|
||||
|
||||
private static final String METHOD_POST = "POST";
|
||||
|
||||
private static final String METHOD_GET = "GET";
|
||||
|
||||
private static final int CONNECTTIMEOUT = 5000;
|
||||
|
||||
private static final int READTIMEOUT = 5000;
|
||||
|
||||
private static class DefaultTrustManager implements X509TrustManager {
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] cert, String oauthType)
|
||||
throws java.security.cert.CertificateException {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] cert, String oauthType)
|
||||
throws java.security.cert.CertificateException {
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpURLConnection getConnection(URL url, String method)
|
||||
throws IOException {
|
||||
|
||||
HttpURLConnection conn;
|
||||
if ("https".equals(url.getProtocol())) {
|
||||
SSLContext ctx;
|
||||
try {
|
||||
ctx = SSLContext.getInstance("TLS");
|
||||
ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() },
|
||||
new SecureRandom());
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
|
||||
connHttps.setSSLSocketFactory(ctx.getSocketFactory());
|
||||
connHttps.setHostnameVerifier(new HostnameVerifier() {
|
||||
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;// 默认都认证通过
|
||||
}
|
||||
});
|
||||
conn = connHttps;
|
||||
} else {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
}
|
||||
conn.setRequestMethod(method);
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(true);
|
||||
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
||||
conn.setRequestProperty("Connection", "Keep-Alive");
|
||||
return conn;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过get方法访问
|
||||
*
|
||||
* @param url 访问的url地址
|
||||
* @param urlParams 请求需要的参数
|
||||
* @return 返回请求响应的数据
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String doGet(String url, Map<String, String> urlParams)
|
||||
throws IOException {
|
||||
if (isEmpty(url)) {
|
||||
throw new IllegalArgumentException("The parameter 'url' can not be null or blank.");
|
||||
}
|
||||
url += buildQuery(urlParams, DEFAULT_CHARSET);
|
||||
HttpURLConnection conn = getConnection(new URL(url), METHOD_GET);
|
||||
String s = getResponseAsString(conn);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param url api请求的权路径url地址
|
||||
* @param urlParams 请求的参数
|
||||
* @param requestJson 请求报文
|
||||
* @return 请求响应
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String doPost(String url, Map<String, String> urlParams, String requestJson) throws IOException {
|
||||
return doPost(url, urlParams, requestJson, CONNECTTIMEOUT, READTIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 通过post方法请求数据
|
||||
*
|
||||
* @param url 请求的url地址
|
||||
* @param urlParams 请求的参数
|
||||
* @param requestJson 请求报文
|
||||
* @param connectTimeOut 请求连接过期时间
|
||||
* @param readTimeOut 请求读取过期时间
|
||||
* @return 请求响应
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String doPost(String url, Map<String, String> urlParams, String requestJson,
|
||||
int connectTimeOut, int readTimeOut) throws IOException {
|
||||
if (isEmpty(url)) {
|
||||
throw new IllegalArgumentException("The parameter 'url' can not be null or blank.");
|
||||
}
|
||||
url += buildQuery(urlParams, DEFAULT_CHARSET);
|
||||
HttpURLConnection conn = getConnection(new URL(url), METHOD_POST);
|
||||
conn.setConnectTimeout(connectTimeOut);
|
||||
conn.setReadTimeout(readTimeOut);
|
||||
conn.getOutputStream().write(requestJson.getBytes(DEFAULT_CHARSET));
|
||||
String s = getResponseAsString(conn);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params 请求参数
|
||||
* @return 构建query
|
||||
*/
|
||||
public static String buildQuery(Map<String, String> params, String charset) throws UnsupportedEncodingException {
|
||||
if (params == null || params.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Entry<String, String> entry : params.entrySet()) {
|
||||
if (first) {
|
||||
sb.append("?");
|
||||
first = false;
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
if (areNotEmpty(key, value)) {
|
||||
sb.append(key).append("=").append(URLEncoder.encode(value, charset));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
private static String getResponseAsString(HttpURLConnection conn) throws IOException {
|
||||
InputStream es = conn.getErrorStream();
|
||||
if (es == null) {
|
||||
return getStreamAsString(conn.getInputStream(), DEFAULT_CHARSET);
|
||||
} else {
|
||||
String msg = getStreamAsString(es, DEFAULT_CHARSET);
|
||||
if (isEmpty(msg)) {
|
||||
throw new IOException(conn.getResponseCode() + " : " + conn.getResponseMessage());
|
||||
} else {
|
||||
throw new IOException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String getStreamAsString(InputStream input, String charset) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
BufferedReader bf = null;
|
||||
try {
|
||||
bf = new BufferedReader(new InputStreamReader(input, charset));
|
||||
String str;
|
||||
while ((str = bf.readLine()) != null) {
|
||||
sb.append(str);
|
||||
}
|
||||
return sb.toString();
|
||||
} finally {
|
||||
if (bf != null) {
|
||||
bf.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串为空
|
||||
*
|
||||
* @param str 字符串信息
|
||||
* @return true or false
|
||||
*/
|
||||
private static boolean isEmpty(String str) {
|
||||
return str == null || str.trim().length() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符数组,不为空
|
||||
*
|
||||
* @param values 字符数组
|
||||
* @return true or false
|
||||
*/
|
||||
public static boolean areNotEmpty(String... values) {
|
||||
if (values == null || values.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String value : values) {
|
||||
if (isEmpty(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
86
src/main/java/com/sqx/modules/utils/InvitationCodeUtil.java
Normal file
86
src/main/java/com/sqx/modules/utils/InvitationCodeUtil.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
/**
|
||||
* 邀请码生成解密工具类
|
||||
* @author fang
|
||||
* @date 2020/7/8
|
||||
*/
|
||||
public class InvitationCodeUtil {
|
||||
|
||||
|
||||
/** 自定义进制(选择你想要的进制数,不能重复且最好不要0、1这些容易混淆的字符) */
|
||||
private static final char[] r=new char[]{ 'M', 'J', 'U', 'D', 'Z', 'X', '9', 'C', '7', 'P','E', '8', '6', 'B', 'G', 'H', 'S', '2', '5', 'F', 'R', '4','Q', 'W', 'K', '3', 'V', 'Y', 'T', 'N'};
|
||||
|
||||
/** 定义一个字符用来补全邀请码长度(该字符前面是计算出来的邀请码,后面是用来补全用的) */
|
||||
private static final char b='A';
|
||||
|
||||
/** 进制长度 */
|
||||
private static final int binLen=r.length;
|
||||
|
||||
/** 邀请码长度 */
|
||||
private static final int s=6;
|
||||
|
||||
|
||||
/** 补位字符串 */
|
||||
private static final String e="KSLFXFR";
|
||||
|
||||
/**
|
||||
* 根据ID生成六位随机码
|
||||
* @param id ID
|
||||
* @return 随机码
|
||||
*/
|
||||
public static String toSerialCode(long id) {
|
||||
char[] buf=new char[32];
|
||||
int charPos=32;
|
||||
|
||||
while((id / binLen) > 0) {
|
||||
int ind=(int)(id % binLen);
|
||||
buf[--charPos]=r[ind];
|
||||
id /= binLen;
|
||||
}
|
||||
buf[--charPos]=r[(int)(id % binLen)];
|
||||
String str=new String(buf, charPos, (32 - charPos));
|
||||
// 不够长度的自动补全
|
||||
if(str.length() < s) {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append(e.subSequence(0, s-str.length()));
|
||||
str+=sb.toString();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据随机码生成ID
|
||||
* @param code 随机码
|
||||
* @return ID
|
||||
*/
|
||||
public static long codeToId(String code) {
|
||||
char[] chs;
|
||||
chs = code.toCharArray();
|
||||
long res=0L;
|
||||
for(int i=0; i < chs.length; i++) {
|
||||
int ind=0;
|
||||
for(int j=0; j < binLen; j++) {
|
||||
if(chs[i] == r[j]) {
|
||||
ind=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(chs[i] == b) {
|
||||
break;
|
||||
}
|
||||
if(i > 0) {
|
||||
res=res * binLen + ind;
|
||||
} else {
|
||||
res=ind;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
180
src/main/java/com/sqx/modules/utils/MD5Util.java
Normal file
180
src/main/java/com/sqx/modules/utils/MD5Util.java
Normal file
@@ -0,0 +1,180 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5Util {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MD5Util.class);
|
||||
static MessageDigest messageDigest = null;
|
||||
|
||||
/**
|
||||
* 判断新密码和旧密码是否正确 返回true 和 false
|
||||
*
|
||||
* @param newStr
|
||||
* @param oldMD5Str
|
||||
* @return
|
||||
*/
|
||||
public final static boolean checkMD5(String newStr, String oldMD5Str) {
|
||||
String temp = encoderByMd5(newStr);
|
||||
return (temp != null && temp.equals(oldMD5Str)) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对给定的字符串进行加密
|
||||
*
|
||||
* @param source
|
||||
* @return 加密后的16进制的字符串
|
||||
*/
|
||||
public final static String encoderByMd5(String source) {
|
||||
String tmp = source.substring(0, 1)
|
||||
+ source.subSequence(source.length() - 1, source.length());
|
||||
tmp = md5(tmp);
|
||||
return md5(source + tmp);
|
||||
}
|
||||
|
||||
private static String md5(String source) {
|
||||
|
||||
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
|
||||
'e', 'f'};
|
||||
try {
|
||||
|
||||
byte[] strTemp = source.getBytes();
|
||||
// 使用MD5创建MessageDigest对象
|
||||
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 b : md) {
|
||||
str[k++] = hexDigits[b >> 4 & 0xf];
|
||||
str[k++] = hexDigits[b & 0xf];
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("加密后的字符串:" + new String(str));
|
||||
}
|
||||
return new String(str);
|
||||
} catch (Exception e) {
|
||||
logger.error("md5加密出错:" + source, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String encodeByMD5(String str) {
|
||||
try {
|
||||
if (messageDigest == null)
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
messageDigest.reset();
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
logger.error("NoSuchAlgorithmException caught!", e);
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("UnsupportedEncodingException error!", e);
|
||||
}
|
||||
if (messageDigest == null)
|
||||
return "";
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密字符串(32位大写)
|
||||
*
|
||||
* @param string 需要进行MD5加密的字符串
|
||||
* @return 加密后的字符串(大写)
|
||||
*/
|
||||
public static String md5Encrypt32Upper(String string) {
|
||||
byte[] hash;
|
||||
try {
|
||||
//创建一个MD5算法对象,并获得MD5字节数组,16*8=128位
|
||||
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("Huh, MD5 should be supported?", e);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Huh, UTF-8 should be supported?", e);
|
||||
}
|
||||
//转换为十六进制字符串
|
||||
StringBuilder hex = new StringBuilder(hash.length * 2);
|
||||
for (byte b : hash) {
|
||||
if ((b & 0xFF) < 0x10) hex.append("0");
|
||||
hex.append(Integer.toHexString(b & 0xFF));
|
||||
}
|
||||
return hex.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
public static String encryption(String plain) {
|
||||
String re_md5 = new String();
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(plain.getBytes("utf-8"));
|
||||
byte b[] = md.digest();
|
||||
|
||||
int i;
|
||||
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (int offset = 0; offset < b.length; offset++) {
|
||||
i = b[offset];
|
||||
if (i < 0)
|
||||
i += 256;
|
||||
if (i < 16)
|
||||
buf.append("0");
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
|
||||
re_md5 = buf.toString();
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return re_md5;
|
||||
}
|
||||
//
|
||||
public static String calculateHmacSha256(String data, String key) {
|
||||
try {
|
||||
// 1. 生成密钥
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
|
||||
// 2. 创建Mac对象
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
// 3. 初始化Mac对象
|
||||
mac.init(secretKeySpec);
|
||||
// 4. 加密数据
|
||||
byte[] hmacBytes = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
||||
// 5. 获取加密结果
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (byte b : hmacBytes) {
|
||||
// 将字节转换成16进制字符串
|
||||
stringBuilder.append(String.format("%02x", b));
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/com/sqx/modules/utils/MessageUtil.java
Normal file
22
src/main/java/com/sqx/modules/utils/MessageUtil.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
public class MessageUtil {
|
||||
public static final String MESSAGE_TEXT = "text";
|
||||
public static final String MESSAGE_IMAGE = "image";
|
||||
public static final String MESSAGE_VOICE = "voice";
|
||||
public static final String MESSAGE_VIDEO = "video";
|
||||
public static final String MESSAGE_LINK = "link";
|
||||
public static final String MESSAGE_LOCATION = "location";
|
||||
public static final String MESSAGE_EVENT = "event";
|
||||
public static final String EVENT_SUB = "subscribe";
|
||||
public static final String EVENT_SCAN = "SCAN";
|
||||
public static final String EVENT_UNSUB = "unsubscribe";
|
||||
public static final String EVENT_CLICK = "CLICK";
|
||||
public static final String EVENT_VIEW = "VIEW";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
248
src/main/java/com/sqx/modules/utils/SenInfoCheckUtil.java
Normal file
248
src/main/java/com/sqx/modules/utils/SenInfoCheckUtil.java
Normal file
@@ -0,0 +1,248 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sqx.modules.common.service.CommonInfoService;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Component
|
||||
public class SenInfoCheckUtil {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(SenInfoCheckUtil.class);
|
||||
|
||||
private static String MpAccessToken;
|
||||
|
||||
private static String DyAccessToken;
|
||||
|
||||
// 这里使用静态,让 service 属于类
|
||||
private static CommonInfoService commonInfoService;
|
||||
|
||||
// 注入的时候,给类的 service 注入
|
||||
@Autowired
|
||||
public void setWxChatContentService(CommonInfoService commonInfoService) {
|
||||
SenInfoCheckUtil.commonInfoService = commonInfoService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取Token 小程序
|
||||
* @param
|
||||
* @param
|
||||
* @return AccessToken
|
||||
*/
|
||||
public static String getMpToken(){
|
||||
return getMpAccessToken();
|
||||
}
|
||||
|
||||
public static String getDyToken(){
|
||||
return getDyAccessToken();
|
||||
}
|
||||
|
||||
|
||||
public static void getImg(String relation,String goodsId,String type, String page,HttpServletResponse response){
|
||||
String mpToken = getMpToken();
|
||||
//获取二维码数据
|
||||
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+mpToken;
|
||||
Map<String,Object> map = Maps.newHashMap();
|
||||
map.put("scene",relation+"&"+goodsId+"&"+type);
|
||||
String value = commonInfoService.findOne(105).getValue();
|
||||
if("是".equals(value)){
|
||||
map.put("page",page);
|
||||
}
|
||||
map.put("width", 280);
|
||||
String jsonString = JSON.toJSONString(map);
|
||||
InputStream inputStream = sendPostBackStream(url, jsonString);
|
||||
//生成二维码图片
|
||||
response.setContentType("image/png");
|
||||
try{
|
||||
BufferedImage bi = ImageIO.read(inputStream);
|
||||
ImageIO.write(bi, "JPG", response.getOutputStream());
|
||||
inputStream.close();
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取二维码图片
|
||||
*/
|
||||
public static void getDyImg(String invitationCode,String page, HttpServletResponse response){
|
||||
String dyToken = getDyToken();
|
||||
//获取二维码数据
|
||||
String url = "https://open.douyin.com/api/apps/v1/qrcode/create/";
|
||||
|
||||
JSONObject map = new JSONObject();
|
||||
String[] split = invitationCode.split(",");
|
||||
|
||||
String path="{"+page+"}?invitation="+split[0]+"&qdCode="+split[1];
|
||||
try {
|
||||
path = URLEncoder.encode(path,"utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String appid = commonInfoService.findOne(805).getValue();
|
||||
map.put("appid",appid);
|
||||
map.put("path",path);
|
||||
map.put("app_name","douyin");
|
||||
map.put("is_circle_code",false);
|
||||
map.put("set_icon",true);
|
||||
|
||||
String s = HttpClientUtil.doPostJson(url, map.toJSONString(),dyToken);
|
||||
JSONObject jsonObject = JSONObject.parseObject(s);
|
||||
String err_no = jsonObject.getString("err_no");
|
||||
if(!"0".equals(err_no)){
|
||||
logger.error("抖音二维码生成失败:"+jsonObject.getString("err_msg"));
|
||||
}
|
||||
JSONObject data = jsonObject.getJSONObject("data");
|
||||
String img = data.getString("img");
|
||||
BufferedImage bi = base64ToBufferedImage(img);
|
||||
if(bi!=null){
|
||||
//生成二维码图片
|
||||
response.setContentType("image/png");
|
||||
try{
|
||||
ImageIO.write(bi, "JPG", response.getOutputStream());
|
||||
}catch (Exception e){
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* base64 编码转换为 BufferedImage
|
||||
* @param base64
|
||||
* @return
|
||||
*/
|
||||
public static BufferedImage base64ToBufferedImage(String base64) {
|
||||
Base64.Decoder decoder = Base64.getDecoder();
|
||||
try {
|
||||
byte[] byteArray = decoder.decode(base64);
|
||||
ByteArrayInputStream bai = new ByteArrayInputStream(byteArray);
|
||||
return ImageIO.read(bai);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取二维码图片
|
||||
*/
|
||||
public static void getPoster(String invitationCode,String page, HttpServletResponse response){
|
||||
String mpToken = getMpToken();
|
||||
//获取二维码数据
|
||||
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+mpToken;
|
||||
Map<String,Object> map = Maps.newHashMap();
|
||||
map.put("scene",invitationCode);
|
||||
if(StringUtils.isNotEmpty(page)){
|
||||
map.put("page",page);
|
||||
}
|
||||
map.put("width", 280);
|
||||
String jsonString = JSON.toJSONString(map);
|
||||
InputStream inputStream = sendPostBackStream(url, jsonString);
|
||||
//生成二维码图片
|
||||
response.setContentType("image/png");
|
||||
try{
|
||||
BufferedImage bi = ImageIO.read(inputStream);
|
||||
ImageIO.write(bi, "JPG", response.getOutputStream());
|
||||
inputStream.close();
|
||||
}catch (Exception e){
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static InputStream sendPostBackStream(String url, String param) {
|
||||
PrintWriter out = null;
|
||||
try {
|
||||
URL realUrl = new URL(url);
|
||||
// 打开和URL之间的连接
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
// 设置通用的请求属性
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
//解决乱码问题
|
||||
OutputStreamWriter outWriter =new OutputStreamWriter(conn.getOutputStream(), "utf-8");
|
||||
out =new PrintWriter(outWriter);
|
||||
// 发送请求参数
|
||||
if(StringUtils.isNotBlank(param)) {
|
||||
out.print(param);
|
||||
}
|
||||
// flush输出流的缓冲
|
||||
out.flush();
|
||||
return conn.getInputStream();
|
||||
} catch (Exception e) {
|
||||
logger.error("发送 POST 请求出现异常!"+e);
|
||||
} finally{
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取access_token
|
||||
* 每个两个小时自动刷新AcessTocken
|
||||
*/
|
||||
public static String getMpAccessToken(){
|
||||
String appid = commonInfoService.findOne(45).getValue();
|
||||
String secret = commonInfoService.findOne(46).getValue();
|
||||
String jsonResult = HttpClientUtil.doPost("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret);
|
||||
JSONObject parseObject = JSON.parseObject(jsonResult);
|
||||
logger.info("=========accessTokenOut========="+parseObject.toJSONString());
|
||||
|
||||
String errcode = parseObject.getString("errcode");
|
||||
String accessToken = parseObject.getString("access_token");
|
||||
String expiresIn = parseObject.getString("expires_in");
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取access_token
|
||||
* 每个两个小时自动刷新AcessTocken
|
||||
*/
|
||||
|
||||
public static String getDyAccessToken(){
|
||||
String appid = commonInfoService.findOne(805).getValue();
|
||||
String secret = commonInfoService.findOne(806).getValue();
|
||||
Map<String,String> jsonObject=new HashMap<>();
|
||||
jsonObject.put("appid",appid);
|
||||
jsonObject.put("secret",secret);
|
||||
jsonObject.put("grant_type","client_credential");
|
||||
String jsonResult = HttpClientUtil.doPost("https://open.douyin.com/oauth/client_token/",jsonObject);
|
||||
|
||||
JSONObject parseObject = JSON.parseObject(jsonResult);
|
||||
logger.info("=========accessTokenOut========="+parseObject.toJSONString());
|
||||
JSONObject data = parseObject.getJSONObject("data");
|
||||
return data.getString("access_token");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
70
src/main/java/com/sqx/modules/utils/WXConfigUtil.java
Normal file
70
src/main/java/com/sqx/modules/utils/WXConfigUtil.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package com.sqx.modules.utils;
|
||||
|
||||
import com.github.wxpay.sdk.WXPayConfig;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
/**
|
||||
* @author fang
|
||||
* @date 2020/2/26
|
||||
*/
|
||||
@Data
|
||||
public class WXConfigUtil implements WXPayConfig {
|
||||
private byte[] certData;
|
||||
private String appId = "";
|
||||
private String key = "";
|
||||
private String mchId = "";
|
||||
|
||||
|
||||
//初始化加载证书
|
||||
public WXConfigUtil(String filePath) throws Exception {
|
||||
|
||||
File file = new File(filePath);
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = Files.newInputStream(file.toPath());
|
||||
this.certData = IOUtils.toByteArray(fis);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getAppID() {
|
||||
return this.appId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMchID() {
|
||||
return this.mchId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getCertStream() {
|
||||
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
|
||||
return certBis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpConnectTimeoutMs() {
|
||||
return 8000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpReadTimeoutMs() {
|
||||
return 10000;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
34
src/main/java/com/sqx/modules/utils/excel/ExcelData.java
Normal file
34
src/main/java/com/sqx/modules/utils/excel/ExcelData.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.sqx.modules.utils.excel;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fang
|
||||
* @date 2020/9/24
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class ExcelData implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4454016249210520899L;
|
||||
|
||||
/**
|
||||
* 表头
|
||||
*/
|
||||
private List<String> titles;
|
||||
|
||||
/**
|
||||
* 数据
|
||||
*/
|
||||
private List<List<Object>> rows;
|
||||
|
||||
/**
|
||||
* 页签名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
||||
}
|
||||
171
src/main/java/com/sqx/modules/utils/excel/ExcelUtils.java
Normal file
171
src/main/java/com/sqx/modules/utils/excel/ExcelUtils.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package com.sqx.modules.utils.excel;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileItemFactory;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author fang
|
||||
* @date 2021/1/27
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExcelUtils {
|
||||
|
||||
/*public static List<OilStation> get(String fileUrl){
|
||||
MultipartFile fileItem = createFileItem(fileUrl, null);
|
||||
String substring = fileUrl.substring(fileUrl.lastIndexOf("."));
|
||||
List<OilStation> list=new ArrayList<>();
|
||||
try {
|
||||
// String fileName = fileItem.getOriginalFilename();
|
||||
String xls=".xlsx";
|
||||
InputStream inputStream = fileItem.getInputStream();
|
||||
log.info("文件名:{}", substring);
|
||||
int serviceStationNo=0;
|
||||
int serviceStationName=0;
|
||||
int oilName=0;
|
||||
int activity=0;
|
||||
int downPrice=0;
|
||||
//区分两种excel表格
|
||||
if(substring.indexOf(xls)!=-1){
|
||||
XSSFWorkbook workbook=new XSSFWorkbook(inputStream);
|
||||
//获取第一个工作表
|
||||
org.apache.poi.xssf.usermodel.XSSFSheet hs=workbook.getSheetAt(0);
|
||||
//获取Sheet的第一个行号和最后一个行号
|
||||
int last=hs.getLastRowNum();
|
||||
int first=hs.getFirstRowNum();
|
||||
//遍历获取单元格里的信息
|
||||
for (int i = first; i <=last; i++) {
|
||||
XSSFRow row=hs.getRow(i);
|
||||
int firstCellNum=row.getFirstCellNum();//获取所在行的第一个行号
|
||||
int lastCellNum=row.getLastCellNum();//获取所在行的最后一个行号
|
||||
OilStation oilStation=new OilStation();
|
||||
for (int j = firstCellNum; j <lastCellNum; j++) {
|
||||
XSSFCell cell=row.getCell(j);
|
||||
cell.setCellType(CellType.STRING);
|
||||
String value=cell.getStringCellValue();
|
||||
if("油站编码".equals(value)){
|
||||
serviceStationNo=j;
|
||||
}else if("油站名称".equals(value)){
|
||||
serviceStationName=j;
|
||||
}else if("油品".equals(value)){
|
||||
oilName=j;
|
||||
}else if("活动时间".equals(value)){
|
||||
activity=j;
|
||||
}else if("直降".equals(value)){
|
||||
downPrice=j;
|
||||
}else{
|
||||
if(j==serviceStationNo){
|
||||
oilStation.setServiceStationNo(value);
|
||||
}else if(j==serviceStationName){
|
||||
oilStation.setServiceStationName(value);
|
||||
}else if(j==oilName){
|
||||
oilStation.setOilName(value);
|
||||
}else if(j==activity){
|
||||
oilStation.setActivity(value);
|
||||
}else if(j==downPrice){
|
||||
oilStation.setDownPrice(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(oilStation.getServiceStationNo())){
|
||||
list.add(oilStation);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
HSSFWorkbook workbook=new HSSFWorkbook(inputStream);
|
||||
//获取第一个工作表
|
||||
HSSFSheet hs=workbook.getSheetAt(0);
|
||||
//获取Sheet的第一个行号和最后一个行号
|
||||
int last=hs.getLastRowNum();
|
||||
int first=hs.getFirstRowNum();
|
||||
//遍历获取单元格里的信息
|
||||
for (int i = first; i <=last; i++) {
|
||||
HSSFRow row=hs.getRow(i);
|
||||
int firstCellNum=row.getFirstCellNum();//获取所在行的第一个行号
|
||||
int lastCellNum=row.getLastCellNum();//获取所在行的最后一个行号
|
||||
OilStation oilStation=new OilStation();
|
||||
for (int j = firstCellNum; j <lastCellNum; j++) {
|
||||
HSSFCell cell=row.getCell(j);
|
||||
cell.setCellType(CellType.STRING);
|
||||
String value=cell.getStringCellValue();
|
||||
if("油站编码".equals(value)){
|
||||
serviceStationNo=j;
|
||||
}else if("油站名称".equals(value)){
|
||||
serviceStationName=j;
|
||||
}else if("油品".equals(value)){
|
||||
oilName=j;
|
||||
}else if("活动时间".equals(value)){
|
||||
activity=j;
|
||||
}else if("直降".equals(value)){
|
||||
downPrice=j;
|
||||
}else{
|
||||
if(j==serviceStationNo){
|
||||
oilStation.setServiceStationNo(value);
|
||||
}else if(j==serviceStationName){
|
||||
oilStation.setServiceStationName(value);
|
||||
}else if(j==oilName){
|
||||
oilStation.setOilName(value);
|
||||
}else if(j==activity){
|
||||
oilStation.setActivity(value);
|
||||
}else if(j==downPrice){
|
||||
oilStation.setDownPrice(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(oilStation.getServiceStationNo())){
|
||||
list.add(oilStation);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return list;
|
||||
}*/
|
||||
|
||||
|
||||
public static MultipartFile createFileItem(String url, String fileName) {
|
||||
FileItem item = null;
|
||||
try {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setReadTimeout(30000);
|
||||
conn.setConnectTimeout(30000);
|
||||
//设置应用程序要从网络连接读取数据
|
||||
conn.setDoInput(true);
|
||||
conn.setRequestMethod("GET");
|
||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
InputStream is = conn.getInputStream();
|
||||
|
||||
FileItemFactory factory = new DiskFileItemFactory(16, null);
|
||||
String textFieldName = "uploadfile";
|
||||
item = factory.createItem(textFieldName, ContentType.APPLICATION_OCTET_STREAM.toString(), false, fileName);
|
||||
OutputStream os = item.getOutputStream();
|
||||
|
||||
int bytesRead = 0;
|
||||
byte[] buffer = new byte[8192];
|
||||
while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
|
||||
os.write(buffer, 0, bytesRead);
|
||||
}
|
||||
os.close();
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("文件下载失败", e);
|
||||
}
|
||||
|
||||
return new CommonsMultipartFile(item);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
209
src/main/java/com/sqx/modules/utils/excel/ExportExcelUtils.java
Normal file
209
src/main/java/com/sqx/modules/utils/excel/ExportExcelUtils.java
Normal file
@@ -0,0 +1,209 @@
|
||||
package com.sqx.modules.utils.excel;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fang
|
||||
* @date 2020/9/24
|
||||
*/
|
||||
public class ExportExcelUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* @param response
|
||||
* @param fileName
|
||||
* @param data
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void exportExcel(HttpServletResponse response, String fileName, ExcelData data) throws Exception {
|
||||
// 告诉浏览器用什么软件可以打开此文件
|
||||
response.setHeader("content-Type", "application/vnd.ms-excel");
|
||||
// 下载文件的默认名称
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
|
||||
exportExcel(data, response.getOutputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 表格
|
||||
* @param data
|
||||
* @param out
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void exportExcel(ExcelData data, OutputStream out) throws Exception {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
try {
|
||||
String sheetName = data.getName();
|
||||
if (null == sheetName) {
|
||||
sheetName = "Sheet1";
|
||||
}
|
||||
XSSFSheet sheet = wb.createSheet(sheetName);
|
||||
writeExcel(wb, sheet, data);
|
||||
wb.write(out);
|
||||
} finally {
|
||||
wb.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据写入表格
|
||||
* @param wb
|
||||
* @param sheet
|
||||
* @param data
|
||||
*/
|
||||
private static void writeExcel(XSSFWorkbook wb, Sheet sheet, ExcelData data) {
|
||||
int rowIndex = 0;
|
||||
rowIndex = writeTitlesToExcel(wb, sheet, data.getTitles());
|
||||
writeRowsToExcel(wb, sheet, data.getRows(), rowIndex);
|
||||
autoSizeColumns(sheet, data.getTitles().size() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入表头
|
||||
* @param wb
|
||||
* @param sheet
|
||||
* @param titles
|
||||
* @return
|
||||
*/
|
||||
private static int writeTitlesToExcel(XSSFWorkbook wb, Sheet sheet, List<String> titles) {
|
||||
int rowIndex = 0;
|
||||
int colIndex = 0;
|
||||
Font titleFont = wb.createFont();//获取字体
|
||||
titleFont.setFontName("simsun");//设置字体名称(宋体)
|
||||
titleFont.setBold(true);//设置字体加粗
|
||||
titleFont.setColor(IndexedColors.BLACK.index);//设置字体颜色 黑色
|
||||
XSSFCellStyle titleStyle = wb.createCellStyle();//获取单元格样式
|
||||
titleStyle.setAlignment(HorizontalAlignment.CENTER);//设置单元格的水平对齐类型(这里是水平居中)
|
||||
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//设置单元格的垂直对齐类型(这里是居中)
|
||||
titleStyle.setFillForegroundColor(createXssfColor("#FFFFFF"));//设置单元格前景色(白色)
|
||||
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//指定图案和纯色单元格填充的单元格填充信息(实心前景)
|
||||
titleStyle.setFont(titleFont);//设置字体样式
|
||||
setBorder(titleStyle, BorderStyle.THIN, createXssfColor("#000000"));//设置边框样式(细线、黑色)
|
||||
Row titleRow = sheet.createRow(rowIndex);//在该工作簿中创建第一行.
|
||||
colIndex = 0;
|
||||
for (String field : titles) {//循环创建列
|
||||
Cell cell = titleRow.createCell(colIndex);
|
||||
cell.setCellValue(field);
|
||||
cell.setCellStyle(titleStyle);
|
||||
colIndex++;
|
||||
}
|
||||
rowIndex++;//将行数++ 返回用于下面添加数据
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据写入
|
||||
* @param wb
|
||||
* @param sheet
|
||||
* @param rows
|
||||
* @param rowIndex
|
||||
* @return
|
||||
*/
|
||||
private static int writeRowsToExcel(XSSFWorkbook wb, Sheet sheet, List<List<Object>> rows, int rowIndex) {
|
||||
int colIndex = 0;
|
||||
Font dataFont = wb.createFont();//获取字体
|
||||
dataFont.setFontName("simsun");//设置字体名称(宋体)
|
||||
dataFont.setColor(IndexedColors.BLACK.index);//设置字体颜色 黑色
|
||||
XSSFCellStyle dataStyle = wb.createCellStyle();//获取单元格样式
|
||||
dataStyle.setAlignment(HorizontalAlignment.CENTER);//设置单元格的水平对齐类型(这里是水平居中)
|
||||
dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);//设置单元格的垂直对齐类型(这里是居中)
|
||||
dataStyle.setFont(dataFont);//设置字体样式
|
||||
setBorder(dataStyle, BorderStyle.THIN, createXssfColor("#000000"));//设置边框样式(细线、黑色)
|
||||
for (List<Object> rowData : rows) {//循环写入数据
|
||||
Row dataRow = sheet.createRow(rowIndex);
|
||||
colIndex = 0;
|
||||
for (Object cellData : rowData) {
|
||||
Cell cell = dataRow.createCell(colIndex);
|
||||
if (cellData != null) {
|
||||
cell.setCellValue(cellData.toString());
|
||||
} else {
|
||||
cell.setCellValue("");
|
||||
}
|
||||
|
||||
cell.setCellStyle(dataStyle);
|
||||
colIndex++;
|
||||
}
|
||||
rowIndex++;
|
||||
}
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动调整大小
|
||||
* @param sheet
|
||||
* @param columnNumber
|
||||
*/
|
||||
private static void autoSizeColumns(Sheet sheet, int columnNumber) {
|
||||
for (int i = 0; i < columnNumber; i++) {
|
||||
int orgWidth = sheet.getColumnWidth(i);
|
||||
sheet.autoSizeColumn(i, true);
|
||||
int newWidth = (int) (sheet.getColumnWidth(i) + 100);
|
||||
if (newWidth > orgWidth) {
|
||||
sheet.setColumnWidth(i, newWidth);
|
||||
} else {
|
||||
sheet.setColumnWidth(i, orgWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置表格样式
|
||||
* @param style
|
||||
* @param border
|
||||
* @param color
|
||||
*/
|
||||
private static void setBorder(XSSFCellStyle style, BorderStyle border, XSSFColor color) {
|
||||
style.setBorderTop(border);
|
||||
style.setBorderLeft(border);
|
||||
style.setBorderRight(border);
|
||||
style.setBorderBottom(border);
|
||||
style.setBorderColor(XSSFCellBorder.BorderSide.TOP, color);
|
||||
style.setBorderColor(XSSFCellBorder.BorderSide.LEFT, color);
|
||||
style.setBorderColor(XSSFCellBorder.BorderSide.RIGHT, color);
|
||||
style.setBorderColor(XSSFCellBorder.BorderSide.BOTTOM, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将rgb颜色码 转换为 XSSFColor
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
private static XSSFColor createXssfColor(String color) {
|
||||
int[] rgbColor = hexToRgb(color);
|
||||
XSSFColor xssfColor = new XSSFColor(new java.awt.Color(rgbColor[0], rgbColor[1], rgbColor[2]), new DefaultIndexedColorMap());
|
||||
return xssfColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将颜色码 转换为 r g b
|
||||
* @param hex
|
||||
* @return
|
||||
*/
|
||||
public static int[] hexToRgb(String hex) {
|
||||
String colorStr = hex;
|
||||
if (hex.startsWith("#")) {
|
||||
colorStr = hex.substring(1);
|
||||
}
|
||||
if (StringUtils.length(colorStr) == 8) {
|
||||
colorStr = hex.substring(2);
|
||||
}
|
||||
int r= Integer.valueOf( colorStr.substring( 0, 2 ), 16 );
|
||||
int g= Integer.valueOf( colorStr.substring( 2, 4 ), 16 );
|
||||
int b= Integer.valueOf( colorStr.substring( 4, 6 ), 16 );
|
||||
|
||||
return new int[] { r, g, b };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
18
src/main/java/com/sqx/modules/utils/qrcode/QRCode.java
Normal file
18
src/main/java/com/sqx/modules/utils/qrcode/QRCode.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.sqx.modules.utils.qrcode;
|
||||
|
||||
import cn.hutool.extra.qrcode.QrConfig;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@Configuration
|
||||
public class QRCode {
|
||||
@Bean
|
||||
public QrConfig qrConfig(){
|
||||
QrConfig qrConfig=new QrConfig();
|
||||
qrConfig.setBackColor(Color.white.getRGB());
|
||||
qrConfig.setForeColor(Color.black.getRGB());
|
||||
return qrConfig;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user