13 Commits

Author SHA1 Message Date
41a9f1b507 Merge remote-tracking branch 'origin/jre11' into jre11
# Conflicts:
#	src/main/java/com/yexuejc/base/util/JsonUtil.java
2023-09-20 10:02:40 +08:00
bf731e753a 增加StrUtil.printStackTrace方法:把异常堆栈信息转化为字符串 -> 替代 e.printStackTrace() 2023-09-20 10:01:58 +08:00
8d5e653d2b 增加StrUtil.printStackTrace方法:把异常堆栈信息转化为字符串 -> 替代 e.printStackTrace() 2023-09-20 10:01:27 +08:00
c4fc4bd4f8 [update]FileUtil优化分页读取 2023-07-19 20:14:15 +08:00
yexuejc007
667ad26971 [update] ObjUtil.copy方法优化(即使copy不成功,也不报错,出警告日志)。PR:copy源和目标对象中的属性类型不一致,copy不成功 2023-06-15 14:24:05 +08:00
yexuejc007
a260b41fae Merge remote-tracking branch 'origin/jre11' into jre11 2023-06-13 17:56:08 +08:00
yexuejc007
0754660c45 [feat] ObjUtil 增加对象的深度copy 2023-06-13 17:55:37 +08:00
0dc13a6aa1 1.5.1-jre11 2023-06-08 16:11:04 +08:00
yexuejc007
3ddd11f9c9 [update] JsonUtil 升级优化,增加特殊需求String的反序列化 2023-05-29 17:30:07 +08:00
yexuejc007
a05bb00123 [update] JsonUtil 升级优化,提供不同序列化反序列化的jsonmapper,处理反序列化时间值为空时的优化 2023-05-29 16:59:53 +08:00
yexuejc007
77a0e29916 [feat] 增加json化时对LocalDateTime,LocalDate,Timestamp时间的优化;
[version] 1.5.2-jdk11(未发布)
2023-05-17 14:02:28 +08:00
yexuejc007
b0b8cbc7ab [update] 日期时间工具丰富 2023-05-15 16:47:57 +08:00
4c77c4ebe8 AES加解密
文件压缩
FileUtil.base64ToStr 优化
兼容jdk11
2022-11-11 19:25:46 +08:00
23 changed files with 1352 additions and 164 deletions

View File

@@ -1,6 +1,20 @@
yexuejc-base 更新记录 yexuejc-base 更新记录
------------------ ------------------
#### version 1.5.1-jre11
**time2023-6-8 16:02:56** <br/>
**branch** jre11 <br/>
**update** <br/>
1. FileUtil 增加读取csv文件分页读取
提供读取IO流方法合集
2. 增加AES加解密
3. 增加文件压缩ZipUtil
4. DateUtilDateTimeUtil 时间操作工具优化
5. JsonUtil [feat] 增加json化时对LocalDateTime,LocalDate,Timestamp时间的优化,增加特殊场景序列化反序列化
---
#### version 1.5.0-jre8 #### version 1.5.0-jre8
**time2022-5-9 13:37:31** <br/> **time2022-5-9 13:37:31** <br/>
**branch** master <br/> **branch** master <br/>

30
pom.xml
View File

@@ -6,16 +6,16 @@
<groupId>top.yexuejc</groupId> <groupId>top.yexuejc</groupId>
<artifactId>yexuejc-base</artifactId> <artifactId>yexuejc-base</artifactId>
<version>1.5.0-jre8</version> <version>1.5.1-jre11</version>
<name>yexuejc-base</name> <name>yexuejc-base</name>
<url>https://github.com/yexuejc/yexuejc-base</url> <url>https://github.com/yexuejc/yexuejc-base</url>
<description>Common toolkits based on JDK8 packaging</description> <description>Common toolkits based on JDK11 packaging</description>
<licenses> <licenses>
<license> <license>
<name>The Apache Software License, Version 2.0</name> <name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license> </license>
</licenses> </licenses>
@@ -44,14 +44,15 @@
<repos.jitpack.url>https://jitpack.io</repos.jitpack.url> <repos.jitpack.url>https://jitpack.io</repos.jitpack.url>
<jjwt.version>0.11.5</jjwt.version> <jjwt.version>0.11.5</jjwt.version>
<maven.compiler.verbose>true</maven.compiler.verbose> <maven.compiler.verbose>true</maven.compiler.verbose>
<java.version>1.8</java.version> <java.version>11</java.version>
<validation-api.version>3.0.1</validation-api.version> <validation-api.version>3.0.2</validation-api.version>
<commons-io.version>2.11.0</commons-io.version> <commons-io.version>2.11.0</commons-io.version>
<bcprov-jdk15on.version>1.70</bcprov-jdk15on.version> <bcprov-jdk15on.version>1.70</bcprov-jdk15on.version>
<guava.version>31.1-jre</guava.version> <guava.version>31.1-jre</guava.version>
<apache-poi.version>5.2.2</apache-poi.version> <apache-poi.version>5.2.2</apache-poi.version>
<jackson.version>2.13.2</jackson.version> <jackson.version>2.14.2</jackson.version>
<zip4j.version>2.11.4</zip4j.version>
<!-- 文件拷贝时的编码 --> <!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@@ -117,11 +118,22 @@
<artifactId>jackson-dataformat-csv</artifactId> <artifactId>jackson-dataformat-csv</artifactId>
<version>${jackson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>${zip4j.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>5.8.1</version> <version>5.9.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@@ -136,8 +148,8 @@
<version>3.8.1</version> <version>3.8.1</version>
<configuration> <configuration>
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
<source>8</source> <source>11</source>
<target>8</target> <target>11</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- 打包源码 --> <!-- 打包源码 -->

View File

@@ -11,11 +11,21 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Inherited @Inherited
public @interface CsvHeader { public @interface CsvToBean {
/** /**
* 在类头上设置csv格式的header * 在类头上设置csv格式的header
* @return * csv文件和java bean的映射
*/ */
String header(); String header();
/**
* csv文件的分割符号
*/
char delimiter() default ',';
/**
* CSV文件是否有header
*/
boolean hasHeader() default false;
} }

View File

@@ -0,0 +1,21 @@
package com.yexuejc.base.constant;
/**
* @author yexuejc
* @class-name DateConsts
* @description
* @date 2023/05/17 13:45
*/
public class DateConsts {
public static final String BAR = "-";
public static final CharSequence DATE_KEY_AM = "AM";
public static final CharSequence DATE_KEY_PM = "PM";
public static final String DATE_TIMESTAMP_LINUX = "M/dd/yy, h:mm a";
public static final CharSequence SLASH = "/";
public static final CharSequence COLON = ":";
public static final String DATE_YYYY_MM_DD_SLASH = "yyyy/MM/dd";
public static final CharSequence DATE_KEY_T = "T";
public static final String DATE_KEY_Z = "Z";
public static final String DATE_TIMESTAMP = "yyyy/MM/dd H:m:s";
public static final String DATE_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
}

View File

@@ -0,0 +1,44 @@
package com.yexuejc.base.converter;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.yexuejc.base.constant.DateConsts;
import com.yexuejc.base.util.StrUtil;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
/**
* json转LocalDate
*
* @author yexuejc
* @date 2022/10/08
*/
public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
String timeString = jsonParser.getValueAsString();
if (StrUtil.isEmpty(timeString)) {
return null;
}
if (timeString.contains(DateConsts.BAR)) {
return LocalDate.parse(timeString, DateTimeFormatter.ISO_DATE);
} else if (timeString.contains(DateConsts.DATE_KEY_AM)
|| timeString.contains(DateConsts.DATE_KEY_PM)) {
return LocalDate.parse(timeString,
DateTimeFormatter.ofPattern(DateConsts.DATE_TIMESTAMP_LINUX, Locale.ENGLISH));
} else if (timeString.contains(DateConsts.SLASH) && timeString.contains(DateConsts.COLON)) {
return LocalDate.parse(timeString.substring(0, 10),
DateTimeFormatter.ofPattern(DateConsts.DATE_YYYY_MM_DD_SLASH));
} else if (timeString.contains(DateConsts.SLASH)) {
return LocalDate.parse(timeString, DateTimeFormatter.ofPattern(DateConsts.DATE_YYYY_MM_DD_SLASH));
} else {
return LocalDate.parse(timeString, DateTimeFormatter.BASIC_ISO_DATE);
}
}
}

View File

@@ -0,0 +1,23 @@
package com.yexuejc.base.converter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
* localDate转json
*
* @author yexuejc
* @date 2022/10/08
*/
public class LocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString(localDate.format(DateTimeFormatter.ISO_DATE));
}
}

View File

@@ -0,0 +1,44 @@
package com.yexuejc.base.converter;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.yexuejc.base.constant.DateConsts;
import com.yexuejc.base.util.StrUtil;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
/**
* json转LocalDateTime
*
* @author yexuejc
* @date 2022/10/08
*/
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
String timeString = jsonParser.getValueAsString();
if (StrUtil.isEmpty(timeString)) {
return null;
}
if (timeString.contains(DateConsts.DATE_KEY_T)) {
return LocalDateTime.parse(timeString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} else if (timeString.contains(DateConsts.DATE_KEY_AM)
|| timeString.contains(DateConsts.DATE_KEY_PM)) {
return LocalDateTime.parse(timeString,
DateTimeFormatter.ofPattern(DateConsts.DATE_TIMESTAMP_LINUX, Locale.ENGLISH));
} else if (timeString.endsWith(DateConsts.DATE_KEY_Z)) {
return LocalDateTime.parse(timeString, DateTimeFormatter.ISO_INSTANT);
} else if (timeString.contains(DateConsts.SLASH)) {
return LocalDateTime.parse(timeString, DateTimeFormatter.ofPattern(DateConsts.DATE_TIMESTAMP));
} else {
return LocalDateTime.parse(timeString,
DateTimeFormatter.ofPattern(DateConsts.DATE_YYYY_MM_DD_HH_MM_SS));
}
}
}

View File

@@ -0,0 +1,23 @@
package com.yexuejc.base.converter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* LocalDateTime转json
*
* @author yexuejc
* @date 2022/10/08
*/
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
}

View File

@@ -0,0 +1,38 @@
package com.yexuejc.base.converter;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
/**
* <pre>
* json中的“”转String对象时值为null
* 例子:{str:""} ->
* JsonBean{
* public String str;
* }
* str的值为null [不使用{@link StringDeserializer},str的值为“”]
* </pre>
*
* <pre>
* 使用方式:
* jsonMapper.registerModule(new SimpleModule().addDeserializer(String.class, new StringDeserializer()));
* </pre>
*
* @author yexuejc
* @date 2022/10/08
*/
public class StringDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
String timeString = jsonParser.getValueAsString();
if ("".equals(timeString)) {
return null;
}
return timeString;
}
}

View File

@@ -0,0 +1,46 @@
package com.yexuejc.base.converter;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.yexuejc.base.constant.DateConsts;
import com.yexuejc.base.util.StrUtil;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
/**
* json转LocalDateTime
*
* @author yexuejc
* @date 2022/10/08
*/
public class TimestampDeserializer extends JsonDeserializer<Timestamp> {
@Override
public Timestamp deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
String timeString = jsonParser.getValueAsString();
if (StrUtil.isEmpty(timeString)) {
return null;
}
if (timeString.contains(DateConsts.DATE_KEY_T)) {
return Timestamp.valueOf(LocalDateTime.parse(timeString, DateTimeFormatter.ISO_LOCAL_DATE_TIME));
} else if (timeString.contains(DateConsts.DATE_KEY_AM)
|| timeString.contains(DateConsts.DATE_KEY_PM)) {
return Timestamp.valueOf(LocalDateTime.parse(timeString,
DateTimeFormatter.ofPattern(DateConsts.DATE_TIMESTAMP_LINUX, Locale.ENGLISH)));
} else if (timeString.endsWith(DateConsts.DATE_KEY_Z)) {
return Timestamp.valueOf(LocalDateTime.parse(timeString, DateTimeFormatter.ISO_INSTANT));
} else if (timeString.contains(DateConsts.SLASH)) {
return Timestamp.valueOf(
LocalDateTime.parse(timeString, DateTimeFormatter.ofPattern(DateConsts.DATE_TIMESTAMP)));
} else {
return Timestamp.valueOf(LocalDateTime.parse(timeString,
DateTimeFormatter.ofPattern(DateConsts.DATE_YYYY_MM_DD_HH_MM_SS)));
}
}
}

View File

@@ -0,0 +1,25 @@
package com.yexuejc.base.converter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.yexuejc.base.constant.DateConsts;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
/**
* Timestamp转json
*
* @author yexuejc
* @date 2022/10/08
*/
public class TimestampSerializer extends JsonSerializer<Timestamp> {
@Override
public void serialize(Timestamp timestamp, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
SimpleDateFormat df = new SimpleDateFormat(DateConsts.DATE_TIMESTAMP);
jsonGenerator.writeString(df.format(timestamp));
}
}

View File

@@ -0,0 +1,173 @@
package com.yexuejc.base.encrypt;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* AES加解密
*
* @author maxf
* @class-name AES
* @description
* @date 2022/11/11 15:36
*/
public class AES {
public static AES builder() {
return Instace.aes;
}
private static class Instace {
private static AES aes = new AES();
}
public static final String AES_ALGORITHM = "AES";
/**
* 加密模式
*/
public static enum ALGORITHM {
//算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
//AES/CBC/NoPadding 16 不支持
AES_CBC_NoPadding("AES/CBC/NoPadding"),
//AES/CBC/PKCS5Padding 32 16
AES_CBC_PKCS5Padding("AES/CBC/PKCS5Padding"),
//AES/CBC/ISO10126Padding 32 16
AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"),
//AES/CFB/NoPadding 16 原始数据长度
AES_CFB_NoPadding("AES/CFB/NoPadding"),
//AES/CFB/PKCS5Padding 32 16
AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"),
//AES/CFB/ISO10126Padding 32 16
AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"),
//AES/ECB/NoPadding 16 不支持
AES_ECB_NoPadding("AES/ECB/NoPadding"),
//AES/ECB/PKCS5Padding 32 16
AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"),
//AES/ECB/ISO10126Padding 32 16
AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"),
//AES/OFB/NoPadding 16 原始数据长度
AES_OFB_NoPadding("AES/OFB/NoPadding"),
//AES/OFB/PKCS5Padding 32 16
AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"),
//AES/OFB/ISO10126Padding 32 16
AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"),
//AES/PCBC/NoPadding 16 不支持
AES_PCBC_NoPadding("AES/PCBC/NoPadding"),
//AES/PCBC/PKCS5Padding 32 16
AES_PCBC_PKCS5Padding("AES/PCBC/PKCS5Padding"),
//AES/PCBC/ISO10126Padding 32 16
AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding");
public String name;
ALGORITHM(String name) {
this.name = name;
}
}
private ALGORITHM algorithm = ALGORITHM.AES_CBC_NoPadding;
private String key = "hj7x89H$yuBI0456";
private String iv = "NIfb&95GUY86Gfgh";
private Charset charset = StandardCharsets.UTF_8;
/**
* 加密
*
* @param data 明文
* @return 密文
* @Description AES算法加密明文
*/
public String encrypt(String data) throws Exception {
try {
Cipher cipher = Cipher.getInstance(algorithm.name);
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes(charset);
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset));
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 解密
*
* @param data 密文
* @return 明文
* @Description AES算法解密密文
*/
public String decrypt(String data) throws Exception {
try {
byte[] encrypted = Base64.getDecoder().decode(data);
Cipher cipher = Cipher.getInstance(algorithm.name);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset));
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted);
return new String(original, charset).trim();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//
// public static void main(String[] args) throws Exception {
// String str = " 奥萨蒂 asd8阿斯顿8asd ";
// AES.builder().setAlgorithm(ALGORITHM.AES_CBC_ISO10126Padding);
// AES.builder().setKey("DEsx89H$yuBI0456");
// String encrypt = AES.builder().encrypt(str);
// System.out.println(encrypt);
// String decrypt = AES.builder().decrypt(encrypt);
// System.out.println(">>>" + decrypt + "<<<");
// }
public ALGORITHM getAlgorithm() {
return algorithm;
}
public AES setAlgorithm(ALGORITHM algorithm) {
this.algorithm = algorithm;
return this;
}
public String getKey() {
return key;
}
public AES setKey(String key) {
this.key = key;
return this;
}
public String getIv() {
return iv;
}
public AES setIv(String iv) {
this.iv = iv;
return this;
}
public Charset getCharset() {
return charset;
}
public AES setCharset(Charset charset) {
this.charset = charset;
return this;
}
}

View File

@@ -0,0 +1,90 @@
package com.yexuejc.base.pojo;
import java.util.List;
/**
* 压缩文件的参数设定
*
* @author maxf
* @class-name CreateZipFileBean
* @description 压缩文件参考 {@link com.yexuejc.base.util.ZipUtil}
* @date 2022/11/11 10:30
*/
public class CreateZipFileBean {
/**
* 压缩的源文件列表,为空表示压缩整个目录
*/
private List<String> sourceFileName;
/**
* 当压缩文件夹时,需要排除的文件。压缩文件时(该参数无效)
*/
private List<String> excludeFileName;
/**
* 压缩源文件的目录
*/
private String sourcePath;
/**
* 生成压缩文件路径(全路径+压缩文件名)
*/
private String zipFile;
/**
* 加密密码
*/
private String encryptPwd;
private String writeCharsetName = "UTF-8";
public List<String> getSourceFileName() {
return sourceFileName;
}
public String getEncryptPwd() {
return encryptPwd;
}
public CreateZipFileBean setEncryptPwd(String encryptPwd) {
this.encryptPwd = encryptPwd;
return this;
}
public CreateZipFileBean setSourceFileName(List<String> sourceFileName) {
this.sourceFileName = sourceFileName;
return this;
}
public String getSourcePath() {
return sourcePath;
}
public CreateZipFileBean setSourcePath(String sourcePath) {
this.sourcePath = sourcePath;
return this;
}
public String getZipFile() {
return zipFile;
}
public CreateZipFileBean setZipFile(String zipFile) {
this.zipFile = zipFile;
return this;
}
public String getWriteCharsetName() {
return writeCharsetName;
}
public CreateZipFileBean setWriteCharsetName(String writeCharsetName) {
this.writeCharsetName = writeCharsetName;
return this;
}
public List<String> getExcludeFileName() {
return excludeFileName;
}
public CreateZipFileBean setExcludeFileName(List<String> excludeFileName) {
this.excludeFileName = excludeFileName;
return this;
}
}

View File

@@ -0,0 +1,61 @@
package com.yexuejc.base.pojo;
/**
* {@link com.yexuejc.base.annotation.CsvToBean}
* 读取csv文件用
* @author yexuejc
* @class-name CsvToBean
* @description
* @date 2023/6/6 18:15
*/
public class CsvToBean {
/**
* 在类头上设置csv格式的header
* csv文件和java bean的映射
*/
private String header;
/**
* csv文件的分割符号
*/
private char delimiter;
/**
* CSV文件是否有header
*/
private boolean hasHeader;
public CsvToBean(String header, char delimiter, boolean hasHeader) {
this.header = header;
this.delimiter = delimiter;
this.hasHeader = hasHeader;
}
public String getHeader() {
return header;
}
public CsvToBean setHeader(String header) {
this.header = header;
return this;
}
public char getDelimiter() {
return delimiter;
}
public CsvToBean setDelimiter(char delimiter) {
this.delimiter = delimiter;
return this;
}
public boolean isHasHeader() {
return hasHeader;
}
public CsvToBean setHasHeader(boolean hasHeader) {
this.hasHeader = hasHeader;
return this;
}
}

View File

@@ -4,7 +4,6 @@ import com.yexuejc.base.util.JsonUtil;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
/** /**
* 分页 VO * 分页 VO
* *

View File

@@ -1,6 +1,11 @@
package com.yexuejc.base.pojo; package com.yexuejc.base.pojo;
import org.checkerframework.checker.units.qual.C;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.function.Function;
/** /**
* @author maxf * @author maxf
@@ -34,7 +39,18 @@ public class ReadFileBean<T> {
* 文件的length * 文件的length
*/ */
private long fileLength; private long fileLength;
/**
* csv文件存在header
*/
private String header;
private Charset readCharset = StandardCharsets.UTF_8;
public Function<String, String> lineScavenger = t -> t;
public ReadFileBean() {
this.readRowNum = Integer.MAX_VALUE;
this.startRowNum = 1;
this.endRowNum = 0;
}
public ReadFileBean(int readRow) { public ReadFileBean(int readRow) {
this.readRowNum = readRow; this.readRowNum = readRow;
@@ -42,6 +58,24 @@ public class ReadFileBean<T> {
this.endRowNum = 0; this.endRowNum = 0;
} }
public Charset getReadCharset() {
return readCharset;
}
public ReadFileBean<T> setReadCharset(Charset readCharset) {
this.readCharset = readCharset;
return this;
}
public String getHeader() {
return header;
}
public ReadFileBean<T> setHeader(String header) {
this.header = header;
return this;
}
public int getReadRowNum() { public int getReadRowNum() {
return readRowNum; return readRowNum;
} }
@@ -82,4 +116,12 @@ public class ReadFileBean<T> {
this.fileLength = fileLength; this.fileLength = fileLength;
return this; return this;
} }
public String lineScavenge(String lineData) {
return this.lineScavenger.apply(lineData);
}
public boolean hasNext() {
return this.fileLength > this.pointer;
}
} }

View File

@@ -1,11 +1,13 @@
package com.yexuejc.base.util; package com.yexuejc.base.util;
import java.text.ParseException;
import java.time.*; import java.time.*;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalAdjusters;
import java.util.Date; import java.util.Date;
/** /**
* 新版时间日期出来 工具 * 新版时间日期出来 工具
* *
@@ -258,9 +260,19 @@ public class DateTimeUtil {
* @return * @return
*/ */
public static LocalDateTime parseLocalDateTime13(long timestamp) { public static LocalDateTime parseLocalDateTime13(long timestamp) {
return parseLocalDateTime13(timestamp, ZoneId.systemDefault());
}
/**
* Long 转 LocalDateTime
*
* @param timestamp 13位毫秒
* @param zoneId 时区
* @return
*/
public static LocalDateTime parseLocalDateTime13(long timestamp, ZoneId zoneId) {
Instant instant = Instant.ofEpochMilli(timestamp); Instant instant = Instant.ofEpochMilli(timestamp);
ZoneId zone = ZoneId.systemDefault(); return LocalDateTime.ofInstant(instant, zoneId);
return LocalDateTime.ofInstant(instant, zone);
} }
/** /**
@@ -270,9 +282,32 @@ public class DateTimeUtil {
* @return * @return
*/ */
public static LocalDateTime parseLocalDateTime10(long timestamp) { public static LocalDateTime parseLocalDateTime10(long timestamp) {
return parseLocalDateTime10(timestamp, ZoneId.systemDefault());
}
/**
* Long 转 LocalDateTime
*
* @param timestamp 10位
* @param zoneId 时区
* @return
*/
public static LocalDateTime parseLocalDateTime10(long timestamp, ZoneId zoneId) {
Instant instant = Instant.ofEpochMilli(timestamp * 1000); Instant instant = Instant.ofEpochMilli(timestamp * 1000);
ZoneId zone = ZoneId.systemDefault(); return LocalDateTime.ofInstant(instant, zoneId);
return LocalDateTime.ofInstant(instant, zone); }
/**
* UTC格林威治标准时间
*
* @param timestamp 13位毫秒/ 10位
* @return
*/
public static LocalDateTime parserUTC(Long timestamp) {
if (String.valueOf(timestamp).length() == 10) {
timestamp = timestamp * 1000;
}
return parseLocalDateTime13(timestamp, ZoneId.of("UTC"));
} }
/** /**
@@ -299,6 +334,7 @@ public class DateTimeUtil {
return instant.toEpochMilli(); return instant.toEpochMilli();
} }
/** /**
* 格式化时间 <br/> * 格式化时间 <br/>
* 格式 yyyy-MM-dd HH:mm:ss * 格式 yyyy-MM-dd HH:mm:ss
@@ -351,23 +387,69 @@ public class DateTimeUtil {
return df.format(dateTime); return df.format(dateTime);
} }
/**
* 获取UTC格林威治标准时间
*
* @param date
* @return
*/
public static LocalDateTime convertUTC(LocalDateTime date) {
return convertTimezone(date, null, "UTC");
}
/** public static void main(String[] args) { /**
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); * 时区转换(当前时区)
System.out.println(df.format(zonedDateTime2Date(ZonedDateTime.now()))); *
System.out.println(df2.format(date2ZonedDateTime(new Date()))); * @param date 时间
* @param zoneId 转换时区
* @return
*/
public static LocalDateTime convertTimezone(LocalDateTime date, String zoneId) {
return convertTimezone(date, null, zoneId);
}
System.out.println(getWeek4First());
System.out.println(format(getWeek4First(LocalDate.parse("2018-02-10")).atTime(LocalTime.MIN)));
System.out.println(format(getWeek4Last(LocalDate.parse("2018-02-10")).atTime(LocalTime.MAX)));
System.out.println(format(getMonth4First().atTime(LocalTime.MIN))); /**
System.out.println(format(getMonth4Last().atTime(LocalTime.MAX))); * 时区转换
*
* @param date 时间
* @param currentZoneId 当前时间的时区
* @param targetZoneId 转换时区
* @return
*/
public static LocalDateTime convertTimezone(LocalDateTime date, String currentZoneId, String targetZoneId) {
ZoneId currentZone;
if (currentZoneId == null) {
currentZone = ZoneId.systemDefault();
} else {
currentZone = ZoneId.of(currentZoneId);
}
ZoneId targetZone = ZoneId.of(targetZoneId);
return date.atZone(currentZone).withZoneSameInstant(targetZone).toLocalDateTime();
}
System.out.println(format(getYear4First().atTime(LocalTime.MIN)));
System.out.println(format(getYear4Last().atTime(LocalTime.MAX)));
}*/ /*public static void main(String[] args) throws ParseException {
System.out.println(parserUTC(1684140338161L));
System.out.println(convertUTC(LocalDateTime.now()));
Date date = DateUtil.str2dateTime("2023-05-15 08:28:05.327");
LocalDateTime localDateTime = parseLocalDateTime(date);
System.out.println(date);
System.out.println(localDateTime);
LocalDateTime utc = convertTimezone(localDateTime, "UTC", "Asia/Shanghai");
System.out.println(utc);
System.out.println(getWeek4First());
System.out.println(format(getWeek4First(LocalDate.parse("2018-02-10")).atTime(LocalTime.MIN)));
System.out.println(format(getWeek4Last(LocalDate.parse("2018-02-10")).atTime(LocalTime.MAX)));
System.out.println(format(getMonth4First().atTime(LocalTime.MIN)));
System.out.println(format(getMonth4Last().atTime(LocalTime.MAX)));
System.out.println(format(getYear4First().atTime(LocalTime.MIN)));
System.out.println(format(getYear4Last().atTime(LocalTime.MAX)));
}*/
} }

View File

@@ -3,6 +3,7 @@ package com.yexuejc.base.util;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@@ -191,4 +192,44 @@ public class DateUtil {
return calendar.getTime(); return calendar.getTime();
} }
/**
* 获取UTC格林威治标准时间
*
* @param date
* @return
*/
public static Date convertUTC(Date date) {
return convertTimezone(date, null, "UTC");
}
/**
* 时区转换(当前时区)
*
* @param date 时间
* @param zoneId 转换时区
* @return
*/
public static Date convertTimezone(Date date, String zoneId) {
return convertTimezone(date, null, zoneId);
}
/**
* 时区转换
*
* @param date 时间
* @param currentZoneId 当前时间的时区
* @param targetZoneId 转换时区
* @return
*/
public static Date convertTimezone(Date date, String currentZoneId, String targetZoneId) {
ZoneId currentZone;
if (currentZoneId == null) {
currentZone = ZoneId.systemDefault();
} else {
currentZone = ZoneId.of(currentZoneId);
}
ZoneId targetZone = ZoneId.of(targetZoneId);
return Date.from(date.toInstant().atZone(currentZone).withZoneSameInstant(targetZone).toInstant());
}
} }

View File

@@ -5,17 +5,31 @@ import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema; import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams; import com.google.common.io.CharStreams;
import com.yexuejc.base.annotation.CsvHeader; import com.yexuejc.base.annotation.CsvToBean;
import com.yexuejc.base.pojo.ReadFileBean; import com.yexuejc.base.pojo.ReadFileBean;
import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Assert;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import java.io.*; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.io.StringWriter;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.MappedByteBuffer; import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -37,7 +51,7 @@ import java.util.zip.CRC32;
public class FileUtil { public class FileUtil {
static Logger logger = Logger.getLogger(FileUtil.class.getName()); static Logger logger = Logger.getLogger(FileUtil.class.getName());
private FileUtil() { public FileUtil() {
} }
private static final String TYPE_TAR_GZ = ".tar.gz"; private static final String TYPE_TAR_GZ = ".tar.gz";
@@ -159,7 +173,6 @@ public class FileUtil {
return null; return null;
} }
/*** /***
* 计算SHA1码 * 计算SHA1码
* *
@@ -303,41 +316,24 @@ public class FileUtil {
* @return * @return
*/ */
public static String base64ToStr(File file) { public static String base64ToStr(File file) {
return new String(base64(file));
}
/**
* 获取文件base64
*
* @param file
* @return
*/
public static byte[] base64(File file) {
FileInputStream fileInputStream = null;
byte[] data = null;
// 读取图片字节数组
try { try {
fileInputStream = new FileInputStream(file); byte[] bytes = Files.readAllBytes(Path.of(file.getPath()));
data = new byte[fileInputStream.available()]; return Base64.getEncoder().encodeToString(bytes);
fileInputStream.read(data);
fileInputStream.close();
} catch (IOException e) { } catch (IOException e) {
logger.severe("The operation file is an IO exception."); logger.severe("The operation file is an IO exception.");
e.printStackTrace();
} }
// 对字节数组Base64编码 return null;
return Base64.getEncoder().encode(data);
} }
/** /**
* base64转文件 * base64转文件
* <p> * <p>
* <i> * <i>
* 文件转base64请使用 {@link FileUtil#base64(File)} * 文件转base64请使用 {@link FileUtil#base64ToStr(File)}
* </i> * </i>
* *
* @param decode {@link FileUtil#base64ToStr(File)} 的结果 * @param decode {@link FileUtil#base64ToStr(File)} 的结果
* @param fileName 文件名称(包含路径) * @param fileName 保存文件名称(包含路径)
* @return 返回保存地址 * @return 返回保存地址
*/ */
public static String base64ToFile(String decode, String fileName) { public static String base64ToFile(String decode, String fileName) {
@@ -348,7 +344,7 @@ public class FileUtil {
* base64转文件 * base64转文件
* <p> * <p>
* <i> * <i>
* 文件转base64请使用 {@link FileUtil#base64(File)} * 文件转base64请使用 {@link FileUtil#base64ToStr(File)}
* </i> * </i>
* *
* @param decode baseByte * @param decode baseByte
@@ -494,24 +490,48 @@ public class FileUtil {
* @param <T> 读取结果类型bean * @param <T> 读取结果类型bean
* @return * @return
*/ */
public <T> ReadFileBean<T> readBigFile(String path, ReadFileBean<T> readFileBean, Class<T> readCls) { public <T> ReadFileBean<T> readBigFile(String path, ReadFileBean<T> readFileBean, Class<T> readCls) throws FileNotFoundException {
File file = new File(path); File file = new File(path);
judeFileExists(file); if (!file.exists() || file.isDirectory()) {
try { throw new FileNotFoundException("file:" + path + " is not found.");
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r"); }
try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
if (readFileBean.getPointer() < 0) {
readFileBean.setPointer(0);
}
randomAccessFile.seek(readFileBean.getPointer()); randomAccessFile.seek(readFileBean.getPointer());
readFileBean.setFileLength(randomAccessFile.length()); readFileBean.setFileLength(randomAccessFile.length());
List<String> datas = new ArrayList<>(); List<String> datas = new ArrayList<>();
for (int i = 0; i < readFileBean.getReadRowNum(); i++) { int row = 1;
String s = randomAccessFile.readLine(); String line;
datas.add(charsetDecode(s, StandardCharsets.UTF_8)); while ((line = randomAccessFile.readLine()) != null && row <= readFileBean.getReadRowNum()) {
row++;
readFileBean.setPointer(randomAccessFile.getFilePointer()); readFileBean.setPointer(randomAccessFile.getFilePointer());
datas.add(readFileBean.lineScavenge(charsetDecode(line, readFileBean.getReadCharset()))); }
if (StrUtil.isEmpty(datas)) {
//无数据
return readFileBean.setDatas(List.of());
} }
randomAccessFile.close();
if (path.contains(TYPE_CSV)) { if (path.contains(TYPE_CSV)) {
//csv文件处理 //csv文件处理
datas.add(0, getCsvHeader(readCls)); com.yexuejc.base.pojo.CsvToBean csvToBean = getCsvToBean(readCls);
List<T> dataList = readCsv(String.join("\n", datas), readCls, ','); readFileBean.setHeader(csvToBean.getHeader());
if (csvToBean.isHasHeader()) {
//文件存在header,设置header优先,没设置使用文件的
if (StrUtil.isNotEmpty(csvToBean.getHeader())) {
//替换header
datas.remove(0);
datas.add(0, csvToBean.getHeader());
} else {
readFileBean.setHeader(datas.get(0));
}
} else {
//文件不存在header使用设置的
datas.add(0, csvToBean.getHeader());
}
List<T> dataList = readCsv(String.join("\n", datas), readCls, csvToBean.getDelimiter());
readFileBean.setDatas(dataList); readFileBean.setDatas(dataList);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
@@ -523,18 +543,18 @@ public class FileUtil {
} }
/** /**
* 获取csv的header,使用注解{@link CsvHeader} * 获取csv的header,使用注解{@link CsvToBean}
* *
* @param cls * @param cls
* @param <T> * @param <T>
* @return * @return
*/ */
public static <T> String getCsvHeader(Class<T> cls) { public static <T> com.yexuejc.base.pojo.CsvToBean getCsvToBean(Class<T> cls) {
CsvHeader annotation = cls.getAnnotation(CsvHeader.class); CsvToBean annotation = cls.getAnnotation(CsvToBean.class);
Assert.notNull(annotation, cls.toString() + "类上需要添加注解@CsvHeader并指定header。"); Assert.notNull(annotation, cls.toString() + "类上需要添加注解@CsvToBean并指定header。");
String header = annotation.header(); com.yexuejc.base.pojo.CsvToBean csvToBean = new com.yexuejc.base.pojo.CsvToBean(
Assert.notNull(header, cls.toString() + "类上需要添加注解@CsvHeader并指定header。"); annotation.header(), annotation.delimiter(), annotation.hasHeader());
return header; return csvToBean;
} }
/** /**
@@ -553,7 +573,6 @@ public class FileUtil {
return new String(result, charset); return new String(result, charset);
} }
/** /**
* 提供读取IO流方法合集 * 提供读取IO流方法合集
* <p>读取速度快慢顺序:</p> * <p>读取速度快慢顺序:</p>
@@ -614,7 +633,6 @@ public class FileUtil {
.collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator)); .collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator));
} }
/** /**
* 读取IO流内容Scanner A方式 * 读取IO流内容Scanner A方式
* *
@@ -637,7 +655,6 @@ public class FileUtil {
return new Scanner(inputStream).useDelimiter("\\Z").next(); return new Scanner(inputStream).useDelimiter("\\Z").next();
} }
/** /**
* 读取IO流内容StringBuilder方式 * 读取IO流内容StringBuilder方式
* *
@@ -741,6 +758,7 @@ public class FileUtil {
} }
} }
/*public static void main(String[] args) { /*public static void main(String[] args) {
long size = FileUtil.size(new File("E:\\OS\\deepin-15.6-amd64\\DeepinCloudPrintServerInstaller_1.0.0.1.exe")); long size = FileUtil.size(new File("E:\\OS\\deepin-15.6-amd64\\DeepinCloudPrintServerInstaller_1.0.0.1.exe"));
System.out.println(size); System.out.println(size);

View File

@@ -1,16 +1,34 @@
package com.yexuejc.base.util; package com.yexuejc.base.util;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.type.MapType; import com.fasterxml.jackson.databind.type.MapType;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.yexuejc.base.converter.LocalDateDeserializer;
import com.yexuejc.base.converter.LocalDateSerializer;
import com.yexuejc.base.converter.LocalDateTimeDeserializer;
import com.yexuejc.base.converter.LocalDateTimeSerializer;
import com.yexuejc.base.converter.TimestampDeserializer;
import com.yexuejc.base.converter.TimestampSerializer;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -32,32 +50,102 @@ public class JsonUtil {
/** /**
* 作为单例全局使用 * 作为单例全局使用
*/ */
private static ObjectMapper objectMapper = new ObjectMapper(); private static JsonMapper jsonMapper = new JsonMapper();
static { static {
JsonUtil.initDefaultObjectMapper(JsonUtil.objectMapper); JsonUtil.setJavaTimeModule(JsonUtil.jsonMapper);
JsonUtil.initDefaultObjectMapper(JsonUtil.jsonMapper);
}
/**
* 对时间的支持
*
* @param jsonMapper
*/
private static void setJavaTimeModule(ObjectMapper jsonMapper) {
//设置一下时区,可以和程序同步避免时区问题
jsonMapper.setTimeZone(TimeZone.getDefault());
jsonMapper.setDateFormat(DateUtil.DATE_TIME_FORMAT);
JavaTimeModule javaTime = new JavaTimeModule();
//java time 特殊处理
javaTime.addSerializer(LocalDate.class, new LocalDateSerializer());
javaTime.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
javaTime.addSerializer(Timestamp.class, new TimestampSerializer());
javaTime.addDeserializer(LocalDate.class, new LocalDateDeserializer());
javaTime.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
javaTime.addDeserializer(Timestamp.class, new TimestampDeserializer());
jsonMapper.registerModule(javaTime);
} }
/** /**
* 初始化ObjectMapper为默认属性 * 初始化ObjectMapper为默认属性
* <pre>
* 1.序列化值为空时NON_NULL舍去字段
* 2.JsonParser.Feature.ALLOW_SINGLE_QUOTES解析JSON时允许使用单引号')作为字符串的引号(true)
* 例子:{'localDateTime':'2023-05-29T15:32:03.9770447'}
* 3.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES解析JSON时允许不使用引号作为字符串的引号(true)
* 例子:{age:12};适用于基本数据类型
* 4.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIESjson对应java Bean,数据字段对不齐的情况下不报错(false)
* 5.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS(false):用于指定是否将日期类型序列化为时间戳格式。如果启用该特性则日期类型将被序列化为Unix时间戳即从1970年1月1日00:00:00 GMT开始的毫秒数。如果禁用该特性则日期类型将以其原始格式进行序列化。
* 例子(false)"timestamp": "2020-07-08T02:02:55.000+00:00"
* 例子(true)"timestamp": 1594236175000
* </pre>
* *
* @param objectMapper * @param jsonMapper
*/ */
private static void initDefaultObjectMapper(ObjectMapper objectMapper) { private static void initDefaultObjectMapper(ObjectMapper jsonMapper) {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); //值为空时NON_NULL舍去字段ALWAYS:保留字段
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); jsonMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); jsonMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); jsonMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//设置一下时区,可以和程序同步避免时区问题 jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setTimeZone(TimeZone.getDefault()); }
objectMapper.setDateFormat(DateUtil.DATE_TIME_FORMAT);
/**
* 初始化ObjectMapper的默认属性
* <pre>
* 1.序列化值为空时ALWAYS:保留字段,值为“”
* 2.JsonParser.Feature.ALLOW_SINGLE_QUOTES解析JSON时允许使用单引号')作为字符串的引号(true)
* 例子:{'localDateTime':'2023-05-29T15:32:03.9770447'}
* 3.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES解析JSON时允许不使用引号作为字符串的引号(true)
* 例子:{age:12};适用于基本数据类型
* 4.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIESjson对应java Bean,数据字段对不齐的情况下不报错(false)
* 5.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS(false):用于指定是否将日期类型序列化为时间戳格式。如果启用该特性则日期类型将被序列化为Unix时间戳即从1970年1月1日00:00:00 GMT开始的毫秒数。如果禁用该特性则日期类型将以其原始格式进行序列化。
* 例子(false)"timestamp": "2020-07-08T02:02:55.000+00:00"
* 例子(true)"timestamp": 1594236175000
* 6.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT反序列化值为空时映射到java Bean 非字符串类型值为null
* </pre>
*
* @return
*/
public static ObjectMapper acceptEmptyStringAsNullObject() {
JsonMapper jsonMapper = new JsonMapper();
setJavaTimeModule(jsonMapper);
//值为空时ALWAYS:保留字段默认字符串值为“”对象值为null
jsonMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
jsonMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
jsonMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
jsonMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
//值为空时,序列化所有值为“”
jsonMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<>() {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString("");
}
});
return jsonMapper;
} }
//TODO 待优化 //TODO 待优化
public static void initSnakeCase() { public static void initSnakeCase() {
//驼峰下划线互转 //驼峰下划线互转
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); jsonMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
} }
/** /**
@@ -86,8 +174,8 @@ public class JsonUtil {
* *
* @return * @return
*/ */
public static ObjectMapper getObjectMapper() { public static ObjectMapper getJsonMapper() {
return objectMapper; return jsonMapper;
} }
/** /**
@@ -101,13 +189,13 @@ public class JsonUtil {
T pojo = null; T pojo = null;
try { try {
pojo = objectMapper.readValue(json, cls); pojo = jsonMapper.readValue(json, cls);
} catch (JsonParseException e) { } catch (JsonParseException e) {
log.warning("json to Object JsonParseException.\n" + e.getMessage()); log.warning("json to Object JsonParseException.\n" + e);
} catch (JsonMappingException e) { } catch (JsonMappingException e) {
log.warning("json to Object JsonMappingException.\n" + e.getMessage()); log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
} catch (IOException e) { } catch (IOException e) {
log.warning("json to Object IOException.\n" + e.getMessage()); log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
} }
return pojo; return pojo;
@@ -123,15 +211,15 @@ public class JsonUtil {
public static <T> T json2Obj(String json, Class<T> cls) { public static <T> T json2Obj(String json, Class<T> cls) {
T pojo = null; T pojo = null;
try { try {
pojo = objectMapper.readValue(json, cls); pojo = jsonMapper.readValue(json, cls);
} catch (JsonParseException e) { } catch (JsonParseException e) {
log.warning("json to Object JsonParseException.\n" + e.getMessage()); log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
} catch (JsonMappingException e) { } catch (JsonMappingException e) {
log.warning("json to Object JsonMappingException.\n" + e.getMessage()); log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
} catch (IOException e) { } catch (IOException e) {
log.warning("json to Object IOException.\n" + e.getMessage()); log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.warning("json to Object Exception.\n" + StrUtil.printStackTrace(e));
} }
return pojo; return pojo;
@@ -147,15 +235,15 @@ public class JsonUtil {
*/ */
public static <T> T json2Obj(String json, Class<T> parametrized, Class<?>... parameterClasses) { public static <T> T json2Obj(String json, Class<T> parametrized, Class<?>... parameterClasses) {
T pojo = null; T pojo = null;
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(parametrized, parameterClasses); JavaType javaType = jsonMapper.getTypeFactory().constructParametricType(parametrized, parameterClasses);
try { try {
pojo = objectMapper.readValue(json, javaType); pojo = jsonMapper.readValue(json, javaType);
} catch (JsonParseException e) { } catch (JsonParseException e) {
log.warning("json to Object JsonParseException.\n" + e.getMessage()); log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
} catch (JsonMappingException e) { } catch (JsonMappingException e) {
log.warning("json to Object JsonMappingException.\n" + e.getMessage()); log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
} catch (IOException e) { } catch (IOException e) {
log.warning("json to Object IOException.\n" + e.getMessage()); log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
} }
return pojo; return pojo;
} }
@@ -172,15 +260,15 @@ public class JsonUtil {
*/ */
public static <T> T json2Obj(String json, Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass) { public static <T> T json2Obj(String json, Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass) {
T pojo = null; T pojo = null;
MapType mapType = objectMapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass); MapType mapType = jsonMapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass);
try { try {
pojo = objectMapper.readValue(json, mapType); pojo = jsonMapper.readValue(json, mapType);
} catch (JsonParseException e) { } catch (JsonParseException e) {
log.warning("json to Object JsonParseException.\n" + e.getMessage()); log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
} catch (JsonMappingException e) { } catch (JsonMappingException e) {
log.warning("json to Object JsonMappingException.\n" + e.getMessage()); log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
} catch (IOException e) { } catch (IOException e) {
log.warning("json to Object IOException.\n" + e.getMessage()); log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
} }
return pojo; return pojo;
} }
@@ -195,9 +283,9 @@ public class JsonUtil {
*/ */
public static <T extends Object> T json2Obj(String json, TypeReference<T> javaType) { public static <T extends Object> T json2Obj(String json, TypeReference<T> javaType) {
try { try {
return objectMapper.readValue(json, javaType); return jsonMapper.readValue(json, javaType);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.warning("json to Object JsonParseException.\n" + e.getMessage()); log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
} }
return null; return null;
} }
@@ -212,16 +300,16 @@ public class JsonUtil {
*/ */
public static <T> T json2Obj(InputStream json, Class<T> parametrized, Class<?>... parameterClasses) { public static <T> T json2Obj(InputStream json, Class<T> parametrized, Class<?>... parameterClasses) {
T pojo = null; T pojo = null;
JavaType javaType = objectMapper.getTypeFactory().constructParametrizedType(parametrized, parametrized, JavaType javaType = jsonMapper.getTypeFactory().constructParametrizedType(parametrized, parametrized,
parameterClasses); parameterClasses);
try { try {
pojo = objectMapper.readValue(json, javaType); pojo = jsonMapper.readValue(json, javaType);
} catch (JsonParseException e) { } catch (JsonParseException e) {
log.warning("json to Object JsonParseException.\n" + e.getMessage()); log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
} catch (JsonMappingException e) { } catch (JsonMappingException e) {
log.warning("json to Object JsonMappingException.\n" + e.getMessage()); log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
} catch (IOException e) { } catch (IOException e) {
log.warning("json to Object IOException.\n" + e.getMessage()); log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
} }
return pojo; return pojo;
} }
@@ -235,9 +323,9 @@ public class JsonUtil {
public static String obj2Json(Object pojo) { public static String obj2Json(Object pojo) {
String json = null; String json = null;
try { try {
json = objectMapper.writeValueAsString(pojo); json = jsonMapper.writeValueAsString(pojo);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.warning("json to Object JsonProcessingException.\n" + e.getMessage()); log.warning("json to Object JsonProcessingException.\n" + StrUtil.printStackTrace(e));
} }
return json; return json;
} }
@@ -251,10 +339,11 @@ public class JsonUtil {
public static String formatPrinter(Object obj) { public static String formatPrinter(Object obj) {
String json = null; String json = null;
try { try {
json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); json = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.warning("json to Object JsonProcessingException.\n" + e.getMessage()); log.warning("json to Object JsonProcessingException.\n" + StrUtil.printStackTrace(e));
} }
return json; return json;
} }
} }

View File

@@ -4,9 +4,13 @@ import com.yexuejc.base.annotation.ToUeProperty;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/** /**
* 对象工具:对类的操作 * 对象工具:对类的操作
@@ -18,6 +22,8 @@ import java.util.*;
* @date 2018/12/28 15:54 * @date 2018/12/28 15:54
*/ */
public class ObjUtil { public class ObjUtil {
private static Logger log = Logger.getLogger(ObjUtil.class.getName());
private ObjUtil() { private ObjUtil() {
} }
@@ -260,4 +266,150 @@ public class ObjUtil {
return outer; return outer;
} }
/**
* 复制对象属性值,包含父类 (不需要getter和setter)
* <p>includeField和excludeField同时传入走包含逻辑</p>
*
* @param source 源对象
* @param targetClass 目标对象class
* @param includeField 包含对象
* @param excludeField 排除对象
* @param <I>
* @param <O>
* @return 目标对象
* @throws Exception
*/
public static <I, O> O copy(I source, Class<O> targetClass, List<String> includeField, List<String> excludeField) throws Exception {
List<Field> allFields = getAllFields(source.getClass());
O o = targetClass.getDeclaredConstructor().newInstance();
if (StrUtil.isNotEmpty(excludeField) && StrUtil.isEmpty(includeField)) {
allFields = allFields.stream().filter(f -> !excludeField.contains(f.getName())).collect(Collectors.toList());
}
if (StrUtil.isNotEmpty(includeField)) {
allFields = allFields.stream().filter(f -> includeField.contains(f.getName())).collect(Collectors.toList());
}
allFields.forEach(f -> {
try {
try {
Field field = targetClass.getDeclaredField(f.getName());
if (field != null) {
f.setAccessible(true);
Object v = f.get(source);
f.setAccessible(false);
field.setAccessible(true);
field.set(o, v);
field.setAccessible(false);
}
} catch (NoSuchFieldException e) {
}
} catch (Exception e) {
log.warning(lowerCaseFirstChar(f.getName()) + " field copy failed. " + e);
log.log(Level.FINER, lowerCaseFirstChar(f.getName()) +
" field copy failed. The exception information is as follows:", e);
}
});
return o;
}
/**
* 深度复制对象
* <p>获取source的所有getXxx。xxx作为属性且包含父类的getXxx</p>
* <p>查找target的xxx属性进行反射设值</p>
*
* @param source 源对象
* @param targetClass 目标对象class
* @param invokeSetter 设置target属性值时是否使用setter方法设置
* @param <I>
* @param <O>
* @return 目标对象
*/
public static <I, O> O copy(I source, Class<O> targetClass, boolean invokeSetter) throws Exception {
List<Method> getterMethods = getAllGetterMethods(source.getClass(), "get");
O o = targetClass.getDeclaredConstructor().newInstance();
getterMethods.forEach(method -> {
String fieldName = method.getName().replace("get", "");
try {
Object v = method.invoke(source);
if (invokeSetter) {
try {
Method setterMethod = targetClass.getDeclaredMethod("set" + fieldName, method.getReturnType());
if (null != setterMethod) {
setterMethod.invoke(o, v);
}
} catch (NoSuchMethodException e) {
}
} else {
try {
Field field = targetClass.getDeclaredField(lowerCaseFirstChar(fieldName));
if (field != null) {
field.setAccessible(true);
field.set(o, v);
field.setAccessible(false);
}
} catch (NoSuchFieldException e) {
}
}
} catch (Exception e) {
log.warning(lowerCaseFirstChar(fieldName) + " field copy failed. " + e);
log.log(Level.FINER, lowerCaseFirstChar(fieldName) +
" field copy failed. The exception information is as follows:\n", e);
}
});
return o;
}
/**
* 获取所有方法,包含父类
*
* @param beanClass
* @param startsWith 方法的开头匹配(空,返回所有)
* @return
*/
public static List<Method> getAllGetterMethods(Class<?> beanClass, String startsWith) {
List<Method> methodList = new ArrayList<>();
Method[] methods = beanClass.getDeclaredMethods();
if (StrUtil.isNotEmpty(startsWith)) {
methodList.addAll(Arrays.stream(methods)
.filter(method -> method.getName().startsWith(startsWith))
.collect(Collectors.toList()));
} else {
methodList.addAll(Arrays.asList(methods));
}
Class<?> superclass = beanClass.getSuperclass();
if (superclass != null) {
methodList.addAll(getAllGetterMethods(superclass, startsWith));
}
return methodList;
}
/**
* 获取所有属性,包含父类
*
* @param beanClass
* @return
*/
public static List<Field> getAllFields(Class<?> beanClass) {
List<Field> fieldList = new ArrayList<>();
while (beanClass != null) {
fieldList.addAll(Arrays.asList(beanClass.getDeclaredFields()));
beanClass = beanClass.getSuperclass();
}
return fieldList;
}
/**
* 首字母小写
*
* @param str
* @return
*/
public static String lowerCaseFirstChar(String str) {
if (str == null || str.length() == 0) {
return str;
} else {
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
}
} }

View File

@@ -1,9 +1,20 @@
package com.yexuejc.base.util; package com.yexuejc.base.util;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -19,7 +30,7 @@ public final class StrUtil {
private StrUtil() { private StrUtil() {
} }
public static char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/** /**
* 判断字符串,数组,集合 是否为空 * 判断字符串,数组,集合 是否为空
@@ -111,40 +122,6 @@ public final class StrUtil {
return num.append(String.format("%010d", hashCode)).toString().substring(0, 8); return num.append(String.format("%010d", hashCode)).toString().substring(0, 8);
} }
/**
* 解析aa=bb&cc=dd&ee=ff格式的字符串返回HashMap
*
* @param urlencoded
* @return
*/
public static Map<String, String> parseUrlencoded(String urlencoded) {
if (isEmpty(urlencoded)) {
return null;
}
String[] entrys = urlencoded.split("&");
if (isEmpty(entrys)) {
return null;
}
Map<String, String> map = new HashMap<String, String>(16);
String[] kv = null;
for (String entry : entrys) {
if (isEmpty(entry)) {
continue;
}
kv = entry.split("=");
if (isEmpty(kv)) {
continue;
}
if (kv.length > 1) {
map.put(kv[0], kv[1]);
} else {
map.put(kv[0], null);
}
}
return map;
}
/** /**
* 字符串转换方法 把字节数组转换成16进制字符串 * 字符串转换方法 把字节数组转换成16进制字符串
* *
@@ -254,8 +231,8 @@ public final class StrUtil {
/** /**
* 对ID32位进行编码 * 对ID32位进行编码
* *
* @param id * @param id 32位ID
* @return * @return 编码后的64位ID
*/ */
public static String codeId(String id) { public static String codeId(String id) {
if (id == null || id.length() != 32) { if (id == null || id.length() != 32) {
@@ -282,8 +259,8 @@ public final class StrUtil {
/** /**
* 对ID32位进行解码 * 对ID32位进行解码
* *
* @param coded * @param coded 编码后的64位ID
* @return * @return 解码后的32位ID
*/ */
public static String decodeId(String coded) { public static String decodeId(String coded) {
if (coded == null || coded.length() != 64) { if (coded == null || coded.length() != 64) {
@@ -297,6 +274,40 @@ public final class StrUtil {
return id.toString(); return id.toString();
} }
/**
* 解析aa=bb&cc=dd&ee=ff格式的字符串返回HashMap
*
* @param urlencoded
* @return
*/
public static Map<String, String> parseUrlencoded(String urlencoded) {
if (isEmpty(urlencoded)) {
return null;
}
String[] entrys = urlencoded.split("&");
if (isEmpty(entrys)) {
return null;
}
Map<String, String> map = new HashMap<String, String>(16);
String[] kv = null;
for (String entry : entrys) {
if (isEmpty(entry)) {
continue;
}
kv = entry.split("=");
if (isEmpty(kv)) {
continue;
}
if (kv.length > 1) {
map.put(kv[0], kv[1]);
} else {
map.put(kv[0], null);
}
}
return map;
}
/** /**
* map parameters 转url parameters * map parameters 转url parameters
* *
@@ -370,7 +381,7 @@ public final class StrUtil {
/** /**
* 下划线字符 * 下划线字符
*/ */
public static final char UNDERLINE = '_'; private static final char UNDERLINE = '_';
/** /**
* 字符串下划线转驼峰格式 * 字符串下划线转驼峰格式
@@ -419,4 +430,69 @@ public final class StrUtil {
} }
return sb.toString(); return sb.toString();
} }
private static final String NEW_LINE = "\n";
private static final String ERROR_MESSAGE_FORMAT = "%s.%s(%s:%d)";
/**
* 把异常堆栈信息转化为字符串,同时把所有的errorMessage用\n方式拼接到printStackTrace前面 -> 替代 e.printStackTrace()
* <p>使用e.printStackTrace()不能作为字符串处理本方法可以转换e.printStackTrace()为字符串</p>
* <p><b>printStackTrace</b>信息从<i>Caused by:</i>C开始</p>
*
* @param cause
* @return
*/
public static String printStackTraceAndMessage(Throwable cause) {
if (cause != null) {
StringBuilder msg = new StringBuilder();
if (isNotEmpty(cause.getMessage())) {
msg.append(cause.getMessage()).append(NEW_LINE);
}
String causedMsg = printStackTrace(cause, (eMessage) -> {
if (isNotEmpty(eMessage)) {
msg.append(eMessage).append(NEW_LINE);
}
});
return msg.append(causedMsg).toString();
}
return "";
}
/**
* 把异常堆栈信息转化为字符串 -> 替代 e.printStackTrace()
* <p>使用e.printStackTrace()不能作为字符串处理本方法可以转换e.printStackTrace()为字符串</p>
*
* @param cause
* @return
*/
public static String printStackTrace(Throwable cause) {
return printStackTrace(cause, (eMessage) -> {
});
}
private static String printStackTrace(Throwable cause, Consumer<String> consumer) {
if (cause != null) {
StringBuilder sb = new StringBuilder();
String cClass = cause.getClass().getName();
String eMessage = cause.getMessage();
StackTraceElement[] stackTrace = cause.getStackTrace();
Throwable caused = cause.getCause();
while (caused != null) {
cClass = caused.getClass().getName();
eMessage = caused.getMessage();
stackTrace = caused.getStackTrace();
caused = caused.getCause();
consumer.accept(eMessage);
}
sb.append("Caused by: ").append(cClass).append(": ").append(eMessage).append(NEW_LINE);
for (StackTraceElement element : stackTrace) {
sb.append("\tat ");
sb.append(String.format(ERROR_MESSAGE_FORMAT, element.getClassName(), element.getMethodName(),
element.getFileName(), element.getLineNumber()));
sb.append(NEW_LINE);
}
return sb.toString();
}
return "";
}
} }

View File

@@ -0,0 +1,65 @@
package com.yexuejc.base.util;
import com.yexuejc.base.pojo.CreateZipFileBean;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ExcludeFileFilter;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 压缩相关
* <p>依赖于zip4j<a href='https://github.com/srikanth-lingala/zip4j'>https://github.com/srikanth-lingala/zip4j</a></p>
*
* @author maxf
* @class-name ZipUtil
* @description 文件压缩
* @date 2022/11/11 11:09
*/
public class ZipUtil {
/**
* 创建压缩文件
*
* @param zipFileBean
*/
public static void createZipFile(CreateZipFileBean zipFileBean) throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(CompressionMethod.STORE);
//加密
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
ZipFile zipFile = new ZipFile(zipFileBean.getZipFile());
if (StrUtil.isNotEmpty(zipFileBean.getEncryptPwd())) {
zipFile = new ZipFile(zipFileBean.getZipFile(), zipFileBean.getEncryptPwd().toCharArray());
}
if (StrUtil.isNotEmpty(zipFileBean.getSourceFileName())) {
//压缩文件
List<File> filesToAdd = new ArrayList<>(16);
Map<String, String> fileNamesMap = new HashMap<>(16);
zipFileBean.getSourceFileName().forEach(it -> {
String file = zipFileBean.getSourcePath() + File.separator + it;
filesToAdd.add(new File(file));
fileNamesMap.put(file, it);
});
zipFile.renameFiles(fileNamesMap);
zipFile.addFiles(filesToAdd, zipParameters);
} else {
//压缩目录
ExcludeFileFilter excludeFileFilter = zipFileBean.getExcludeFileName()::contains;
zipParameters.setExcludeFileFilter(excludeFileFilter);
zipFile.addFolder(new File(zipFileBean.getSourcePath()), zipParameters);
}
}
}
//checkemun key -> codeMst检索(缓存)
//返回exception(message用区分分割文言和exp)