mirror of
https://gitee.com/jzsw-it/yexuejc-base.git
synced 2025-11-19 01:37:45 +08:00
Compare commits
15 Commits
2031a3aadf
...
1.5.3-jre1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9c65f8866 | ||
|
|
f2c904869f | ||
|
|
b0fd28d208 | ||
|
|
982f3aa418 | ||
|
|
8b43d99e11 | ||
|
|
31040ad0e9 | ||
|
|
9f5ecefc43 | ||
|
|
beb72c8009 | ||
|
|
0403c7c693 | ||
|
|
cf8231017d | ||
|
|
1415200b1a | ||
|
|
0954eb64b5 | ||
|
|
70aad08b97 | ||
|
|
59f0e6e296 | ||
|
|
8e8f390b5d |
24
.gitea/workflows/package.yaml
Normal file
24
.gitea/workflows/package.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
name: yexuejc-base package jre11
|
||||
run-name: Deploy to ${{ inputs.deploy_target }} by @${{ github.actor }} 🚀
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- jre11
|
||||
|
||||
jobs:
|
||||
package_job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
||||
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||
- name: Check out repository code
|
||||
uses: advanced-security/maven-dependency-submission-action@v4
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ gitea.workspace }}
|
||||
mvn -v
|
||||
mvn clean package
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
14
UPDATE.md
14
UPDATE.md
@@ -1,13 +1,25 @@
|
||||
yexuejc-base 更新记录
|
||||
------------------
|
||||
|
||||
#### version :1.5.3-jre11
|
||||
**time: 2025-4-27 16:37:29** <br/>
|
||||
**branch:** jre11 <br/>
|
||||
**update:** <br/>
|
||||
1. [FileUtil](src/main/java/com/yexuejc/base/util/FileUtil.java) 增加读取大文件自定义方法和单纯读取方法
|
||||
2. [JsonUtil](src/main/java/com/yexuejc/base/util/JsonUtil.java) 增加objToMap;优化obj2Json
|
||||
3. [DateUtil](src/main/java/com/yexuejc/base/util/DateUtil.java) 标准化日期时间的转换函数
|
||||
4. [AES](src/main/java/com/yexuejc/base/encrypt/AES.java) 兼容ECB(虽然不再建议利用)
|
||||
5. [StrUtil](src/main/java/com/yexuejc/base/util/StrUtil.java) 增加国家代码二进制相互转换
|
||||
---
|
||||
|
||||
#### version :1.5.2-jre11
|
||||
**time:2024-4-7 14:34:33** <br/>
|
||||
**branch:** jre11 <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)
|
||||
---
|
||||
|
||||
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>1.5.2-jre11</version>
|
||||
<version>1.5.3-jre11</version>
|
||||
|
||||
<name>yexuejc-base</name>
|
||||
<url>https://github.com/yexuejc/yexuejc-base</url>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package com.yexuejc.base.annotation;
|
||||
|
||||
import java.lang.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
|
||||
|
||||
@@ -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.deser.std.StdScalarDeserializer;
|
||||
|
||||
/**
|
||||
* 反序列化中内容为空时,返回Integer为空
|
||||
* <p>使用方式:@JsonDeserialize(using = IntegerNullValueDeserializer.class)</p>
|
||||
* @author: yexuejc
|
||||
* @date: 2024/4/15 18:08
|
||||
*/
|
||||
public class IntegerNullValueDeserializer extends StdScalarDeserializer<Integer> {
|
||||
public IntegerNullValueDeserializer() {
|
||||
super(Integer.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
String value = p.getValueAsString();
|
||||
if (isInteger(value)) {
|
||||
return super._parseInteger(p, ctxt, Integer.class);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInteger(String s) {
|
||||
try {
|
||||
Integer.parseInt(s);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* json转LocalDate
|
||||
*
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.yexuejc.base.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
/**
|
||||
* localDate转json
|
||||
*
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* json转LocalDateTime
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
|
||||
@Override
|
||||
public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator,
|
||||
SerializerProvider serializerProvider) throws IOException {
|
||||
SerializerProvider serializerProvider) throws IOException {
|
||||
jsonGenerator.writeString(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* json中的“”转String对象时值为null
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package com.yexuejc.base.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.yexuejc.base.constant.DateConsts;
|
||||
import com.yexuejc.base.util.StrUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
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
|
||||
*
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* Timestamp转json
|
||||
*
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.yexuejc.base.encrypt;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* AES加解密
|
||||
@@ -35,32 +35,50 @@ public class AES {
|
||||
AES_CBC_NoPadding("AES/CBC/NoPadding"),
|
||||
//AES/CBC/PKCS5Padding 32 16
|
||||
AES_CBC_PKCS5Padding("AES/CBC/PKCS5Padding"),
|
||||
//AES/CBC/PKCS7Padding 32 16
|
||||
AES_CBC_PKCS7Padding("AES/CBC/PKCS7Padding"),
|
||||
//AES/CBC/ISO10126Padding 32 16
|
||||
AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"),
|
||||
//AES/CBC/ZeroPadding 16 16
|
||||
AES_CBC_ZeroPadding("AES/CBC/ZeroPadding"),
|
||||
//AES/CFB/NoPadding 16 原始数据长度
|
||||
AES_CFB_NoPadding("AES/CFB/NoPadding"),
|
||||
//AES/CFB/PKCS5Padding 32 16
|
||||
//AES/CFB/PKCS5Padding 16 不支持
|
||||
AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"),
|
||||
//AES/CFB/ISO10126Padding 32 16
|
||||
//AES/CFB/PKCS7Padding 16 不支持
|
||||
AES_CFB_PKCS7Padding("AES/CFB/PKCS7Padding"),
|
||||
//AES/CFB/ISO10126Padding 16 不支持
|
||||
AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"),
|
||||
//AES/CFB/ZeroPadding 16 不支持
|
||||
AES_CFB_ZeroPadding("AES/CFB/ZeroPadding"),
|
||||
//AES/ECB/NoPadding 16 不支持
|
||||
AES_ECB_NoPadding("AES/ECB/NoPadding"),
|
||||
//AES/ECB/PKCS5Padding 32 16
|
||||
//AES/ECB/PKCS5Padding 32 不支持
|
||||
AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"),
|
||||
//AES/ECB/PKCS7Padding 32 16
|
||||
AES_ECB_PKCS7Padding("AES/ECB/PKCS7Padding"),
|
||||
//AES/ECB/ISO10126Padding 32 16
|
||||
AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"),
|
||||
//AES/ECB/ZeroPadding 16 16
|
||||
AES_ECB_ZeroPadding("AES/ECB/ZeroPadding"),
|
||||
//AES/OFB/NoPadding 16 原始数据长度
|
||||
AES_OFB_NoPadding("AES/OFB/NoPadding"),
|
||||
//AES/OFB/PKCS5Padding 32 16
|
||||
AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"),
|
||||
//AES/OFB/PKCS7Padding 32 16
|
||||
AES_OFB_PKCS7Padding("AES/OFB/PKCS7Padding"),
|
||||
//AES/OFB/ISO10126Padding 32 16
|
||||
AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"),
|
||||
//AES/OFB/ZeroPadding 16 16
|
||||
AES_OFB_ZeroPadding("AES/OFB/ZeroPadding"),
|
||||
//AES/PCBC/NoPadding 16 不支持
|
||||
AES_PCBC_NoPadding("AES/PCBC/NoPadding"),
|
||||
//AES/PCBC/PKCS5Padding 32 16
|
||||
AES_PCBC_PKCS5Padding("AES/PCBC/PKCS5Padding"),
|
||||
//AES/PCBC/ISO10126Padding 32 16
|
||||
AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding");
|
||||
AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding"),
|
||||
//AES/CTR/NoPadding 16 不支持
|
||||
AES_CTR_NoPadding("AES/CTR/NoPadding");
|
||||
public String name;
|
||||
|
||||
ALGORITHM(String name) {
|
||||
@@ -93,7 +111,10 @@ public class AES {
|
||||
byte[] plaintext = new byte[plaintextLength];
|
||||
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset));
|
||||
IvParameterSpec ivspec = null;
|
||||
if(!algorithm.name.contains("ECB")){
|
||||
ivspec = new IvParameterSpec(iv.getBytes(charset));
|
||||
}
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
|
||||
byte[] encrypted = cipher.doFinal(plaintext);
|
||||
return Base64.getEncoder().encodeToString(encrypted);
|
||||
@@ -115,7 +136,10 @@ public class AES {
|
||||
byte[] encrypted = Base64.getDecoder().decode(data);
|
||||
Cipher cipher = Cipher.getInstance(algorithm.name);
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes(charset));
|
||||
IvParameterSpec ivspec = null;
|
||||
if(!algorithm.name.contains("ECB")){
|
||||
ivspec = new IvParameterSpec(iv.getBytes(charset));
|
||||
}
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
byte[] original = cipher.doFinal(encrypted);
|
||||
return new String(original, charset).trim();
|
||||
|
||||
@@ -50,7 +50,7 @@ public class CsvToBean {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isHasHeader() {
|
||||
public boolean hasHeader() {
|
||||
return hasHeader;
|
||||
}
|
||||
|
||||
|
||||
@@ -448,6 +448,8 @@ public class DateTimeUtil {
|
||||
|
||||
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()));
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ public class DateUtil {
|
||||
/**
|
||||
* 比较两个日期大小
|
||||
*
|
||||
* @param date1
|
||||
* @param date2
|
||||
* @param date1 格式 yyyy-MM-dd
|
||||
* @param date2 格式 yyyy-MM-dd
|
||||
* @return date1>date2返回1;date1=date2返回0;date1<date2返回-1
|
||||
* @throws ParseException
|
||||
*/
|
||||
@@ -80,57 +80,122 @@ public class DateUtil {
|
||||
/**
|
||||
* 日期字符串转date
|
||||
*
|
||||
* @param dateStr
|
||||
* @return Date
|
||||
* @param dateStr 格式:yyyy-MM-dd
|
||||
* @return Date 日期
|
||||
* @throws ParseException
|
||||
* @deprecated 替代参考 {@link #parseDate(String, String)}
|
||||
* @see 1.5.2
|
||||
*/
|
||||
@Deprecated
|
||||
public static Date str2date(String dateStr) throws ParseException {
|
||||
Date date = DATE_FORMAT.parse(dateStr);
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* date转字符串
|
||||
*
|
||||
* @param date
|
||||
* @return Date
|
||||
* @throws ParseException
|
||||
* @param date 日期
|
||||
* @return String 格式 yyyy-MM-dd
|
||||
* @deprecated 替代参考 {@link #formatDate(Date, String)} 或 {@link #formatDate(Date, String, Locale)}
|
||||
* @see 1.5.2
|
||||
*/
|
||||
public static String date2str(Date date) throws ParseException {
|
||||
@Deprecated
|
||||
public static String date2str(Date date) {
|
||||
if (date != null) {
|
||||
return DATE_FORMAT.format(date);
|
||||
} else {
|
||||
return "null";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 日期字符串转dateTime
|
||||
*
|
||||
* @param dateStr
|
||||
* @return
|
||||
* @param dateStr 格式:yyyy-MM-dd HH:mm:ss.SSS
|
||||
* @return Date 时间
|
||||
* @throws ParseException
|
||||
* @deprecated 替代参考 {@link #parseDate(String, String)}
|
||||
* @see 1.5.2
|
||||
*/
|
||||
@Deprecated
|
||||
public static Date str2dateTime(String dateStr) throws ParseException {
|
||||
Date date = DATE_TIME_FORMAT.parse(dateStr);
|
||||
return date;
|
||||
return DATE_TIME_FORMAT.parse(dateStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* dateTime转字符串
|
||||
*
|
||||
* @param date
|
||||
* @return Date
|
||||
* @throws ParseException
|
||||
* @param date 时间
|
||||
* @return String 格式:yyyy-MM-dd HH:mm:ss.SSS
|
||||
* @deprecated 替代参考 {@link #formatDate(Date, String)} 或 {@link #formatDate(Date, String, Locale)}
|
||||
* @see 1.5.2
|
||||
*/
|
||||
public static String dateTime2str(Date date) throws ParseException {
|
||||
@Deprecated
|
||||
public static String dateTime2str(Date date) {
|
||||
if (date != null) {
|
||||
return DATE_TIME_FORMAT.format(date);
|
||||
} else {
|
||||
return "null";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化当前日期为指定格式的字符串。
|
||||
*
|
||||
* @param dateFormat 日期格式字符串,用于指定日期的输出格式,例如"yyyy-MM-dd HH:mm:ss"。
|
||||
* @return 格式化后的当前日期字符串。
|
||||
*/
|
||||
public static String formatDateNow(String dateFormat) {
|
||||
return formatDate(new Date(), dateFormat); // 使用系统当前时间生成日期对象,并按指定格式进行格式化。
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字符串形式的日期到Date对象。
|
||||
*
|
||||
* @param dateStr 待解析的日期字符串。
|
||||
* @param dateFormat 日期字符串的格式。
|
||||
* @return 返回解析后的Date对象,如果解析失败则返回null。
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Date parseDate(String dateStr, String dateFormat) throws ParseException {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
// 尝试根据给定的日期格式解析日期字符串
|
||||
return sdf.parse(dateStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定的日期格式和地域格式化日期对象为字符串。
|
||||
* 如果未指定地域,则默认使用中文地域格式。
|
||||
*
|
||||
* @param date 需要格式化的日期对象。
|
||||
* @param dateFormat 日期格式字符串,例如"yyyy-MM-dd"。
|
||||
* @return 格式化后的日期字符串。
|
||||
*/
|
||||
public static String formatDate(Date date, String dateFormat) {
|
||||
return formatDate(date, dateFormat, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定的日期格式、地域格式化日期对象为字符串。
|
||||
*
|
||||
* @param date 需要格式化的日期对象。
|
||||
* @param dateFormat 日期格式字符串,例如"yyyy-MM-dd"。
|
||||
* @param locale 地域设置,如果为null则默认使用中文地域。
|
||||
* @return 格式化后的日期字符串。
|
||||
*/
|
||||
public static String formatDate(Date date, String dateFormat, Locale locale) {
|
||||
SimpleDateFormat sdf;
|
||||
// 根据是否提供了地域参数来创建SimpleDateFormat实例
|
||||
if (StrUtil.isEmpty(locale)) {
|
||||
sdf = new SimpleDateFormat(dateFormat, Locale.CHINA);
|
||||
} else {
|
||||
sdf = new SimpleDateFormat(dateFormat, locale);
|
||||
}
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本周的日期
|
||||
@@ -232,4 +297,19 @@ public class DateUtil {
|
||||
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"));
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -6,17 +6,20 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.MappedByteBuffer;
|
||||
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.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
@@ -36,11 +39,14 @@ import io.jsonwebtoken.lang.Assert;
|
||||
* @time 2017年11月3日 下午3:12:49
|
||||
*/
|
||||
public class FileUtil {
|
||||
static Logger logger = Logger.getLogger(FileUtil.class.getName());
|
||||
private static final Logger logger = Logger.getLogger(FileUtil.class.getName());
|
||||
|
||||
public FileUtil() {
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
|
||||
private static final String NEW_LINE = "\n";
|
||||
private static final String CONSTANT_DOT = ".";
|
||||
private static final String TYPE_TAR_GZ = ".tar.gz";
|
||||
private static final String TYPE_CSV = ".csv";
|
||||
private static final String TAR_GZ = "tar.gz";
|
||||
@@ -59,32 +65,48 @@ public class FileUtil {
|
||||
if (fileName.lastIndexOf(TYPE_TAR_GZ) > 0) {
|
||||
return TAR_GZ;
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
return fileName.substring(fileName.lastIndexOf(CONSTANT_DOT) + 1);
|
||||
} catch (Exception e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
}
|
||||
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
|
||||
*/
|
||||
public static void judeFileExists(File file) {
|
||||
|
||||
if (file.exists()) {
|
||||
logger.severe("file exists");
|
||||
} else {
|
||||
logger.info("file not exists, create it ...");
|
||||
try {
|
||||
file.createNewFile();
|
||||
boolean b = file.createNewFile();
|
||||
if (b) {
|
||||
logger.info("file create success");
|
||||
} else {
|
||||
logger.severe("file create fail");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe("file create fail");
|
||||
e.printStackTrace();
|
||||
logger.log(Level.WARNING, "file create fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,72 +143,9 @@ public class FileUtil {
|
||||
* @return
|
||||
*/
|
||||
public static String sha1(File file) {
|
||||
FileInputStream in = null;
|
||||
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;
|
||||
return getDigest(file, "SHA-1");
|
||||
}
|
||||
|
||||
/***
|
||||
* 计算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
|
||||
@@ -195,66 +154,40 @@ public class FileUtil {
|
||||
* @return
|
||||
*/
|
||||
public static String md5(File file) {
|
||||
FileInputStream in = null;
|
||||
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;
|
||||
return getDigest(file, "MD5");
|
||||
}
|
||||
|
||||
/**
|
||||
* 对一个文件获取md5值
|
||||
*
|
||||
* @return md5串
|
||||
* @throws NoSuchAlgorithmException
|
||||
* 获取文件的散列值
|
||||
* @param file
|
||||
* @param digestCode
|
||||
* @return
|
||||
*/
|
||||
public static String md5ByBigFile(File file) {
|
||||
|
||||
MessageDigest messagedigest = null;
|
||||
try {
|
||||
messagedigest = MessageDigest.getInstance("MD5");
|
||||
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());
|
||||
private static String getDigest(File file, String digestCode) {
|
||||
try (FileInputStream in = new FileInputStream(file)) {
|
||||
MessageDigest digest = MessageDigest.getInstance(digestCode);
|
||||
FileChannel channel = in.getChannel();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); // 1MB 缓冲区
|
||||
// 读取文件内容并更新 MessageDigest
|
||||
while (channel.read(buffer) != -1) {
|
||||
buffer.flip(); // 将 Buffer 从写模式切换到读模式
|
||||
digest.update(buffer); // 更新 MessageDigest
|
||||
buffer.clear(); // 清空 Buffer
|
||||
}
|
||||
// 计算最终的 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) {
|
||||
logger.severe("system algorithm error.");
|
||||
e.printStackTrace();
|
||||
logger.log(Level.SEVERE, "system algorithm error.", e);
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
e.printStackTrace();
|
||||
logger.log(Level.SEVERE, "file doesn't exist or is not a file", e);
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
logger.log(Level.SEVERE, "The operation file is an IO exception.", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -262,37 +195,24 @@ public class FileUtil {
|
||||
/**
|
||||
* 获取文件CRC32码
|
||||
*
|
||||
* @return String
|
||||
* @return 获取失败返回-1
|
||||
*/
|
||||
public static String crc32(File file) {
|
||||
public static long crc32(File file) {
|
||||
CRC32 crc32 = new CRC32();
|
||||
// MessageDigest.get
|
||||
FileInputStream fileInputStream = null;
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
byte[] buffer = new byte[8192];
|
||||
try (FileInputStream fileInputStream = new FileInputStream(file);) {
|
||||
byte[] buffer = new byte[1024 * 1024];
|
||||
int length;
|
||||
while ((length = fileInputStream.read(buffer)) != -1) {
|
||||
crc32.update(buffer, 0, length);
|
||||
}
|
||||
return crc32.getValue() + "";
|
||||
return crc32.getValue();
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
logger.log(Level.SEVERE, "file doesn't exist or is not a file", e);
|
||||
return -1;
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (fileInputStream != null) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe("close FileInputStream IO exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.log(Level.SEVERE, "The operation file is an IO exception.", e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +224,7 @@ public class FileUtil {
|
||||
*/
|
||||
public static String base64ToStr(File file) {
|
||||
try {
|
||||
byte[] bytes = Files.readAllBytes(Path.of(file.getPath()));
|
||||
byte[] bytes = Files.readAllBytes(Paths.get(file.getPath()));
|
||||
return Base64.getEncoder().encodeToString(bytes);
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
@@ -320,10 +240,10 @@ public class FileUtil {
|
||||
* </i>
|
||||
*
|
||||
* @param decode {@link FileUtil#base64ToStr(File)} 的结果
|
||||
* @param fileName 保存文件名称(包含路径)
|
||||
* @param fileName 文件名称(包含路径)
|
||||
* @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);
|
||||
}
|
||||
|
||||
@@ -331,29 +251,16 @@ public class FileUtil {
|
||||
* base64转文件
|
||||
* <p>
|
||||
* <i>
|
||||
* 文件转base64请使用 {@link FileUtil#base64ToStr(File)}
|
||||
* 文件转base64请使用 {@link FileUtil#base64ToStr(File)}}
|
||||
* </i>
|
||||
*
|
||||
* @param decode baseByte
|
||||
* @param fileName 文件名称(包含路径)
|
||||
* @return 返回保存地址
|
||||
*/
|
||||
public static String base64ToFile(byte[] decode, String fileName) {
|
||||
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(fileName);
|
||||
public static String base64ToFile(byte[] decode, String fileName) throws IOException {
|
||||
try (FileOutputStream out = new FileOutputStream(fileName)) {
|
||||
out.write(decode);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
@@ -361,50 +268,18 @@ public class FileUtil {
|
||||
/**
|
||||
* 获取文件大小 :直接返回大小
|
||||
*
|
||||
* @param f
|
||||
* @param path 文件地址
|
||||
* @return f.length()
|
||||
*/
|
||||
public static long size(File f) {
|
||||
if (f.exists() && f.isFile()) {
|
||||
return f.length();
|
||||
public static long size(Path path) throws IOException {
|
||||
if (Files.exists(path) && Files.isRegularFile(path)) {
|
||||
return Files.size(path);
|
||||
} else {
|
||||
logger.info("file doesn't exist or is not a file");
|
||||
}
|
||||
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格式)转 对象
|
||||
*
|
||||
@@ -431,14 +306,15 @@ public class FileUtil {
|
||||
*
|
||||
* @param csvFilePath 文件地址
|
||||
* @param cls 读取转化的对象
|
||||
* @param hasHeader 是否存在header
|
||||
* @param header 解析列对应的java字段;用delimiter分割
|
||||
* @param hasHeader csv文件中第一行是否是header
|
||||
* @param delimiter 分隔符.默认【,】
|
||||
* @param <I>
|
||||
* @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)) {
|
||||
throw new RuntimeException(String.format("解析用的csv:\u0020[%s] 文件不存在。", csvFilePath));
|
||||
throw new RuntimeException(String.format("解析用的csv: [%s] 文件不存在。", csvFilePath));
|
||||
}
|
||||
if (StrUtil.isEmpty(delimiter)) {
|
||||
delimiter = ',';
|
||||
@@ -446,7 +322,12 @@ public class FileUtil {
|
||||
try {
|
||||
File csvFile = new File(csvFilePath);
|
||||
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);
|
||||
return recordIterator.readAll();
|
||||
} catch (IOException e) {
|
||||
@@ -455,81 +336,90 @@ 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 filePath 文件路径
|
||||
* @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数
|
||||
* @param <T> 读取结果类型bean
|
||||
* @return
|
||||
* @return 文件分页读取内容(自定义处理后)及读取信息
|
||||
*/
|
||||
public <T> ReadFileBean<T> readBigFile(String path, ReadFileBean<T> readFileBean, Class<T> readCls) throws FileNotFoundException {
|
||||
File file = new File(path);
|
||||
if (!file.exists() || file.isDirectory()) {
|
||||
throw new FileNotFoundException("file:" + path + " is not found.");
|
||||
public static <T> ReadFileBean<T> readBigFile(String filePath, ReadFileBean<T> readFileBean, Function<List<String>, List<T>> readAfter) throws IOException {
|
||||
if (!isFileExist(filePath)) {
|
||||
throw new FileNotFoundException(String.format("[%s]文件不存在。", filePath));
|
||||
}
|
||||
try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
|
||||
List<String> datas = new ArrayList<>();
|
||||
try (RandomAccessFile randomAccessFile = new RandomAccessFile(new File(filePath), "r")) {
|
||||
if (readFileBean.getPointer() < 0) {
|
||||
readFileBean.setPointer(0);
|
||||
}
|
||||
randomAccessFile.seek(readFileBean.getPointer());
|
||||
readFileBean.setFileLength(randomAccessFile.length());
|
||||
List<String> datas = new ArrayList<>();
|
||||
int row = 1;
|
||||
int row = 0;
|
||||
String line;
|
||||
while ((line = randomAccessFile.readLine()) != null && row <= readFileBean.getReadRowNum()) {
|
||||
row++;
|
||||
readFileBean.setPointer(randomAccessFile.getFilePointer());
|
||||
datas.add(readFileBean.lineScavenge(charsetDecode(line, readFileBean.getReadCharset())));
|
||||
}
|
||||
|
||||
if (StrUtil.isEmpty(datas)) {
|
||||
//无数据
|
||||
return readFileBean.setDatas(List.of());
|
||||
}
|
||||
if (path.contains(TYPE_CSV)) {
|
||||
//csv文件处理
|
||||
com.yexuejc.base.pojo.CsvToBean csvToBean = getCsvToBean(readCls);
|
||||
readFileBean.setHeader(csvToBean.getHeader());
|
||||
if (csvToBean.isHasHeader()) {
|
||||
//文件存在header,设置header优先,没设置使用文件的
|
||||
if (StrUtil.isNotEmpty(csvToBean.getHeader())) {
|
||||
//替换header
|
||||
datas.remove(0);
|
||||
datas.add(0, csvToBean.getHeader());
|
||||
} else {
|
||||
readFileBean.setHeader(datas.get(0));
|
||||
}
|
||||
} else {
|
||||
//文件不存在header,使用设置的
|
||||
datas.add(0, csvToBean.getHeader());
|
||||
}
|
||||
|
||||
List<T> dataList = readCsv(String.join("\n", datas), readCls, csvToBean.getDelimiter());
|
||||
readFileBean.setDatas(dataList);
|
||||
}
|
||||
} 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<>());
|
||||
}
|
||||
List<T> dataList = readAfter.apply(datas);
|
||||
readFileBean.setDatas(dataList);
|
||||
return readFileBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分段读取大文件(不解析)
|
||||
*
|
||||
* @param csvFilePath 文件路径
|
||||
* @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数
|
||||
* @return 文件分页读取内容(每行为一个String对象)及读取信息
|
||||
*/
|
||||
public static ReadFileBean<String> readBigFile(String csvFilePath, ReadFileBean<String> readFileBean) throws IOException {
|
||||
return readBigFile(csvFilePath, readFileBean, (datas) -> datas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分段读取大文件(CSV格式)
|
||||
*
|
||||
* @param csvFilePath 文件路径
|
||||
* @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数
|
||||
* @param <T> 读取结果类型bean
|
||||
* @return 文件分页读取内容(转bean后)及读取信息
|
||||
*/
|
||||
public static <T> ReadFileBean<T> readBigFile(String csvFilePath, ReadFileBean<T> readFileBean, Class<T> readCls) throws IOException {
|
||||
if (!csvFilePath.endsWith(TYPE_CSV)) {
|
||||
throw new IOException(String.format("[%s]文件不是CSV文件格式。", csvFilePath));
|
||||
}
|
||||
return readBigFile(csvFilePath, readFileBean, (datas) -> {
|
||||
//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());
|
||||
}
|
||||
try {
|
||||
return readCsv(String.join(NEW_LINE, datas), readCls, csvToBean.getDelimiter());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取csv的header,使用注解{@link CsvToBean}
|
||||
*
|
||||
@@ -539,10 +429,8 @@ public class FileUtil {
|
||||
*/
|
||||
public static <T> com.yexuejc.base.pojo.CsvToBean getCsvToBean(Class<T> cls) {
|
||||
CsvToBean annotation = cls.getAnnotation(CsvToBean.class);
|
||||
Assert.notNull(annotation, cls.toString() + "类上需要添加注解@CsvToBean,并指定header。");
|
||||
com.yexuejc.base.pojo.CsvToBean csvToBean = new com.yexuejc.base.pojo.CsvToBean(
|
||||
annotation.header(), annotation.delimiter(), annotation.hasHeader());
|
||||
return csvToBean;
|
||||
Assert.notNull(annotation, cls + "类上需要添加注解@CsvToBean,并指定header。");
|
||||
return new com.yexuejc.base.pojo.CsvToBean(annotation.header(), annotation.delimiter(), annotation.hasHeader());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -249,6 +249,29 @@ public class JsonUtil {
|
||||
return pojo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Json字符串转换为Java对象
|
||||
*
|
||||
* @param in 输入流
|
||||
* @param parametrized 容器类
|
||||
* @param parameterClasses 实际类
|
||||
* @return
|
||||
*/
|
||||
public static <T> T json2Obj(InputStream in, Class<T> parametrized, Class<?>... parameterClasses) {
|
||||
T pojo = null;
|
||||
JavaType javaType = jsonMapper.getTypeFactory().constructParametricType(parametrized, parameterClasses);
|
||||
try {
|
||||
pojo = jsonMapper.readValue(in, javaType);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
|
||||
}
|
||||
return pojo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Json字符串转换为Java-Map对象
|
||||
*
|
||||
@@ -291,29 +314,6 @@ public class JsonUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Json字符串转换为Java对象
|
||||
*
|
||||
* @param json 字符串
|
||||
* @param parametrized 容器类
|
||||
* @param parameterClasses 实际类
|
||||
* @return
|
||||
*/
|
||||
public static <T> T json2Obj(InputStream json, Class<T> parametrized, Class<?>... parameterClasses) {
|
||||
T pojo = null;
|
||||
JavaType javaType = jsonMapper.getTypeFactory().constructParametrizedType(parametrized, parametrized,
|
||||
parameterClasses);
|
||||
try {
|
||||
pojo = jsonMapper.readValue(json, javaType);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + StrUtil.printStackTrace(e));
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + StrUtil.printStackTrace(e));
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + StrUtil.printStackTrace(e));
|
||||
}
|
||||
return pojo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将任何对象转换为json
|
||||
@@ -322,15 +322,55 @@ public class JsonUtil {
|
||||
* @return 返回json
|
||||
*/
|
||||
public static String obj2Json(Object pojo) {
|
||||
String json = null;
|
||||
if (StrUtil.isEmpty(pojo)) {
|
||||
return "";
|
||||
}
|
||||
String json = "";
|
||||
try {
|
||||
json = jsonMapper.writeValueAsString(pojo);
|
||||
return jsonMapper.writeValueAsString(pojo);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warning("json to Object JsonProcessingException.\n" + StrUtil.printStackTrace(e));
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从bean到Map的转换
|
||||
* <p>
|
||||
* 例:Map map = JsonUtil.obj2Map(data);
|
||||
* </p>
|
||||
*
|
||||
* @param pojo bean
|
||||
* @return Map
|
||||
*/
|
||||
public static Map<?, ?> objToMap(Object pojo) {
|
||||
return json2Obj(obj2Json(pojo), Map.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* json -> Map<String, String> 转换
|
||||
*
|
||||
* @param json JSON
|
||||
* @return Map
|
||||
*/
|
||||
public static Map<String, String> jsonToMapString(String json) {
|
||||
return objToMap(json, String.class, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Bean 对象转换为 Map
|
||||
* <p>
|
||||
* 示例:Map<String, RequestBean> map = JacksonMapperConfig.objToMap(data, String.class, RequestBean.class);
|
||||
* </p>
|
||||
*
|
||||
* @param pojo Bean 数据
|
||||
* @return Map 数据
|
||||
*/
|
||||
|
||||
public static <K, V> Map<K, V> objToMap(Object pojo, Class<K> kCls, Class<V> vCls) {
|
||||
return json2Obj(obj2Json(pojo), Map.class, kCls, vCls);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化输出
|
||||
*
|
||||
@@ -338,7 +378,7 @@ public class JsonUtil {
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
public static String formatPrinter(Object obj) {
|
||||
String json = null;
|
||||
String json = "";
|
||||
try {
|
||||
json = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import io.jsonwebtoken.security.SecureDigestAlgorithm;
|
||||
|
||||
/**
|
||||
* jwt工具类
|
||||
@@ -32,35 +36,46 @@ public class JwtUtil {
|
||||
/**
|
||||
* 参数配置:设置一次即可,多次设置会覆盖之前的
|
||||
*
|
||||
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
||||
* @param type 加密类型:默认JWT
|
||||
* @param iss token发行商: 默认yexuejc.com
|
||||
* @param type 加密类型:默认JWT
|
||||
* @param iss token发行商: 默认yexuejc.top
|
||||
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
||||
* @param algorithm 加密方式
|
||||
* @return
|
||||
*/
|
||||
public static JwtUtil config(String key, String type, String iss) {
|
||||
public static JwtUtil config(String type, String iss, String key, SecureDigestAlgorithm<SecretKey, SecretKey> algorithm) {
|
||||
JwtUtil jwtUtil = instace();
|
||||
jwtUtil.JWT_SIGNATURE_KEY = key;
|
||||
jwtUtil.JWT_HEADER_TYP = type;
|
||||
jwtUtil.JWT_CLAIMS_ISS = iss;
|
||||
if (null != key) {
|
||||
jwtUtil.jwtSignatureKey = key;
|
||||
}
|
||||
if (null != type) {
|
||||
jwtUtil.jwtHeaderTyp = type;
|
||||
}
|
||||
if (null != iss) {
|
||||
jwtUtil.jwtClaimsIss = iss;
|
||||
}
|
||||
if (null != algorithm) {
|
||||
jwtUtil.algorithm = algorithm;
|
||||
}
|
||||
return jwtUtil;
|
||||
}
|
||||
|
||||
public static class Instace {
|
||||
private static class Instace {
|
||||
private static JwtUtil jwtUtil = new JwtUtil();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密用KEY
|
||||
*/
|
||||
private String JWT_SIGNATURE_KEY = "h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a";
|
||||
private String jwtSignatureKey = "h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a";
|
||||
/**
|
||||
* token类型
|
||||
*/
|
||||
private String JWT_HEADER_TYP = "JWT";
|
||||
private String jwtHeaderTyp = "JWT";
|
||||
/**
|
||||
* token发行商
|
||||
*/
|
||||
private String JWT_CLAIMS_ISS = "yexuejc.com";
|
||||
private String jwtClaimsIss = "yexuejc.top";
|
||||
private SecureDigestAlgorithm<SecretKey, SecretKey> algorithm = Jwts.SIG.HS512;
|
||||
|
||||
/**
|
||||
* 加密内容生成token
|
||||
@@ -69,29 +84,38 @@ public class JwtUtil {
|
||||
* @return
|
||||
*/
|
||||
public String compact(Object subjectObj) {
|
||||
String subject = null;
|
||||
if (subjectObj instanceof String) {
|
||||
subject = (String) subjectObj;
|
||||
} else {
|
||||
subject = JsonUtil.obj2Json(subjectObj);
|
||||
return compact(null, subjectObj);
|
||||
}
|
||||
|
||||
public String compact(String subId, Object subjectObj) {
|
||||
String subject = subId;
|
||||
Map<String, Object> subMap = JsonUtil.objToMap(subjectObj, String.class, Object.class);
|
||||
if (StrUtil.isEmpty(subject)) {
|
||||
if (subjectObj instanceof String) {
|
||||
subject = (String) subjectObj;
|
||||
} else if (StrUtil.isNotEmpty(subMap)) {
|
||||
Object sid = subMap.get("subId");
|
||||
Object s = subMap.get("sub");
|
||||
subject = StrUtil.isNotEmpty(sid) ? String.valueOf(sid) : String.valueOf(s);
|
||||
}
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
String token = Jwts.builder()
|
||||
return Jwts.builder()
|
||||
// 设置token的唯一标识ID(claims.jti)
|
||||
.setId(StrUtil.genUUID())
|
||||
.id(StrUtil.genUUID())
|
||||
// 设置token类型(header.typ)
|
||||
.setHeaderParam("typ", JWT_HEADER_TYP)
|
||||
.header().add("typ", jwtHeaderTyp).and()
|
||||
// 设置token发行时间为当前时间(claims.iat)
|
||||
.setIssuedAt(now)
|
||||
.issuedAt(now).claims(JsonUtil.objToMap(subjectObj, String.class, Object.class))
|
||||
// 设置token发行商/发行者(claims.iss)
|
||||
.setIssuer(JWT_CLAIMS_ISS)
|
||||
.issuer(jwtClaimsIss)
|
||||
// 设置token用户定义主体(claims.sub)
|
||||
.setSubject(subject)
|
||||
// 设置签名算法和KEY(signature)
|
||||
.signWith(SignatureAlgorithm.HS512, JWT_SIGNATURE_KEY)
|
||||
.subject(subject)
|
||||
// 设置算法签名,(密钥,加密算法)
|
||||
.signWith(getSecretKey(), algorithm)
|
||||
// 生成token
|
||||
.compact();
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,16 +136,7 @@ public class JwtUtil {
|
||||
* @return
|
||||
*/
|
||||
public <T> T parse(String token, Class<T> cls) {
|
||||
String subject = null;
|
||||
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);
|
||||
return JsonUtil.json2Obj(JsonUtil.obj2Json(parseStr(token)), cls);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,13 +145,18 @@ public class JwtUtil {
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public String parseStr(String token) {
|
||||
String subject = null;
|
||||
try {
|
||||
subject = Jwts.parser().setSigningKey(JWT_SIGNATURE_KEY).parseClaimsJws(token).getBody().getSubject();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
public Claims parseStr(String token) {
|
||||
return Jwts.parser().verifyWith(getSecretKey()).build().parseSignedClaims(token).getPayload();
|
||||
}
|
||||
|
||||
private SecretKey getSecretKey() {
|
||||
int minLen = 32;
|
||||
if (jwtSignatureKey.length() % minLen != 0) {
|
||||
// 补齐32的倍数,左补0
|
||||
String format = "%" + ((jwtSignatureKey.length() / minLen + 1) * minLen) + "s";
|
||||
jwtSignatureKey = String.format(format, jwtSignatureKey).replace(' ', '0');
|
||||
}
|
||||
return subject;
|
||||
byte[] bytes = jwtSignatureKey.getBytes(StandardCharsets.UTF_8);
|
||||
return Keys.hmacShaKeyFor(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
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.NoSuchAlgorithmException;
|
||||
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.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -29,7 +21,7 @@ public final class StrUtil {
|
||||
private StrUtil() {
|
||||
}
|
||||
|
||||
private 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,"",[],{})
|
||||
@@ -79,12 +71,12 @@ public final class StrUtil {
|
||||
} else if (length < 1) {
|
||||
return "";
|
||||
} else {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length / 32; i++) {
|
||||
sb.append(genUUID());
|
||||
}
|
||||
if (length % 32 > 0) {
|
||||
sb.append(genUUID().substring(0, length % 32));
|
||||
sb.append(genUUID(), 0, length % 32);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -100,14 +92,14 @@ public final class StrUtil {
|
||||
*/
|
||||
public static String genNum() {
|
||||
int hashCode = UUID.randomUUID().toString().hashCode();
|
||||
StringBuffer num = new StringBuffer();
|
||||
StringBuilder num = new StringBuilder();
|
||||
if (hashCode < 0) {
|
||||
hashCode = 0 - hashCode;
|
||||
hashCode = -hashCode;
|
||||
num.append("0");
|
||||
} else {
|
||||
num.append("1");
|
||||
}
|
||||
return num.append(String.format("%010d", hashCode)).toString().substring(0, 8);
|
||||
return num.append(String.format("%010d", hashCode)).substring(0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,15 +109,15 @@ public final class StrUtil {
|
||||
* @return 转换后字符串
|
||||
*/
|
||||
public static String toHex(byte[] buf) {
|
||||
StringBuffer strbuf = new StringBuffer(buf.length * 2);
|
||||
StringBuilder sb = new StringBuilder(buf.length * 2);
|
||||
int i;
|
||||
for (i = 0; i < buf.length; i++) {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,11 +184,7 @@ public final class StrUtil {
|
||||
*/
|
||||
public static String iso2utf(String str) {
|
||||
String utfStr = null;
|
||||
try {
|
||||
utfStr = new String(str.getBytes("ISO-8859-1"), "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
utfStr = new String(str.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
|
||||
return utfStr;
|
||||
}
|
||||
|
||||
@@ -206,14 +194,11 @@ public final class StrUtil {
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
private static Pattern pattern = Pattern.compile("[0-9]*");
|
||||
private static final Pattern pattern = Pattern.compile("[0-9]*");
|
||||
|
||||
public static boolean isNumeric(String str) {
|
||||
Matcher isNum = pattern.matcher(str);
|
||||
if (!isNum.matches()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return isNum.matches();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +217,7 @@ public final class StrUtil {
|
||||
for (int i = 0; i < 13; i++) {
|
||||
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++) {
|
||||
coded.append(HEX_CHAR[random.nextInt(16)]);
|
||||
}
|
||||
@@ -256,8 +241,8 @@ public final class StrUtil {
|
||||
}
|
||||
|
||||
StringBuilder id = new StringBuilder();
|
||||
id.append(coded.substring(13, 24));
|
||||
id.append(coded.substring(31, 52));
|
||||
id.append(coded, 13, 24);
|
||||
id.append(coded, 31, 52);
|
||||
|
||||
return id.toString();
|
||||
}
|
||||
@@ -277,7 +262,7 @@ public final class StrUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>(16);
|
||||
Map<String, String> map = new HashMap<>(16);
|
||||
String[] kv = null;
|
||||
for (String entry : entrys) {
|
||||
if (isEmpty(entry)) {
|
||||
@@ -303,16 +288,15 @@ public final class StrUtil {
|
||||
* @return
|
||||
*/
|
||||
public static String getSignContent(Map<String, ?> sortedParams) {
|
||||
StringBuffer content = new StringBuffer();
|
||||
StringBuilder content = new StringBuilder();
|
||||
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
||||
Collections.sort(keys);
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < keys.size(); ++i) {
|
||||
String key = keys.get(i);
|
||||
for (String key : keys) {
|
||||
Object value = sortedParams.get(key);
|
||||
if (isNotEmpty(key) && isNotEmpty(value)) {
|
||||
content.append((index == 0 ? "" : "&") + key + "=" + value);
|
||||
content.append(index == 0 ? "" : "&").append(key).append("=").append(value);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
@@ -343,8 +327,7 @@ public final class StrUtil {
|
||||
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
||||
Collections.sort(keys);
|
||||
int index = 0;
|
||||
for (int i = 0; i < keys.size(); ++i) {
|
||||
String key = keys.get(i);
|
||||
for (String key : keys) {
|
||||
Object value = sortedParams.get(key);
|
||||
map.put(key, value);
|
||||
++index;
|
||||
@@ -475,12 +458,117 @@ public final class StrUtil {
|
||||
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(String.format(ERROR_MESSAGE_FORMAT, element.getClassName(), element.getMethodName(), element.getFileName(), element.getLineNumber()));
|
||||
sb.append(NEW_LINE);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 不是空对象时执行
|
||||
*
|
||||
* @param checkObj 判定对象
|
||||
* @param consumer 执行器
|
||||
* @param <T> 判定对象
|
||||
*/
|
||||
public static <T> void notNullExecute(T checkObj, Consumer<T> consumer) {
|
||||
if (null != checkObj) {
|
||||
consumer.accept(checkObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 不是空内容时执行
|
||||
*
|
||||
* @param checkObj 判定对象
|
||||
* @param consumer 执行器
|
||||
* @param <T> 判定对象
|
||||
*/
|
||||
public static <T> void notEmptyExecute(T checkObj, Consumer<T> consumer) {
|
||||
if (isNotEmpty(checkObj)) {
|
||||
consumer.accept(checkObj);
|
||||
}
|
||||
}
|
||||
|
||||
private static final List<String> COUNTRY_CODE = Arrays.asList("JPN", "KOR", "THA", "SGP", "CHN", "TWN", "HKG", "MAC", "999");
|
||||
|
||||
/**
|
||||
* 国名を国コードに変換
|
||||
*
|
||||
* @param country JPN:日本、KOR:韓国、THA:タイ、SGP:シンガポール、CHN:中国内陸、TWN:中国台湾、HKG:中国香港、MAC:マカオ、999:その他、0:不明
|
||||
* @return code byte <pre>
|
||||
* 1 0 1 0 1 1 1 1 1 <br>
|
||||
* 日本 韓国 タイ シンガポール 中国内陸 台湾 香港 マカオ その他
|
||||
* <br>
|
||||
* 右→左:0位:その他、1位:マカオ、2位:香港、3位:台湾、4位:中国内陸、5位:シンガポール、6位:タイ、7位:韓国、8位:日本
|
||||
* <br> 1:当該国で表示、0:当該国表示しない
|
||||
* </pre>
|
||||
*/
|
||||
public static byte countryToCodeByte(String country) {
|
||||
String code = countryToCode(country);
|
||||
return (byte) Integer.parseInt(code, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 国家代码转換成二进制
|
||||
*
|
||||
* @param country JPN:日本、KOR:韓国、THA:泰国、CHN:中国内陸、SGP:新加坡、TWN:中国台湾、HKG:中国香港、MAC:中国澳门、999:其他、0:不明
|
||||
* @return <pre>
|
||||
* 1 0 1 0 1 1 1 1 1 <br>
|
||||
* 日本 韓国 泰国 新加坡 中国内陸 台湾 香港 澳门 其他
|
||||
* <br>
|
||||
* 右→左:0位:其他、1位:中国澳门、2位:中国香港、3位:中国台湾、4位:中国内陸、5位:新加坡、6位:泰国、7位:韓国、8位:日本
|
||||
* <br> 1:在该国表示、0:不表示该国
|
||||
* </pre>
|
||||
*/
|
||||
public static String countryToCode(String country) {
|
||||
int index = COUNTRY_CODE.indexOf(country);
|
||||
if (index == -1) {
|
||||
return "000000000";
|
||||
}
|
||||
int bn = 1 << (COUNTRY_CODE.size() - 1 - index);
|
||||
// 转成二进制
|
||||
String bs = Integer.toBinaryString(bn);
|
||||
// 为了保证长度一致,前面补0
|
||||
return String.format("%09d", Integer.parseInt(bs));
|
||||
}
|
||||
|
||||
/**
|
||||
* 国家代码二进制转国家代码
|
||||
*
|
||||
* @param countryCode 国家代码二进制转:010000000
|
||||
* <pre>
|
||||
* 1 0 1 0 1 1 1 1 1 <br>
|
||||
* 日本 韓国 泰国 新加坡 中国内陸 台湾 香港 澳门 其他
|
||||
* <br>
|
||||
* 右→左:0位:其他、1位:中国澳门、2位:中国香港、3位:中国台湾、4位:中国内陸、5位:新加坡、6位:泰国、7位:韓国、8位:日本
|
||||
* <br> 1:在该国表示、0:不表示该国
|
||||
* </pre>
|
||||
* @return JPN:日本、KOR:韓国、THA:泰国、CHN:中国内陸、SGP:新加坡、TWN:中国台湾、HKG:中国香港、MAC:中国澳门、999:其他、0:不明
|
||||
*/
|
||||
public static String getCountryByCode(String countryCode) {
|
||||
int i = Integer.parseInt(countryCode, 2);
|
||||
int index = Integer.numberOfTrailingZeros(i);
|
||||
if (index > COUNTRY_CODE.size()) {
|
||||
return "O";
|
||||
}
|
||||
return COUNTRY_CODE.get(COUNTRY_CODE.size() - 1 - index);
|
||||
}
|
||||
|
||||
/**
|
||||
* nationalCodeは想定国エリア範囲内存在するかどうか
|
||||
* 想定国エリア範囲:"JPN", "KOR", "THA", "SGP", "CHN", "TWN", "HKG", "MAC", "999"
|
||||
*
|
||||
* @param nationCode
|
||||
* @return 存在:true;存在しない:false
|
||||
*/
|
||||
public static boolean containsCountry(String nationCode) {
|
||||
if (isNotEmpty(nationCode)) {
|
||||
return COUNTRY_CODE.contains(nationCode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.logging.Logger;
|
||||
* @date: 2017/12/28 16:12
|
||||
*/
|
||||
public class SysUtil {
|
||||
private static Logger logger = Logger.getLogger(SysUtil.class.getName());
|
||||
private static final Logger logger = Logger.getLogger(SysUtil.class.getName());
|
||||
private static final String PROJECT_ROOT_PATH = "java.io.tmpdir";
|
||||
|
||||
private SysUtil() {
|
||||
@@ -43,8 +43,8 @@ public class SysUtil {
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static URL getRootPath(Class clazz, String filePath) {
|
||||
return clazz.getClass().getResource(StrUtil.setStr(filePath, "/"));
|
||||
public static URL getRootPath(Class<?> clazz, String filePath) {
|
||||
return clazz.getResource(StrUtil.setStr(filePath, "/"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,9 +73,7 @@ public class SysUtil {
|
||||
0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
|
||||
|
||||
singleThreadPool.execute(() -> {
|
||||
threadRun.execute();
|
||||
});
|
||||
singleThreadPool.execute(threadRun::execute);
|
||||
singleThreadPool.shutdown();
|
||||
}
|
||||
|
||||
|
||||
55
src/test/java/com/yexuejc/base/encrypt/AESTest.java
Normal file
55
src/test/java/com/yexuejc/base/encrypt/AESTest.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.yexuejc.base.encrypt;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
|
||||
public class AESTest {
|
||||
|
||||
@Test
|
||||
public void testEncrypt() throws Exception {
|
||||
String data = "Hello World!";
|
||||
AES aes = AES.builder()
|
||||
.setAlgorithm(AES.ALGORITHM.AES_CBC_PKCS5Padding)
|
||||
.setKey("hj7x89H$yuBI0456")
|
||||
.setIv("NIfb&95GUY86Gfgh")
|
||||
.setCharset(StandardCharsets.UTF_8);
|
||||
String encrypted = aes.encrypt(data);
|
||||
assertNotNull(encrypted);
|
||||
assertFalse(encrypted.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecrypt() throws Exception {
|
||||
String data = "p0x0vK5T6OOy69+p9cgI/9xfeoi/f0t6NO7HbLsUON4=";
|
||||
AES aes = AES.builder()
|
||||
.setAlgorithm(AES.ALGORITHM.AES_CBC_PKCS5Padding)
|
||||
.setKey("hj7x89H$yuBI0456")
|
||||
.setIv("NIfb&95GUY86Gfgh")
|
||||
.setCharset(StandardCharsets.UTF_8);
|
||||
String decrypted = aes.decrypt(data);
|
||||
assertNotNull(decrypted);
|
||||
assertFalse(decrypted.isEmpty());
|
||||
assertEquals("Hello World!", decrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncryptAndDecrypt() throws Exception {
|
||||
String data = "张三";
|
||||
AES aes = AES.builder()
|
||||
.setAlgorithm(AES.ALGORITHM.AES_OFB_ISO10126Padding)
|
||||
.setKey("hj7x89H$yuBI0456")
|
||||
.setIv("NIfb&95GUY86Gfgh")
|
||||
.setCharset(StandardCharsets.UTF_8);
|
||||
String encrypt = aes.encrypt(data);
|
||||
System.out.println("加密:" + encrypt);
|
||||
String decrypt = aes.decrypt(encrypt);
|
||||
System.out.println("解密:" + decrypt);
|
||||
}
|
||||
|
||||
}
|
||||
70
src/test/java/com/yexuejc/base/util/DateUtilTest.java
Normal file
70
src/test/java/com/yexuejc/base/util/DateUtilTest.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class DateUtilTest {
|
||||
|
||||
@Test
|
||||
public void testParseDate() throws ParseException {
|
||||
String dateStr = "2022-03-20";
|
||||
String dateFormat = "yyyy-MM-dd";
|
||||
Date date = DateUtil.parseDate(dateStr, dateFormat);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
assertEquals(sdf.format(date), dateStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseLocalDate() throws ParseException {
|
||||
String dateStr = "2022-03-20";
|
||||
String dateFormat = "yyyy-MM-dd";
|
||||
LocalDate date = DateTimeUtil.parseLocalDate(DateUtil.parseDate(dateStr, dateFormat));
|
||||
assertEquals(date.toString(), dateStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatDateNow() {
|
||||
String dateFormat = "yyyy-MM-dd";
|
||||
String nowDateStr = DateUtil.formatDateNow(dateFormat);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
String nowDate = sdf.format(new Date());
|
||||
assertEquals(nowDate, nowDateStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatDate() {
|
||||
Date date = new Date();
|
||||
String dateFormat = "yyyy-MM-dd";
|
||||
String formattedDate = DateUtil.formatDate(date, dateFormat);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
assertEquals(sdf.format(date), formattedDate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatDateWithLocale() {
|
||||
Date date = new Date();
|
||||
String dateFormat = "yyyy-MM-dd";
|
||||
Locale locale = Locale.JAPAN;
|
||||
String formattedDate = DateUtil.formatDate(date, dateFormat, locale);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);
|
||||
assertEquals(sdf.format(date), formattedDate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDateByPlusDay() {
|
||||
int days = 2;
|
||||
String dateFormat = "yyyy-MM-dd";
|
||||
String plusDateStr = DateUtil.formatDate(DateUtil.datePlus(new Date(), days), dateFormat);
|
||||
LocalDate nowDate = LocalDate.now();
|
||||
LocalDate plusDate = nowDate.plusDays(days);
|
||||
assertEquals(plusDate.toString(), plusDateStr);
|
||||
}
|
||||
|
||||
}
|
||||
117
src/test/java/com/yexuejc/base/util/FileUtilTest.java
Normal file
117
src/test/java/com/yexuejc/base/util/FileUtilTest.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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-base\\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<String> readFileBean2 = new ReadFileBean<>(2);
|
||||
ReadFileBean<String> bean2 = FileUtil.readBigFile(path, readFileBean2);
|
||||
System.out.println("直接把每行读取成字符串============================================");
|
||||
System.out.println(JsonUtil.formatPrinter(bean2));
|
||||
System.out.println("直接把每行读取成字符串============================================");
|
||||
|
||||
//自定义每行数据的处理
|
||||
ReadFileBean<AppnodeCertCsvBean> readFileBean1 = new ReadFileBean<>(2);
|
||||
ReadFileBean<AppnodeCertCsvBean> bean1 = FileUtil.readBigFile(path, readFileBean1, datas -> {
|
||||
if (readFileBean1.getStartRowNum() == 1) {
|
||||
datas.remove(0);//跳过第一行
|
||||
}
|
||||
return datas.stream().map(str -> {
|
||||
//自定义处理每一条数据
|
||||
String[] split = str.split(",");
|
||||
AppnodeCertCsvBean app = new AppnodeCertCsvBean();
|
||||
app.setEnable(getValue(split, 0));
|
||||
app.setDomain(getValue(split, 1));
|
||||
app.setProtocol(getValue(split, 2));
|
||||
app.setDeployHost(getValue(split, 3));
|
||||
app.setDeployPath(getValue(split, 4));
|
||||
app.setUname(getValue(split, 5));
|
||||
app.setPwd(getValue(split, 6));
|
||||
if (StrUtil.isNotEmpty(getValue(split, 7))) {
|
||||
app.setAppnodeId(Integer.valueOf(getValue(split, 7)));
|
||||
}
|
||||
return app;
|
||||
}).collect(Collectors.toList());
|
||||
});
|
||||
System.out.println("自定义每行数据的处理============================================");
|
||||
System.out.println(JsonUtil.formatPrinter(bean1));
|
||||
System.out.println("自定义每行数据的处理============================================");
|
||||
|
||||
//直接使用提供的csv文件读取
|
||||
ReadFileBean<AppnodeCertCsvBean> readFileBean = new ReadFileBean<>(2);
|
||||
do {
|
||||
ReadFileBean<AppnodeCertCsvBean> bean = FileUtil.readBigFile(path, readFileBean, AppnodeCertCsvBean.class);
|
||||
System.out.println("直接使用提供的csv文件读取============================================");
|
||||
System.out.println(JsonUtil.formatPrinter(bean));
|
||||
System.out.println("直接使用提供的csv文件读取============================================");
|
||||
} while (readFileBean.hasNext());
|
||||
|
||||
}
|
||||
|
||||
private static String getValue(String[] value, int index) {
|
||||
try {
|
||||
return value[index];
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/test/java/com/yexuejc/base/util/JwtUtilTest.java
Normal file
26
src/test/java/com/yexuejc/base/util/JwtUtilTest.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author maxiaofeng
|
||||
* @date 2024/9/1 15:23
|
||||
*/
|
||||
class JwtUtilTest {
|
||||
|
||||
@Test
|
||||
void compact() {
|
||||
Map map = JsonUtil.json2Obj("{\n" + " \"payload\": {\n" + " \"sub\": \"0fqgx9h1d9eijd07umlyn1ez52jvkkkb883j\",\n" + " " +
|
||||
"\"iss\": \"www" + ".donki.com\",\n" + " \"aud\": \"D27A80C9AF01488F9A1152B8C20D93BA\",\n" + " \"exp\": 1725260806," +
|
||||
"\n" + " " + "\"iat\": 1725174406,\n" + " \"address\": {\n" + " \"country\": \"南朝鮮\"\n" + " },\n" + " " + "\"email_verified\": true,\n" + " \"birthdate\": \"1993/11/16\",\n" + " \"news_letter\": \"1\",\n" + " " + "\"gender\": \"other\",\n" + " \"member_code\": \"3511623793483553889787\",\n" + " \"preferred_username\": " + "\"3923490434\",\n" + " \"nonce\": \"mjhjSTmtVRNWPBtOQXZx\",\n" + " \"country_code\": \"CHN\",\n" + " " + "\"language_code\": \"zh-TW\",\n" + " \"updated_at\": 1722404351,\n" + " \"nickname\": \"3923490434\",\n" + " " + "\"customer_flag\": \"0\",\n" + " \"service_term_version\": \"2\",\n" + " \"email\": \"1828844769@qq.com\",\n" + " " + " \"auth_time\": 1725173983\n" + " }\n" + "}", Map.class);
|
||||
JwtUtil jwtUtil = JwtUtil.config("JWT", "www.donki.com", "5326D79EDEF344C3B3431F268DD2564C", Jwts.SIG.HS256);
|
||||
String jwtStr = jwtUtil.compact(map.get("payload"));
|
||||
System.out.println(jwtStr);
|
||||
|
||||
Map<?, ?> parse = jwtUtil.parse(jwtStr);
|
||||
System.out.println(JsonUtil.obj2Json(parse));
|
||||
}
|
||||
}
|
||||
139
src/test/java/com/yexuejc/base/util/StrUtilTest.java
Normal file
139
src/test/java/com/yexuejc/base/util/StrUtilTest.java
Normal file
@@ -0,0 +1,139 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class StrUtilTest {
|
||||
|
||||
@Test
|
||||
void isEmpty() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEmpty() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void genUUID() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenUUID() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void genNum() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void toHex() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void toMD5() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void toSHA256() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void toSHA() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void iso2utf() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNumeric() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void codeId() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeId() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseUrlencoded() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSignContent() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaceMobile() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapSort() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void setStr() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void underlineToCamel() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void camelToUnderline() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void printStackTraceAndMessage() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void printStackTrace() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void notNullExecute() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void notEmptyExecute() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void countryToCode() {
|
||||
Assertions.assertEquals(StrUtil.countryToCode("JPN"), "100000000");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("KOR"), "010000000");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("THA"), "001000000");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("SGP"), "000100000");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("CHN"), "000010000");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("TWN"), "000001000");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("HKG"), "000000100");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("MAC"), "000000010");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("999"), "000000001");
|
||||
Assertions.assertEquals(StrUtil.countryToCode("O"), "000000000");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCountryByCode() {
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("100000000"), "JPN");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("010000000"), "KOR");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("001000000"), "THA");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000100000"), "SGP");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000010000"), "CHN");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000001000"), "TWN");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000000100"), "HKG");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000000010"), "MAC");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000000001"), "999");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("000000000"), "O");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("100000000000"), "O");
|
||||
Assertions.assertEquals(StrUtil.getCountryByCode("-100000000000"), "O");
|
||||
}
|
||||
|
||||
@Test
|
||||
void countryToCodeByte() {
|
||||
System.out.println(String.format("%9s", Integer.toBinaryString(StrUtil.countryToCodeByte("CHN") & 0xFF)).replace(" ", "0"));
|
||||
}
|
||||
}
|
||||
22
src/test/java/com/yexuejc/base/util/SysUtilTest.java
Normal file
22
src/test/java/com/yexuejc/base/util/SysUtilTest.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
/**
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
}
|
||||
108
src/test/java/com/yexuejc/base/util/bean/AppnodeCertCsvBean.java
Normal file
108
src/test/java/com/yexuejc/base/util/bean/AppnodeCertCsvBean.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package com.yexuejc.base.util.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.yexuejc.base.annotation.CsvToBean;
|
||||
import com.yexuejc.base.converter.IntegerNullValueDeserializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: yexuejc
|
||||
* @date: 2024/2/27 10:40
|
||||
*/
|
||||
@CsvToBean(header = "enable,domain,protocol,deployHost,deployPath,uname,pwd,appnodeId")
|
||||
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
|
||||
*/
|
||||
@JsonDeserialize(using = IntegerNullValueDeserializer.class)
|
||||
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,
|
||||
|
Reference in New Issue
Block a user