mirror of
https://gitee.com/jzsw-it/yexuejc-base.git
synced 2025-06-06 13:54:03 +08:00
[update] 1.5.2-jre8 发布
This commit is contained in:
parent
d25dee8fe4
commit
e7b8f020ed
38
README.md
38
README.md
@ -7,23 +7,9 @@ gitee:https://gitee.com/jzsw-it/yexuejc-base
|
|||||||
### 说明
|
### 说明
|
||||||
1. 支持环境:java8(1.5.0开始支持java11,请使用`x.x.x-jre11`版本)
|
1. 支持环境:java8(1.5.0开始支持java11,请使用`x.x.x-jre11`版本)
|
||||||
2. 该工具包基于springboot提取,按理说适用于所有java工程
|
2. 该工具包基于springboot提取,按理说适用于所有java工程
|
||||||
3. 其中依赖jjwt相关、validation-api,排除请使用
|
3. 从`1.5.0`开始,版本分为`1.5.0-jre8`和`1.5.0-jre11`,分别对于jre8和jre11使用
|
||||||
> ```
|
|
||||||
> <exclusions>
|
|
||||||
> <exclusion>
|
|
||||||
> <artifactId>xxx</artifactId>
|
|
||||||
> <groupId>xxxx</groupId>
|
|
||||||
> </exclusion>
|
|
||||||
> </exclusions>
|
|
||||||
> ```
|
|
||||||
>
|
|
||||||
4. `1.1.9` 升级JWT为单例类
|
|
||||||
5. `1.2.3` 修复RSA加密(签名)Base64Url 问题,如需使用RSA请使用1.2.3+
|
|
||||||
6. 从`1.3.0`开始,变更组织`groupId`为`top.yexuejc`。使用者请尽快升级到`1.3.0`以上(1.3.0代码向下兼容)
|
|
||||||
7. 从`1.5.0`开始,版本分为`1.5.0-jre8`和`1.5.0-jre11`,分别对于jre8和jre11使用
|
|
||||||
|
|
||||||
### 使用
|
### 使用
|
||||||
>yexuejc.base.version=1.5.0-jre8
|
|
||||||
|
|
||||||
pom.xml
|
pom.xml
|
||||||
```
|
```
|
||||||
@ -31,30 +17,10 @@ pom.xml
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>top.yexuejc</groupId>
|
<groupId>top.yexuejc</groupId>
|
||||||
<artifactId>yexuejc-base</artifactId>
|
<artifactId>yexuejc-base</artifactId>
|
||||||
<version>${yexuejc.base.version}</version>
|
<version>1.5.2-jre8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 附:1.3.0之前的使用方式
|
|
||||||
pom.xml
|
|
||||||
```
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.yexuejc.base</groupId>
|
|
||||||
<artifactId>yexuejc-base</artifactId>
|
|
||||||
<version>1.3.0以下</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>yexuejc-nexus-public</id>
|
|
||||||
<name>yexuejc-nexus-public</name>
|
|
||||||
<url>https://nexus.yexuejc.club/repository/maven-public/</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 工具文档
|
### 工具文档
|
||||||
[Wiki](WIKI.md)
|
[Wiki](WIKI.md)
|
||||||
|
|
||||||
|
21
UPDATE.md
21
UPDATE.md
@ -1,5 +1,26 @@
|
|||||||
yexuejc-base 更新记录
|
yexuejc-base 更新记录
|
||||||
------------------
|
------------------
|
||||||
|
#### version :1.5.2-jre8
|
||||||
|
**time:2024-4-7 14:34:33** <br/>
|
||||||
|
**branch:** jre8 <br/>
|
||||||
|
**update:** <br/>
|
||||||
|
1. 升级相关依赖
|
||||||
|
2. 依赖工具读取文件[FileInput.java](src/main/java/com/yexuejc/base/file/FileInput.java)从[FileUtil.java](src/main/java/com/yexuejc/base/util/FileUtil.java)中提取出来
|
||||||
|
3. 优化[FileUtil.java](src/main/java/com/yexuejc/base/util/FileUtil.java)
|
||||||
|
4. 优化[JwtUtil.java](src/main/java/com/yexuejc/base/util/JwtUtil.java)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### version :1.5.1-jre8
|
||||||
|
**time:2023-6-8 16:02:56** <br/>
|
||||||
|
**branch:** jre11 <br/>
|
||||||
|
**update:** <br/>
|
||||||
|
1. FileUtil 增加读取csv文件(分页读取)
|
||||||
|
提供读取IO流方法合集
|
||||||
|
2. 增加AES加解密
|
||||||
|
3. 增加文件压缩ZipUtil
|
||||||
|
4. DateUtil,DateTimeUtil 时间操作工具优化
|
||||||
|
5. JsonUtil [feat] 增加json化时对LocalDateTime,LocalDate,Timestamp时间的优化,增加特殊场景序列化反序列化
|
||||||
|
|
||||||
#### version :1.5.0-jre8
|
#### version :1.5.0-jre8
|
||||||
**time:2022-5-9 13:37:31** <br/>
|
**time:2022-5-9 13:37:31** <br/>
|
||||||
|
47
pom.xml
47
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<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.2-jre8</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>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<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>
|
||||||
|
|
||||||
@ -42,16 +42,17 @@
|
|||||||
<repos.yexuejc.url>https://nexus.yexuejc.top/repository/</repos.yexuejc.url>
|
<repos.yexuejc.url>https://nexus.yexuejc.top/repository/</repos.yexuejc.url>
|
||||||
<repos.aliyun.url>https://maven.aliyun.com/repository/public</repos.aliyun.url>
|
<repos.aliyun.url>https://maven.aliyun.com/repository/public</repos.aliyun.url>
|
||||||
<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.12.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>1.8</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-jdk18on.version>1.78</bcprov-jdk18on.version>
|
||||||
<guava.version>31.1-jre</guava.version>
|
<guava.version>33.1.0-jre</guava.version>
|
||||||
<apache-poi.version>5.2.2</apache-poi.version>
|
<apache-poi.version>5.2.5</apache-poi.version>
|
||||||
<jackson.version>2.13.2</jackson.version>
|
<jackson.version>2.17.0</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>
|
||||||
@ -92,14 +93,15 @@
|
|||||||
<!--支持大量的密码术算法,并提供JCE 1.2.1的实现-->
|
<!--支持大量的密码术算法,并提供JCE 1.2.1的实现-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
<artifactId>bcprov-jdk18on</artifactId>
|
||||||
<version>${bcprov-jdk15on.version}</version>
|
<version>${bcprov-jdk18on.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--com.yexuejc.base.util.SysUtil.threadRun 异步处理代码-->
|
<!--com.yexuejc.base.file.FileInput 读文件-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -111,17 +113,34 @@
|
|||||||
<groupId>org.apache.poi</groupId>
|
<groupId>org.apache.poi</groupId>
|
||||||
<artifactId>poi-ooxml</artifactId>
|
<artifactId>poi-ooxml</artifactId>
|
||||||
<version>${apache-poi.version}</version>
|
<version>${apache-poi.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
<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>
|
||||||
|
|
||||||
@ -133,7 +152,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.13.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
<source>8</source>
|
<source>8</source>
|
||||||
@ -144,7 +163,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>3.3.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-sources</id>
|
<id>attach-sources</id>
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package com.yexuejc.base.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置csv header
|
|
||||||
*
|
|
||||||
* @author MAXF-MAC
|
|
||||||
*/
|
|
||||||
@Target({ElementType.TYPE})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
@Inherited
|
|
||||||
public @interface CsvHeader {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在类头上设置csv格式的header
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
String header();
|
|
||||||
}
|
|
36
src/main/java/com/yexuejc/base/annotation/CsvToBean.java
Normal file
36
src/main/java/com/yexuejc/base/annotation/CsvToBean.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package com.yexuejc.base.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置csv header
|
||||||
|
*
|
||||||
|
* @author MAXF-MAC
|
||||||
|
*/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface CsvToBean {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在类头上设置csv格式的header
|
||||||
|
* csv文件和java bean的映射
|
||||||
|
*/
|
||||||
|
String header();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* csv文件的分割符号
|
||||||
|
*/
|
||||||
|
char delimiter() default ',';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSV文件是否有header
|
||||||
|
*/
|
||||||
|
boolean hasHeader() default false;
|
||||||
|
}
|
21
src/main/java/com/yexuejc/base/constant/DateConsts.java
Normal file
21
src/main/java/com/yexuejc/base/constant/DateConsts.java
Normal 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";
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.yexuejc.base.converter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.yexuejc.base.converter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.yexuejc.base.converter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.yexuejc.base.converter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.yexuejc.base.converter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.yexuejc.base.converter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.yexuejc.base.constant.DateConsts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
}
|
61
src/main/java/com/yexuejc/base/pojo/CsvToBean.java
Normal file
61
src/main/java/com/yexuejc/base/pojo/CsvToBean.java
Normal 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 hasHeader() {
|
||||||
|
return hasHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CsvToBean setHasHeader(boolean hasHeader) {
|
||||||
|
this.hasHeader = hasHeader;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.yexuejc.base.pojo;
|
package com.yexuejc.base.pojo;
|
||||||
|
|
||||||
|
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 +37,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 +56,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 +114,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,71 @@ 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)));
|
||||||
|
System.out.println(parseLocalDateTime10(System.currentTimeMillis() / 1000));
|
||||||
|
System.out.println(parseLocalDateTime13(System.currentTimeMillis()));
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
@ -58,8 +59,8 @@ public class DateUtil {
|
|||||||
/**
|
/**
|
||||||
* 比较两个日期大小
|
* 比较两个日期大小
|
||||||
*
|
*
|
||||||
* @param date1
|
* @param date1 格式 yyyy-MM-dd
|
||||||
* @param date2
|
* @param date2 格式 yyyy-MM-dd
|
||||||
* @return date1>date2返回1;date1=date2返回0;date1<date2返回-1
|
* @return date1>date2返回1;date1=date2返回0;date1<date2返回-1
|
||||||
* @throws ParseException
|
* @throws ParseException
|
||||||
*/
|
*/
|
||||||
@ -191,4 +192,59 @@ 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* public static void main(String[] args) throws ParseException {
|
||||||
|
System.out.println(DateUtil.currentDate());
|
||||||
|
System.out.println(DateUtil.currentTime());
|
||||||
|
System.out.println(DateUtil.currentDateTime());
|
||||||
|
System.out.println(DateUtil.dateCompare("2024-01-25","2025-01-01"));
|
||||||
|
System.out.println(DateUtil.str2date("2024-01-25"));
|
||||||
|
System.out.println(DateUtil.date2str(new Date()));
|
||||||
|
System.out.println(DateUtil.str2dateTime("2024-04-08 11:01:39.361"));
|
||||||
|
System.out.println(DateUtil.dateTime2str(new Date()));
|
||||||
|
System.out.println(DateUtil.getCurrentWeek(1));
|
||||||
|
System.out.println(DateUtil.dateMinus(DateUtil.datePlus(new Date(),50),new Date(),'M'));
|
||||||
|
System.out.println(DateUtil.convertUTC(new Date()));
|
||||||
|
System.out.println(DateUtil.convertTimezone(new Date(),"UTC","Asia/Shanghai"));
|
||||||
|
System.out.println(DateUtil.convertTimezone(new Date(),"UTC"));
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,33 @@
|
|||||||
package com.yexuejc.base.util;
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.MappingIterator;
|
import com.fasterxml.jackson.databind.MappingIterator;
|
||||||
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
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.yexuejc.base.annotation.CsvToBean;
|
||||||
import com.google.common.io.CharStreams;
|
|
||||||
import com.yexuejc.base.annotation.CsvHeader;
|
|
||||||
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 java.io.*;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.nio.MappedByteBuffer;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.zip.CRC32;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件工具类
|
* 文件工具类
|
||||||
@ -65,25 +68,41 @@ public class FileUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否存在
|
||||||
|
*
|
||||||
|
* @param filePath
|
||||||
|
* @return false 文件不存在;true 文件存在
|
||||||
|
*/
|
||||||
|
public static boolean isFileExist(String filePath) {
|
||||||
|
if (StrUtil.isEmpty(filePath)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File file = new File(filePath);
|
||||||
|
return file.exists() && !file.isDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断文件是否存在,不存在就创建一个空的
|
* 判断文件是否存在,不存在就创建一个空的
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
public static void judeFileExists(File file) {
|
public static void judeFileExists(File file) {
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
logger.severe("file exists");
|
logger.severe("file exists");
|
||||||
} else {
|
} else {
|
||||||
logger.info("file not exists, create it ...");
|
logger.info("file not exists, create it ...");
|
||||||
try {
|
try {
|
||||||
file.createNewFile();
|
boolean b = file.createNewFile();
|
||||||
|
if (b) {
|
||||||
|
logger.info("file create success");
|
||||||
|
} else {
|
||||||
|
logger.severe("file create fail");
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.severe("file create fail");
|
logger.log(Level.WARNING, "file create fail", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,74 +139,10 @@ public class FileUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String sha1(File file) {
|
public static String sha1(File file) {
|
||||||
FileInputStream in = null;
|
return getDigest(file, "SHA-1");
|
||||||
try {
|
|
||||||
in = new FileInputStream(file);
|
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
|
||||||
byte[] buffer = new byte[1024 * 1024 * 10];
|
|
||||||
|
|
||||||
int len = 0;
|
|
||||||
while ((len = in.read(buffer)) > 0) {
|
|
||||||
digest.update(buffer, 0, len);
|
|
||||||
}
|
|
||||||
String sha1 = new BigInteger(1, digest.digest()).toString(16);
|
|
||||||
int length = 40 - sha1.length();
|
|
||||||
if (length > 0) {
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
sha1 = "0" + sha1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sha1;
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
logger.severe("system algorithm error.");
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
logger.severe("file doesn't exist or is not a file");
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("The operation file is an IO exception.");
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (in != null) {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("close FileInputStream IO exception.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
* 计算SHA1码
|
|
||||||
*
|
|
||||||
* @return String 适用于上G大的文件
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
* */
|
|
||||||
public static String sha1ByBigFile(File file) {
|
|
||||||
MessageDigest messagedigest = null;
|
|
||||||
try {
|
|
||||||
messagedigest = MessageDigest.getInstance("SHA-1");
|
|
||||||
FileInputStream in = new FileInputStream(file);
|
|
||||||
FileChannel ch = in.getChannel();
|
|
||||||
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
|
|
||||||
messagedigest.update(byteBuffer);
|
|
||||||
return StrUtil.toHex(messagedigest.digest());
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
logger.severe("system algorithm error.");
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
logger.severe("file doesn't exist or is not a file");
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("The operation file is an IO exception.");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件md5
|
* 文件md5
|
||||||
*
|
*
|
||||||
@ -195,66 +150,40 @@ public class FileUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String md5(File file) {
|
public static String md5(File file) {
|
||||||
FileInputStream in = null;
|
return getDigest(file, "MD5");
|
||||||
try {
|
|
||||||
in = new FileInputStream(file);
|
|
||||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
|
||||||
byte[] buffer = new byte[1024 * 1024 * 10];
|
|
||||||
|
|
||||||
int len = 0;
|
|
||||||
while ((len = in.read(buffer)) > 0) {
|
|
||||||
digest.update(buffer, 0, len);
|
|
||||||
}
|
|
||||||
String md5 = new BigInteger(1, digest.digest()).toString(16);
|
|
||||||
int length = 32 - md5.length();
|
|
||||||
if (length > 0) {
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
md5 = "0" + md5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return md5;
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("The operation file is an IO exception.");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
logger.severe("system algorithm error.");
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (in != null) {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("close FileInputStream IO exception.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对一个文件获取md5值
|
* 获取文件的散列值
|
||||||
*
|
* @param file
|
||||||
* @return md5串
|
* @param digestCode
|
||||||
* @throws NoSuchAlgorithmException
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String md5ByBigFile(File file) {
|
private static String getDigest(File file, String digestCode) {
|
||||||
|
try (FileInputStream in = new FileInputStream(file)) {
|
||||||
MessageDigest messagedigest = null;
|
MessageDigest digest = MessageDigest.getInstance(digestCode);
|
||||||
try {
|
FileChannel channel = in.getChannel();
|
||||||
messagedigest = MessageDigest.getInstance("MD5");
|
ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); // 1MB 缓冲区
|
||||||
FileInputStream in = new FileInputStream(file);
|
// 读取文件内容并更新 MessageDigest
|
||||||
FileChannel ch = in.getChannel();
|
while (channel.read(buffer) != -1) {
|
||||||
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
|
buffer.flip(); // 将 Buffer 从写模式切换到读模式
|
||||||
file.length());
|
digest.update(buffer); // 更新 MessageDigest
|
||||||
messagedigest.update(byteBuffer);
|
buffer.clear(); // 清空 Buffer
|
||||||
return StrUtil.toHex(messagedigest.digest());
|
}
|
||||||
|
// 计算最终的 SHA-1 散列值
|
||||||
|
byte[] sha1Bytes = digest.digest();
|
||||||
|
// 将字节数组转换为十六进制字符串
|
||||||
|
StringBuilder sha1Builder = new StringBuilder();
|
||||||
|
for (byte b : sha1Bytes) {
|
||||||
|
sha1Builder.append(String.format("%02x", b));
|
||||||
|
}
|
||||||
|
return sha1Builder.toString();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
logger.severe("system algorithm error.");
|
logger.log(Level.SEVERE, "system algorithm error.", e);
|
||||||
e.printStackTrace();
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
logger.severe("file doesn't exist or is not a file");
|
logger.log(Level.SEVERE, "file doesn't exist or is not a file", e);
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.severe("The operation file is an IO exception.");
|
logger.log(Level.SEVERE, "The operation file is an IO exception.", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -262,37 +191,24 @@ public class FileUtil {
|
|||||||
/**
|
/**
|
||||||
* 获取文件CRC32码
|
* 获取文件CRC32码
|
||||||
*
|
*
|
||||||
* @return String
|
* @return 获取失败返回-1
|
||||||
*/
|
*/
|
||||||
public static String crc32(File file) {
|
public static long crc32(File file) {
|
||||||
CRC32 crc32 = new CRC32();
|
CRC32 crc32 = new CRC32();
|
||||||
// MessageDigest.get
|
// MessageDigest.get
|
||||||
FileInputStream fileInputStream = null;
|
try (FileInputStream fileInputStream = new FileInputStream(file);) {
|
||||||
try {
|
byte[] buffer = new byte[1024 * 1024];
|
||||||
fileInputStream = new FileInputStream(file);
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int length;
|
int length;
|
||||||
while ((length = fileInputStream.read(buffer)) != -1) {
|
while ((length = fileInputStream.read(buffer)) != -1) {
|
||||||
crc32.update(buffer, 0, length);
|
crc32.update(buffer, 0, length);
|
||||||
}
|
}
|
||||||
return crc32.getValue() + "";
|
return crc32.getValue();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
logger.severe("file doesn't exist or is not a file");
|
logger.log(Level.SEVERE, "file doesn't exist or is not a file", e);
|
||||||
e.printStackTrace();
|
return -1;
|
||||||
return null;
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.severe("The operation file is an IO exception.");
|
logger.log(Level.SEVERE, "The operation file is an IO exception.", e);
|
||||||
e.printStackTrace();
|
return -1;
|
||||||
return null;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (fileInputStream != null) {
|
|
||||||
fileInputStream.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("close FileInputStream IO exception.");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,44 +219,27 @@ 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(Paths.get(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) throws IOException {
|
||||||
return base64ToFile(Base64.getDecoder().decode(decode.getBytes()), fileName);
|
return base64ToFile(Base64.getDecoder().decode(decode.getBytes()), fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,29 +247,16 @@ 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
|
||||||
* @param fileName 文件名称(包含路径)
|
* @param fileName 文件名称(包含路径)
|
||||||
* @return 返回保存地址
|
* @return 返回保存地址
|
||||||
*/
|
*/
|
||||||
public static String base64ToFile(byte[] decode, String fileName) {
|
public static String base64ToFile(byte[] decode, String fileName) throws IOException {
|
||||||
|
try (FileOutputStream out = new FileOutputStream(fileName)) {
|
||||||
FileOutputStream out = null;
|
|
||||||
try {
|
|
||||||
out = new FileOutputStream(fileName);
|
|
||||||
out.write(decode);
|
out.write(decode);
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (out != null) {
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
@ -378,50 +264,18 @@ public class FileUtil {
|
|||||||
/**
|
/**
|
||||||
* 获取文件大小 :直接返回大小
|
* 获取文件大小 :直接返回大小
|
||||||
*
|
*
|
||||||
* @param f
|
* @param path 文件地址
|
||||||
* @return f.length()
|
* @return f.length()
|
||||||
*/
|
*/
|
||||||
public static long size(File f) {
|
public static long size(Path path) throws IOException {
|
||||||
if (f.exists() && f.isFile()) {
|
if (Files.exists(path) && Files.isRegularFile(path)) {
|
||||||
return f.length();
|
return Files.size(path);
|
||||||
} else {
|
} else {
|
||||||
logger.info("file doesn't exist or is not a file");
|
logger.info("file doesn't exist or is not a file");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件大小 : 用流的方式获取
|
|
||||||
*
|
|
||||||
* @param f
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static long size4Stream(File f) {
|
|
||||||
FileChannel fc = null;
|
|
||||||
try {
|
|
||||||
if (f.exists() && f.isFile()) {
|
|
||||||
FileInputStream fis = new FileInputStream(f);
|
|
||||||
fc = fis.getChannel();
|
|
||||||
return fc.size();
|
|
||||||
} else {
|
|
||||||
logger.info("file doesn't exist or is not a file");
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
logger.severe("file doesn't exist or is not a file");
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("The operation file is an IO exception.");
|
|
||||||
} finally {
|
|
||||||
if (null != fc) {
|
|
||||||
try {
|
|
||||||
fc.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("close FileInputStream IO exception.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串(csv格式)转 对象
|
* 字符串(csv格式)转 对象
|
||||||
*
|
*
|
||||||
@ -448,14 +302,15 @@ public class FileUtil {
|
|||||||
*
|
*
|
||||||
* @param csvFilePath 文件地址
|
* @param csvFilePath 文件地址
|
||||||
* @param cls 读取转化的对象
|
* @param cls 读取转化的对象
|
||||||
* @param hasHeader 是否存在header
|
* @param header 解析列对应的java字段;用delimiter分割
|
||||||
|
* @param hasHeader csv文件中第一行是否是header
|
||||||
* @param delimiter 分隔符.默认【,】
|
* @param delimiter 分隔符.默认【,】
|
||||||
* @param <I>
|
* @param <I>
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static <I> List<I> readCsv(final String csvFilePath, Class<I> cls, boolean hasHeader, char delimiter) {
|
public static <I> List<I> readCsv(final String csvFilePath, Class<I> cls, boolean hasHeader, String header, char delimiter) {
|
||||||
if (!isFileExist(csvFilePath)) {
|
if (!isFileExist(csvFilePath)) {
|
||||||
throw new RuntimeException(String.format("解析用的csv:\u0020[%s] 文件不存在。", csvFilePath));
|
throw new RuntimeException(String.format("解析用的csv: [%s] 文件不存在。", csvFilePath));
|
||||||
}
|
}
|
||||||
if (StrUtil.isEmpty(delimiter)) {
|
if (StrUtil.isEmpty(delimiter)) {
|
||||||
delimiter = ',';
|
delimiter = ',';
|
||||||
@ -463,7 +318,12 @@ public class FileUtil {
|
|||||||
try {
|
try {
|
||||||
File csvFile = new File(csvFilePath);
|
File csvFile = new File(csvFilePath);
|
||||||
CsvMapper csvMapper = new CsvMapper();
|
CsvMapper csvMapper = new CsvMapper();
|
||||||
CsvSchema csvSchema = csvMapper.typedSchemaFor(cls).withStrictHeaders(hasHeader).withColumnSeparator(delimiter).withComments();
|
CsvSchema.Builder builder = CsvSchema.builder();
|
||||||
|
if (StrUtil.isNotEmpty(header)) {
|
||||||
|
builder.addColumns(Arrays.asList(header.split(String.valueOf(delimiter))), CsvSchema.ColumnType.STRING);
|
||||||
|
}
|
||||||
|
CsvSchema csvSchema = builder.build().withColumnSeparator(delimiter).withSkipFirstDataRow(hasHeader).withStrictHeaders(hasHeader).withComments();
|
||||||
|
|
||||||
MappingIterator<I> recordIterator = csvMapper.readerWithTypedSchemaFor(cls).with(csvSchema).readValues(csvFile);
|
MappingIterator<I> recordIterator = csvMapper.readerWithTypedSchemaFor(cls).with(csvSchema).readValues(csvFile);
|
||||||
return recordIterator.readAll();
|
return recordIterator.readAll();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -471,70 +331,74 @@ public class FileUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断文件是否存在
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean isFileExist(String filePath) {
|
|
||||||
if (StrUtil.isEmpty(filePath)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
File file = new File(filePath);
|
|
||||||
return file.exists() && !file.isDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分段读取大文件
|
* 分段读取大文件
|
||||||
*
|
*
|
||||||
* @param path 文件路径
|
* @param csvFilePath 文件路径
|
||||||
* @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数
|
* @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数
|
||||||
* @param <T> 读取结果类型bean
|
* @param <T> 读取结果类型bean
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public <T> ReadFileBean<T> readBigFile(String path, ReadFileBean<T> readFileBean, Class<T> readCls) {
|
public static <T> ReadFileBean<T> readBigFile(String csvFilePath, ReadFileBean<T> readFileBean, Class<T> readCls) throws IOException {
|
||||||
File file = new File(path);
|
if (!isFileExist(csvFilePath)) {
|
||||||
judeFileExists(file);
|
throw new FileNotFoundException(String.format("解析用的csv: [%s] 文件不存在。", csvFilePath));
|
||||||
try {
|
}
|
||||||
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
|
if (!csvFilePath.endsWith(TYPE_CSV)) {
|
||||||
|
throw new IOException(String.format("解析用的csv: [%s] 文件不是CSV文件格式。", csvFilePath));
|
||||||
|
}
|
||||||
|
List<String> datas = new ArrayList<>();
|
||||||
|
try (RandomAccessFile randomAccessFile = new RandomAccessFile(new File(csvFilePath), "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<>();
|
int row = 0;
|
||||||
for (int i = 0; i < readFileBean.getReadRowNum(); i++) {
|
String line;
|
||||||
String s = randomAccessFile.readLine();
|
while ((line = randomAccessFile.readLine()) != null && row <= readFileBean.getReadRowNum()) {
|
||||||
datas.add(charsetDecode(s, StandardCharsets.UTF_8));
|
row++;
|
||||||
readFileBean.setPointer(randomAccessFile.getFilePointer());
|
readFileBean.setPointer(randomAccessFile.getFilePointer());
|
||||||
|
datas.add(readFileBean.lineScavenge(charsetDecode(line, readFileBean.getReadCharset())));
|
||||||
}
|
}
|
||||||
randomAccessFile.close();
|
|
||||||
if (path.contains(TYPE_CSV)) {
|
|
||||||
//csv文件处理
|
|
||||||
datas.add(0, getCsvHeader(readCls));
|
|
||||||
List<T> dataList = readCsv(String.join("\n", datas), readCls, ',');
|
|
||||||
readFileBean.setDatas(dataList);
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
logger.severe("file exists." + e.getMessage());
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("read file error." + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
if (StrUtil.isEmpty(datas)) {
|
||||||
|
//无数据
|
||||||
|
return readFileBean.setDatas(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
//csv文件处理
|
||||||
|
com.yexuejc.base.pojo.CsvToBean csvToBean = getCsvToBean(readCls);
|
||||||
|
readFileBean.setHeader(csvToBean.getHeader());
|
||||||
|
if (csvToBean.hasHeader()) {
|
||||||
|
//文件存在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);
|
||||||
return readFileBean;
|
return readFileBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取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 + "类上需要添加注解@CsvToBean,并指定header。");
|
||||||
String header = annotation.header();
|
return new com.yexuejc.base.pojo.CsvToBean(annotation.header(), annotation.delimiter(), annotation.hasHeader());
|
||||||
Assert.notNull(header, cls.toString() + "类上需要添加注解@CsvHeader,并指定header。");
|
|
||||||
return header;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -552,225 +416,4 @@ public class FileUtil {
|
|||||||
}
|
}
|
||||||
return new String(result, charset);
|
return new String(result, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提供读取IO流方法合集
|
|
||||||
* <p>读取速度快慢顺序:</p>
|
|
||||||
* 1. {@link #read4Buffer(InputStream, Charset)} <br>
|
|
||||||
* 2. {@link #read4IOUtilsCopy(InputStream, Charset)} <br>
|
|
||||||
* 3. {@link #read4ByteStreams(InputStream, Charset)} <br>
|
|
||||||
* 4. {@link #read4Byte(InputStream, Charset)} <br>
|
|
||||||
* 5. {@link #read4StringBuilder(InputStream, Charset)} <br>
|
|
||||||
* 6. {@link #read4BufferedReaderParallel(InputStream, Charset, String)}<br>
|
|
||||||
* 7. {@link #read4BufferedReader(InputStream, Charset, String)}<br>
|
|
||||||
* 8. {@link #read4ScannerA(InputStream)}<br>
|
|
||||||
* 9. {@link #read4BufferIO(InputStream, Charset)}<br>
|
|
||||||
* 10. {@link #read4IOUtils(InputStream, Charset)}<br>
|
|
||||||
* 11. {@link #read4ScannerZ(InputStream)}<br>
|
|
||||||
* 12. {@link #read4CharStreams(InputStream, Charset)}<br>
|
|
||||||
*/
|
|
||||||
public static class FileInput {
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:byte方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String read4Byte(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
byte[] bytes = new byte[inputStream.available()];
|
|
||||||
inputStream.read(bytes);
|
|
||||||
return new String(bytes, charset == null ? Charset.defaultCharset() : charset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:BufferedReader方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @param lineSeparator 换行方式:默认跟随系统 {@link System#lineSeparator()}
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4BufferedReader(InputStream inputStream, Charset charset, String lineSeparator) {
|
|
||||||
return new BufferedReader(
|
|
||||||
new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset)
|
|
||||||
).lines().collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:BufferedReader 并行方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @param lineSeparator 换行方式:默认跟随系统 {@link System#lineSeparator()}
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4BufferedReaderParallel(InputStream inputStream, Charset charset, String lineSeparator) {
|
|
||||||
return new BufferedReader(
|
|
||||||
new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset)
|
|
||||||
).lines().parallel()
|
|
||||||
.collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:Scanner A方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4ScannerA(InputStream inputStream) {
|
|
||||||
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
|
|
||||||
String str = s.hasNext() ? s.next() : "";
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:Scanner Z方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4ScannerZ(InputStream inputStream) {
|
|
||||||
return new Scanner(inputStream).useDelimiter("\\Z").next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:StringBuilder方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4StringBuilder(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset));
|
|
||||||
while ((line = br.readLine()) != null) {
|
|
||||||
sb.append(line);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:ByteArrayOutputStream方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4Buffer(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length;
|
|
||||||
while ((length = inputStream.read(buffer)) != -1) {
|
|
||||||
result.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
return result.toString(charset == null ? Charset.defaultCharset().name() : charset.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容:BufferedInputStream+ByteArrayOutputStream方式
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String read4BufferIO(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(inputStream);
|
|
||||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
|
||||||
int result = bis.read();
|
|
||||||
while (result != -1) {
|
|
||||||
buf.write((byte) result);
|
|
||||||
result = bis.read();
|
|
||||||
}
|
|
||||||
return buf.toString(charset == null ? Charset.defaultCharset().name() : charset.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容: 依赖于commons-io:commons-io {@link IOUtils#copy(Reader, OutputStream, Charset)}
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String read4IOUtilsCopy(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
IOUtils.copy(inputStream, writer, charset == null ? Charset.defaultCharset() : charset);
|
|
||||||
return writer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容: 依赖于commons-io:commons-io {@link IOUtils#toString(InputStream, Charset)}
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String read4IOUtils(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
return IOUtils.toString(inputStream, charset == null ? Charset.defaultCharset() : charset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容: 依赖于com.google.guava:guava {@link CharStreams#toString(Readable)}
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String read4CharStreams(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
return CharStreams.toString(new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取IO流内容: 依赖于com.google.guava:guava {@link ByteStreams#toByteArray(InputStream)}
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()}
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String read4ByteStreams(InputStream inputStream, Charset charset) throws IOException {
|
|
||||||
return new String(ByteStreams.toByteArray(inputStream), charset == null ? Charset.defaultCharset() : charset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public static void main(String[] args) {
|
|
||||||
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(1024 * 1024 * 5);
|
|
||||||
if (size > 1024 * 1024 * 5) {
|
|
||||||
System.out.println("文件最大5M");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long s1 = fileSize(new File("E:\\OS\\cn_windows_10_consumer_editions_version_1803_updated_march_2018_x64_dvd_12063766.iso"));
|
|
||||||
System.out.println(s1);
|
|
||||||
long s2 = fileSize4Stream(new File("E:\\OS\\cn_windows_10_consumer_editions_version_1803_updated_march_2018_x64_dvd_12063766.iso"));
|
|
||||||
System.out.println(s2);
|
|
||||||
|
|
||||||
String s1 = base64(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
|
||||||
System.out.println(s1);
|
|
||||||
|
|
||||||
String s = sha1(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
|
||||||
String s2 = sha1ByBigFile(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
|
||||||
System.out.println(s);
|
|
||||||
System.out.println(s2);
|
|
||||||
|
|
||||||
|
|
||||||
String md5 = md5(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
|
||||||
String md52 = md5ByBigFile(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
|
||||||
System.out.println(md5);
|
|
||||||
System.out.println(md52);
|
|
||||||
|
|
||||||
|
|
||||||
String crc32 = crc32(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
|
||||||
System.out.println(crc32);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,37 @@
|
|||||||
package com.yexuejc.base.util;
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
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 java.io.IOException;
|
import com.yexuejc.base.converter.LocalDateDeserializer;
|
||||||
import java.io.InputStream;
|
import com.yexuejc.base.converter.LocalDateSerializer;
|
||||||
import java.util.Map;
|
import com.yexuejc.base.converter.LocalDateTimeDeserializer;
|
||||||
import java.util.TimeZone;
|
import com.yexuejc.base.converter.LocalDateTimeSerializer;
|
||||||
import java.util.logging.Logger;
|
import com.yexuejc.base.converter.TimestampDeserializer;
|
||||||
|
import com.yexuejc.base.converter.TimestampSerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json工具类,基于jackson
|
* json工具类,基于jackson
|
||||||
@ -24,7 +42,7 @@ import java.util.logging.Logger;
|
|||||||
* @date 2018/9/3 15:28
|
* @date 2018/9/3 15:28
|
||||||
*/
|
*/
|
||||||
public class JsonUtil {
|
public class JsonUtil {
|
||||||
private static Logger log = Logger.getLogger(JsonUtil.class.getName());
|
private static final Logger log = Logger.getLogger(JsonUtil.class.getName());
|
||||||
|
|
||||||
private JsonUtil() {
|
private JsonUtil() {
|
||||||
}
|
}
|
||||||
@ -32,32 +50,103 @@ public class JsonUtil {
|
|||||||
/**
|
/**
|
||||||
* 作为单例全局使用
|
* 作为单例全局使用
|
||||||
*/
|
*/
|
||||||
private static ObjectMapper objectMapper = new ObjectMapper();
|
private static final JsonMapper jsonMapper = new JsonMapper();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
JsonUtil.initDefaultObjectMapper(JsonUtil.objectMapper);
|
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_PROPERTIES:json对应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
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
private static void initDefaultObjectMapper(ObjectMapper objectMapper) {
|
private static ObjectMapper initDefaultObjectMapper(ObjectMapper jsonMapper) {
|
||||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
JsonUtil.setJavaTimeModule(jsonMapper);
|
||||||
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
|
//值为空时,NON_NULL:舍去字段;ALWAYS:保留字段
|
||||||
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
|
jsonMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
jsonMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
|
||||||
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
jsonMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
|
||||||
//设置一下时区,可以和程序同步避免时区问题
|
jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
objectMapper.setTimeZone(TimeZone.getDefault());
|
jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
||||||
objectMapper.setDateFormat(DateUtil.DATE_TIME_FORMAT);
|
return jsonMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化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_PROPERTIES:json对应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) {
|
||||||
|
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<Object>() {
|
||||||
|
@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 +175,8 @@ public class JsonUtil {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ObjectMapper getObjectMapper() {
|
public static ObjectMapper getJsonMapper() {
|
||||||
return objectMapper;
|
return jsonMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,13 +190,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 +212,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 +236,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 +261,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 +284,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 +301,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 +324,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 +340,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,12 @@
|
|||||||
package com.yexuejc.base.util;
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
import io.jsonwebtoken.Jwts;
|
|
||||||
import io.jsonwebtoken.SignatureAlgorithm;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.io.Decoders;
|
||||||
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jwt工具类
|
* jwt工具类
|
||||||
@ -34,7 +36,7 @@ public class JwtUtil {
|
|||||||
*
|
*
|
||||||
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
||||||
* @param type 加密类型:默认JWT
|
* @param type 加密类型:默认JWT
|
||||||
* @param iss token发行商: 默认yexuejc.com
|
* @param iss token发行商: 默认yexuejc.top
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static JwtUtil config(String key, String type, String iss) {
|
public static JwtUtil config(String key, String type, String iss) {
|
||||||
@ -60,7 +62,7 @@ public class JwtUtil {
|
|||||||
/**
|
/**
|
||||||
* token发行商
|
* token发行商
|
||||||
*/
|
*/
|
||||||
private String JWT_CLAIMS_ISS = "yexuejc.com";
|
private String JWT_CLAIMS_ISS = "yexuejc.top";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加密内容生成token
|
* 加密内容生成token
|
||||||
@ -76,22 +78,22 @@ public class JwtUtil {
|
|||||||
subject = JsonUtil.obj2Json(subjectObj);
|
subject = JsonUtil.obj2Json(subjectObj);
|
||||||
}
|
}
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
String token = Jwts.builder()
|
return Jwts.builder()
|
||||||
// 设置token的唯一标识ID(claims.jti)
|
// 设置token的唯一标识ID(claims.jti)
|
||||||
.setId(StrUtil.genUUID())
|
.id(StrUtil.genUUID())
|
||||||
// 设置token类型(header.typ)
|
// 设置token类型(header.typ)
|
||||||
.setHeaderParam("typ", JWT_HEADER_TYP)
|
.header().add("typ", JWT_HEADER_TYP)
|
||||||
|
.and()
|
||||||
// 设置token发行时间为当前时间(claims.iat)
|
// 设置token发行时间为当前时间(claims.iat)
|
||||||
.setIssuedAt(now)
|
.issuedAt(now)
|
||||||
// 设置token发行商/发行者(claims.iss)
|
// 设置token发行商/发行者(claims.iss)
|
||||||
.setIssuer(JWT_CLAIMS_ISS)
|
.issuer(JWT_CLAIMS_ISS)
|
||||||
// 设置token用户定义主体(claims.sub)
|
// 设置token用户定义主体(claims.sub)
|
||||||
.setSubject(subject)
|
.subject(subject)
|
||||||
// 设置签名算法和KEY(signature)
|
// 设置算法签名,(密钥,加密算法)
|
||||||
.signWith(SignatureAlgorithm.HS512, JWT_SIGNATURE_KEY)
|
.signWith(getSecretKey(), Jwts.SIG.HS512)
|
||||||
// 生成token
|
// 生成token
|
||||||
.compact();
|
.compact();
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,18 +114,8 @@ public class JwtUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public <T> T parse(String token, Class<T> cls) {
|
public <T> T parse(String token, Class<T> cls) {
|
||||||
String subject = null;
|
return JsonUtil.json2Obj(parseStr(token), cls);
|
||||||
try {
|
|
||||||
subject = Jwts.parser().setSigningKey(JWT_SIGNATURE_KEY).parseClaimsJws(token).getBody().getSubject();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
if (subject == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return JsonUtil.json2Obj(subject, cls);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解密token为字符串
|
* 解密token为字符串
|
||||||
*
|
*
|
||||||
@ -131,12 +123,11 @@ public class JwtUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String parseStr(String token) {
|
public String parseStr(String token) {
|
||||||
String subject = null;
|
return Jwts.parser().verifyWith(getSecretKey()).build().parseSignedClaims(token).getPayload().getSubject();
|
||||||
try {
|
|
||||||
subject = Jwts.parser().setSigningKey(JWT_SIGNATURE_KEY).parseClaimsJws(token).getBody().getSubject();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return subject;
|
|
||||||
|
private SecretKey getSecretKey() {
|
||||||
|
byte[] bytes = Decoders.BASE64.decode(JWT_SIGNATURE_KEY);
|
||||||
|
return Keys.hmacShaKeyFor(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
package com.yexuejc.base.util;
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.lang.reflect.Array;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
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.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
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,39 +29,28 @@ 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 final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断字符串,数组,集合 是否为空
|
* 判断字符串,数组,集合 是否为空(null,"",[],{})
|
||||||
*
|
*
|
||||||
* @param obj
|
* @param obj 対象
|
||||||
|
* @return true:空;false:非空
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isEmpty(Object obj) {
|
public static boolean isEmpty(Object obj) {
|
||||||
if (obj instanceof String) {
|
if (obj == null) {
|
||||||
if (obj == null || "".equals((String) obj)) {
|
return true;
|
||||||
return true;
|
} else if (obj instanceof Optional) {
|
||||||
} else {
|
return !((Optional<?>) obj).isPresent();
|
||||||
return false;
|
} else if (obj instanceof CharSequence) {
|
||||||
}
|
return ((CharSequence) obj).length() == 0;
|
||||||
} else if (obj instanceof Object[]) {
|
} else if (obj.getClass().isArray()) {
|
||||||
if (obj == null || ((Object[]) obj).length == 0) {
|
return Array.getLength(obj) == 0;
|
||||||
return true;
|
} else if (obj instanceof Collection) {
|
||||||
} else {
|
return ((Collection<?>) obj).isEmpty();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (obj instanceof Collection<?>) {
|
|
||||||
if (obj == null || ((Collection<?>) obj).size() == 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (obj == null) {
|
return obj instanceof Map && ((Map<?, ?>) obj).isEmpty();
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,12 +79,12 @@ public final class StrUtil {
|
|||||||
} else if (length < 1) {
|
} else if (length < 1) {
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < length / 32; i++) {
|
for (int i = 0; i < length / 32; i++) {
|
||||||
sb.append(genUUID());
|
sb.append(genUUID());
|
||||||
}
|
}
|
||||||
if (length % 32 > 0) {
|
if (length % 32 > 0) {
|
||||||
sb.append(genUUID().substring(0, length % 32));
|
sb.append(genUUID(), 0, length % 32);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@ -101,48 +100,14 @@ public final class StrUtil {
|
|||||||
*/
|
*/
|
||||||
public static String genNum() {
|
public static String genNum() {
|
||||||
int hashCode = UUID.randomUUID().toString().hashCode();
|
int hashCode = UUID.randomUUID().toString().hashCode();
|
||||||
StringBuffer num = new StringBuffer();
|
StringBuilder num = new StringBuilder();
|
||||||
if (hashCode < 0) {
|
if (hashCode < 0) {
|
||||||
hashCode = 0 - hashCode;
|
hashCode = -hashCode;
|
||||||
num.append("0");
|
num.append("0");
|
||||||
} else {
|
} else {
|
||||||
num.append("1");
|
num.append("1");
|
||||||
}
|
}
|
||||||
return num.append(String.format("%010d", hashCode)).toString().substring(0, 8);
|
return num.append(String.format("%010d", hashCode)).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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,15 +117,15 @@ public final class StrUtil {
|
|||||||
* @return 转换后字符串
|
* @return 转换后字符串
|
||||||
*/
|
*/
|
||||||
public static String toHex(byte[] buf) {
|
public static String toHex(byte[] buf) {
|
||||||
StringBuffer strbuf = new StringBuffer(buf.length * 2);
|
StringBuilder sb = new StringBuilder(buf.length * 2);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < buf.length; i++) {
|
for (i = 0; i < buf.length; i++) {
|
||||||
if (((int) buf[i] & 0xff) < 0x10) {
|
if (((int) buf[i] & 0xff) < 0x10) {
|
||||||
strbuf.append("0");
|
sb.append("0");
|
||||||
}
|
}
|
||||||
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
|
sb.append(Long.toString((int) buf[i] & 0xff, 16));
|
||||||
}
|
}
|
||||||
return strbuf.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -227,11 +192,7 @@ public final class StrUtil {
|
|||||||
*/
|
*/
|
||||||
public static String iso2utf(String str) {
|
public static String iso2utf(String str) {
|
||||||
String utfStr = null;
|
String utfStr = null;
|
||||||
try {
|
utfStr = new String(str.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
|
||||||
utfStr = new String(str.getBytes("ISO-8859-1"), "utf-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return utfStr;
|
return utfStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,21 +202,18 @@ public final class StrUtil {
|
|||||||
* @param str
|
* @param str
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static Pattern pattern = Pattern.compile("[0-9]*");
|
private static final Pattern pattern = Pattern.compile("[0-9]*");
|
||||||
|
|
||||||
public static boolean isNumeric(String str) {
|
public static boolean isNumeric(String str) {
|
||||||
Matcher isNum = pattern.matcher(str);
|
Matcher isNum = pattern.matcher(str);
|
||||||
if (!isNum.matches()) {
|
return isNum.matches();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对ID(32位)进行编码
|
* 对ID(32位)进行编码
|
||||||
*
|
*
|
||||||
* @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) {
|
||||||
@ -267,7 +225,7 @@ public final class StrUtil {
|
|||||||
for (int i = 0; i < 13; i++) {
|
for (int i = 0; i < 13; i++) {
|
||||||
coded.append(HEX_CHAR[random.nextInt(16)]);
|
coded.append(HEX_CHAR[random.nextInt(16)]);
|
||||||
}
|
}
|
||||||
coded.append(id.substring(0, 11));
|
coded.append(id, 0, 11);
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
coded.append(HEX_CHAR[random.nextInt(16)]);
|
coded.append(HEX_CHAR[random.nextInt(16)]);
|
||||||
}
|
}
|
||||||
@ -282,8 +240,8 @@ public final class StrUtil {
|
|||||||
/**
|
/**
|
||||||
* 对ID(32位)进行解码
|
* 对ID(32位)进行解码
|
||||||
*
|
*
|
||||||
* @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) {
|
||||||
@ -291,12 +249,46 @@ public final class StrUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder id = new StringBuilder();
|
StringBuilder id = new StringBuilder();
|
||||||
id.append(coded.substring(13, 24));
|
id.append(coded, 13, 24);
|
||||||
id.append(coded.substring(31, 52));
|
id.append(coded, 31, 52);
|
||||||
|
|
||||||
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<>(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
|
||||||
*
|
*
|
||||||
@ -304,16 +296,15 @@ public final class StrUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String getSignContent(Map<String, ?> sortedParams) {
|
public static String getSignContent(Map<String, ?> sortedParams) {
|
||||||
StringBuffer content = new StringBuffer();
|
StringBuilder content = new StringBuilder();
|
||||||
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
||||||
Collections.sort(keys);
|
Collections.sort(keys);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (int i = 0; i < keys.size(); ++i) {
|
for (String key : keys) {
|
||||||
String key = keys.get(i);
|
|
||||||
Object value = sortedParams.get(key);
|
Object value = sortedParams.get(key);
|
||||||
if (isNotEmpty(key) && isNotEmpty(value)) {
|
if (isNotEmpty(key) && isNotEmpty(value)) {
|
||||||
content.append((index == 0 ? "" : "&") + key + "=" + value);
|
content.append(index == 0 ? "" : "&").append(key).append("=").append(value);
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,8 +335,7 @@ public final class StrUtil {
|
|||||||
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
||||||
Collections.sort(keys);
|
Collections.sort(keys);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < keys.size(); ++i) {
|
for (String key : keys) {
|
||||||
String key = keys.get(i);
|
|
||||||
Object value = sortedParams.get(key);
|
Object value = sortedParams.get(key);
|
||||||
map.put(key, value);
|
map.put(key, value);
|
||||||
++index;
|
++index;
|
||||||
@ -370,7 +360,7 @@ public final class StrUtil {
|
|||||||
/**
|
/**
|
||||||
* 下划线字符
|
* 下划线字符
|
||||||
*/
|
*/
|
||||||
public static final char UNDERLINE = '_';
|
private static final char UNDERLINE = '_';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串下划线转驼峰格式
|
* 字符串下划线转驼峰格式
|
||||||
@ -419,4 +409,68 @@ 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 "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,15 @@ package com.yexuejc.base.util;
|
|||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统工具类
|
* 系统工具类
|
||||||
@ -14,6 +22,7 @@ import java.util.concurrent.*;
|
|||||||
* @date: 2017/12/28 16:12
|
* @date: 2017/12/28 16:12
|
||||||
*/
|
*/
|
||||||
public class SysUtil {
|
public class SysUtil {
|
||||||
|
private static final Logger logger = Logger.getLogger(SysUtil.class.getName());
|
||||||
private static final String PROJECT_ROOT_PATH = "java.io.tmpdir";
|
private static final String PROJECT_ROOT_PATH = "java.io.tmpdir";
|
||||||
|
|
||||||
private SysUtil() {
|
private SysUtil() {
|
||||||
@ -34,8 +43,8 @@ public class SysUtil {
|
|||||||
* @param clazz
|
* @param clazz
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static URL getRootPath(Class clazz, String filePath) {
|
public static URL getRootPath(Class<?> clazz, String filePath) {
|
||||||
return clazz.getClass().getResource(StrUtil.setStr(filePath, "/"));
|
return clazz.getResource(StrUtil.setStr(filePath, "/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,9 +73,7 @@ public class SysUtil {
|
|||||||
0L, TimeUnit.MILLISECONDS,
|
0L, TimeUnit.MILLISECONDS,
|
||||||
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
|
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
|
||||||
|
|
||||||
singleThreadPool.execute(() -> {
|
singleThreadPool.execute(threadRun::execute);
|
||||||
threadRun.execute();
|
|
||||||
});
|
|
||||||
singleThreadPool.shutdown();
|
singleThreadPool.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,4 +86,116 @@ public class SysUtil {
|
|||||||
*/
|
*/
|
||||||
void execute();
|
void execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前JVM所有线程
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Thread> getThreadList() {
|
||||||
|
List<Thread> threadList = new ArrayList<>();
|
||||||
|
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
|
||||||
|
while (currentGroup.getParent() != null) {
|
||||||
|
currentGroup = currentGroup.getParent();
|
||||||
|
}
|
||||||
|
int activeCount = currentGroup.activeCount();
|
||||||
|
Thread[] threads = new Thread[activeCount];
|
||||||
|
currentGroup.enumerate(threads);
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
threadList.add(thread);
|
||||||
|
}
|
||||||
|
return threadList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 线程锁 */
|
||||||
|
private static final Lock THREAD_LOCK = new ReentrantLock();
|
||||||
|
/** 已经等待的时间 */
|
||||||
|
private static final AtomicInteger SLEEP_TIME = new AtomicInteger(0);
|
||||||
|
/** 最大等待3分钟 */
|
||||||
|
private static final int MAX_SLEEP_TIME = 180;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过锁的方式判断jvm的内存,如果超80%就等待(最大3分钟)JVM内存降低到80%再执行
|
||||||
|
*/
|
||||||
|
public static void checkJvmMemory() {
|
||||||
|
THREAD_LOCK.lock();
|
||||||
|
try {
|
||||||
|
while (jvmMemoryIsNotExecutable()) {
|
||||||
|
//jvm内存使用率达到80%,阻塞所有线程,最大等待3分钟后放开
|
||||||
|
if (SLEEP_TIME.incrementAndGet() < MAX_SLEEP_TIME) {
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
} finally {
|
||||||
|
THREAD_LOCK.unlock();
|
||||||
|
SLEEP_TIME.set(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jvm内存是否大于80%(不能继续执行)
|
||||||
|
*
|
||||||
|
* @return true:是,false:不是
|
||||||
|
*/
|
||||||
|
public static boolean jvmMemoryIsNotExecutable() {
|
||||||
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
//jvm总内存
|
||||||
|
long jvmTotalMemoryByte = runtime.totalMemory();
|
||||||
|
//jvm最大可申请
|
||||||
|
long jvmMaxMemoryByte = runtime.maxMemory();
|
||||||
|
//空闲空间
|
||||||
|
long freeMemoryByte = runtime.freeMemory();
|
||||||
|
|
||||||
|
double rate = (jvmTotalMemoryByte - freeMemoryByte) * 1.0 / jvmTotalMemoryByte;
|
||||||
|
if (rate >= 0.8) {
|
||||||
|
rate = (jvmTotalMemoryByte - freeMemoryByte) * 1.0 / jvmMaxMemoryByte;
|
||||||
|
if (rate >= 0.8) {
|
||||||
|
//jvm内存使用率达到80%
|
||||||
|
print(jvmTotalMemoryByte, jvmMaxMemoryByte, freeMemoryByte);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final DecimalFormat RATE_DECIMAL_FORMAT = new DecimalFormat("#.##%");
|
||||||
|
|
||||||
|
private static void print(long jvmTotalMemoryByte, long jvmMaxMemoryByte, long freeMemoryByte) {
|
||||||
|
if (logger.isLoggable(Level.WARNING)) {
|
||||||
|
String sb = "\n=========================================================" +
|
||||||
|
"\nThread Name = " + Thread.currentThread().getName() +
|
||||||
|
"\nJVM Memory = " + formatByte(jvmTotalMemoryByte) +
|
||||||
|
"\nJVM Max Memory = " + formatByte(jvmMaxMemoryByte) +
|
||||||
|
"\nJVM Used Memory = " + formatByte(jvmTotalMemoryByte - freeMemoryByte) +
|
||||||
|
"\nJVM Free Memory = " + formatByte(freeMemoryByte) +
|
||||||
|
"\nJVM Memory Rate = " + RATE_DECIMAL_FORMAT.format((jvmTotalMemoryByte - freeMemoryByte) * 1.0 / jvmTotalMemoryByte) +
|
||||||
|
"\n=========================================================";
|
||||||
|
logger.warning(sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatByte(long byteNumber) {
|
||||||
|
//换算单位
|
||||||
|
double format = 1024.0;
|
||||||
|
double kbNumber = byteNumber / format;
|
||||||
|
if (kbNumber < format) {
|
||||||
|
return new DecimalFormat("#.##KB").format(kbNumber);
|
||||||
|
}
|
||||||
|
double mbNumber = kbNumber / format;
|
||||||
|
if (mbNumber < format) {
|
||||||
|
return new DecimalFormat("#.##MB").format(mbNumber);
|
||||||
|
}
|
||||||
|
double gbNumber = mbNumber / format;
|
||||||
|
if (gbNumber < format) {
|
||||||
|
return new DecimalFormat("#.##GB").format(gbNumber);
|
||||||
|
}
|
||||||
|
double tbNumber = gbNumber / format;
|
||||||
|
return new DecimalFormat("#.##TB").format(tbNumber);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
72
src/test/java/com/yexuejc/base/util/FileUtilTest.java
Normal file
72
src/test/java/com/yexuejc/base/util/FileUtilTest.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.yexuejc.base.pojo.ReadFileBean;
|
||||||
|
import com.yexuejc.base.util.bean.AppnodeCertCsvBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author: yexuejc
|
||||||
|
* @date: 2024/4/8 11:33
|
||||||
|
*/
|
||||||
|
public class FileUtilTest {
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
readCsvFile();
|
||||||
|
// other();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void other() throws IOException {
|
||||||
|
System.out.println(FileUtil.getFileType("C:\\Users\\Administrator\\Desktop\\test.txt"));
|
||||||
|
boolean b = FileUtil.judeDirExists(new File("F:\\coding\\yexuejc-base2\\src\\test\\java\\com\\yexuejc\\base\\util\\test\\a"));
|
||||||
|
File file = new File("F:\\coding\\yexuejc-base2\\src\\test\\java\\com\\yexuejc\\base\\util\\test\\a\\test.txt");
|
||||||
|
FileUtil.judeFileExists(file);
|
||||||
|
System.out.println("创建文件夹:" + b);
|
||||||
|
System.out.println("SHA1:" + FileUtil.sha1(file));
|
||||||
|
//超大文件sha1
|
||||||
|
long l = System.currentTimeMillis();
|
||||||
|
System.out.println("SHA1:" + FileUtil.sha1(Paths.get("F:\\Docker\\win\\win10x64.iso").toFile()) + " 花费时间:" + (System.currentTimeMillis() - l));
|
||||||
|
|
||||||
|
System.out.println("MD5:" + FileUtil.md5(file));
|
||||||
|
//超大文件MD5
|
||||||
|
long l2 = System.currentTimeMillis();
|
||||||
|
System.out.println("MD5:" + FileUtil.md5(Paths.get("F:\\Docker\\win\\win10x64.iso").toFile()) + " 花费时间:" + (System.currentTimeMillis() - l2));
|
||||||
|
//超大文件MD5
|
||||||
|
long l3 = System.currentTimeMillis();
|
||||||
|
System.out.println("CRC32:" + FileUtil.crc32(Paths.get("F:\\Docker\\win\\win10x64.iso").toFile()) + " 花费时间:" + (System.currentTimeMillis() - l3));
|
||||||
|
|
||||||
|
String base64ToStr = FileUtil.base64ToStr(file);
|
||||||
|
System.out.println(base64ToStr);
|
||||||
|
String fileName = "F:\\coding\\yexuejc-base2\\src\\test\\java\\com\\yexuejc\\base\\util\\test\\a\\test2.txt";
|
||||||
|
System.out.println(FileUtil.base64ToFile(base64ToStr, fileName));
|
||||||
|
File file2 = Paths.get(fileName).toFile();
|
||||||
|
System.out.println("SHA1:" + FileUtil.sha1(file2));
|
||||||
|
System.out.println("MD5:" + FileUtil.md5(file2));
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(FileUtil.size(file2.toPath()));
|
||||||
|
long l4 = System.currentTimeMillis();
|
||||||
|
System.out.println(FileUtil.size(Paths.get("F:\\Docker\\win\\win10x64.iso")) + " 花费时间:" + (System.currentTimeMillis() - l4));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readCsvFile() throws IOException {
|
||||||
|
String path = "F:\\coding\\yexuejc-base2\\src\\test\\java\\com\\yexuejc\\base\\util\\test.csv";
|
||||||
|
|
||||||
|
List<AppnodeCertCsvBean> list = FileUtil.readCsv(path, AppnodeCertCsvBean.class, true, "enable,domain,protocol,deployHost,deployPath,uname,pwd,appnodeId", ',');
|
||||||
|
System.out.println("***********************************************");
|
||||||
|
System.out.println(JsonUtil.formatPrinter(list));
|
||||||
|
System.out.println("条数:" + list.size());
|
||||||
|
|
||||||
|
ReadFileBean<AppnodeCertCsvBean> readFileBean = new ReadFileBean<>(2);
|
||||||
|
do {
|
||||||
|
ReadFileBean<AppnodeCertCsvBean> bean = FileUtil.readBigFile(path, readFileBean, AppnodeCertCsvBean.class);
|
||||||
|
System.out.println("============================================");
|
||||||
|
System.out.println(JsonUtil.formatPrinter(bean));
|
||||||
|
} while (readFileBean.hasNext());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
24
src/test/java/com/yexuejc/base/util/SysUtilTest.java
Normal file
24
src/test/java/com/yexuejc/base/util/SysUtilTest.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.yexuejc.base.util;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author: yexuejc
|
||||||
|
* @date: 2024/4/8 11:22
|
||||||
|
*/
|
||||||
|
public class SysUtilTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(SysUtil.getCachePath());
|
||||||
|
System.out.println(SysUtil.getRootPath(SysUtilTest.class, null));
|
||||||
|
SysUtil.threadRun("test", () -> {
|
||||||
|
String threadName = Thread.currentThread().getName();
|
||||||
|
System.out.println("当前线程的名称是:" + threadName);
|
||||||
|
});
|
||||||
|
SysUtil.getThreadList().forEach(t -> {
|
||||||
|
System.out.println("线程名称:" + t.getName());
|
||||||
|
});
|
||||||
|
SysUtil.checkJvmMemory();
|
||||||
|
System.out.println(SysUtil.jvmMemoryIsNotExecutable());
|
||||||
|
}
|
||||||
|
}
|
104
src/test/java/com/yexuejc/base/util/bean/AppnodeCertCsvBean.java
Normal file
104
src/test/java/com/yexuejc/base/util/bean/AppnodeCertCsvBean.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package com.yexuejc.base.util.bean;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.yexuejc.base.annotation.CsvToBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author: yexuejc
|
||||||
|
* @date: 2024/2/27 10:40
|
||||||
|
*/
|
||||||
|
public class AppnodeCertCsvBean implements Serializable {
|
||||||
|
/**是否生效:Y/N*/
|
||||||
|
private String enable;
|
||||||
|
/**域名*/
|
||||||
|
private String domain;
|
||||||
|
/**
|
||||||
|
* 部署协议
|
||||||
|
* appnode
|
||||||
|
* ssh
|
||||||
|
* */
|
||||||
|
private String protocol;
|
||||||
|
/**
|
||||||
|
* 部署服务器
|
||||||
|
* 部署协议appnode: local 本机部署
|
||||||
|
* 部署协议appnode: 域名 部署的远程appnode域名
|
||||||
|
* 部署协议ssh : IP
|
||||||
|
* */
|
||||||
|
private String deployHost;
|
||||||
|
/**部署证书位置*/
|
||||||
|
private String deployPath;
|
||||||
|
/**服务器账号*/
|
||||||
|
private String uname;
|
||||||
|
/**服务器密码*/
|
||||||
|
private String pwd;
|
||||||
|
/**
|
||||||
|
* appnode协议时:且远程部署时,对应的远程appnode的ApiNodeId
|
||||||
|
*/
|
||||||
|
private Integer appnodeId;
|
||||||
|
|
||||||
|
public String getEnable() {
|
||||||
|
return enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnable(String enable) {
|
||||||
|
this.enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProtocol() {
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProtocol(String protocol) {
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeployHost() {
|
||||||
|
return deployHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeployHost(String deployHost) {
|
||||||
|
this.deployHost = deployHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeployPath() {
|
||||||
|
return deployPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeployPath(String deployPath) {
|
||||||
|
this.deployPath = deployPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUname() {
|
||||||
|
return uname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUname(String uname) {
|
||||||
|
this.uname = uname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPwd() {
|
||||||
|
return pwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPwd(String pwd) {
|
||||||
|
this.pwd = pwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAppnodeId() {
|
||||||
|
return appnodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppnodeId(Integer appnodeId) {
|
||||||
|
this.appnodeId = appnodeId;
|
||||||
|
}
|
||||||
|
}
|
10
src/test/java/com/yexuejc/base/util/test.csv
Normal file
10
src/test/java/com/yexuejc/base/util/test.csv
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
是否生效,域名,部署协议,部署服务器,部署证书位置,服务器账号,服务器密码,appnodeId
|
||||||
|
N,kasm.mx.yexuejc.top,appnode,http://192.168.56.101:8888,,admin,admin,1
|
||||||
|
N,kasm.mx.yexuejc.top,appnode,local,,,,
|
||||||
|
N,shop.mx.yexuejc.top,appnode,local,,,,
|
||||||
|
Y,cloud.yexuejc.top,ssh,118.126.109.109:10371,/home/frpuser/http/cert/,frpuser,yexuejc1,
|
||||||
|
Y,blog.yexuejc.top,ssh,118.126.109.109:10371,/home/frpuser/http/cert/,frpuser,yexuejc1,
|
||||||
|
Y,yexuejc.top,ssh,118.126.109.109:10371,/home/frpuser/http/cert/,frpuser,yexuejc1,
|
||||||
|
Y,jenkins.yexuejc.top,ssh,118.126.109.109:10371,/home/frpuser/http/cert/,frpuser,yexuejc1,
|
||||||
|
Y,git.yexuejc.top,ssh,118.126.109.109:10371,/home/frpuser/http/cert/,frpuser,yexuejc1,
|
||||||
|
Y,nexus.yexuejc.top,ssh,118.126.109.109:10371,/home/frpuser/http/cert/,frpuser,yexuejc1,
|
|
Loading…
x
Reference in New Issue
Block a user