From 197a03ea2d5e38496d5495ee8bc0d4e127f233cf Mon Sep 17 00:00:00 2001
From: ludc
Date: 星期一, 08 四月 2024 11:31:43 +0800
Subject: [PATCH] 工具类添加
---
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java | 57
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java | 2144 +++++++++++++++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java | 99
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java | 705 +++++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java | 161 +
Source/platformProject/vci-platform-web/pom.xml | 401 +-
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java | 60
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java | 30
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java | 383 ++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java | 3
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java | 115
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java | 35
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java | 71
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java | 433 +++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java | 21
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java | 1
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java | 109
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java | 195 +
Source/platformProject/pom.xml | 2
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java | 501 +++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java | 22
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java | 87
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java | 226 +
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java | 1560 +++++++++++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java | 634 ++++
Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java | 58
26 files changed, 7,916 insertions(+), 197 deletions(-)
diff --git a/Source/platformProject/pom.xml b/Source/platformProject/pom.xml
index 8a37391..b5e7b23 100644
--- a/Source/platformProject/pom.xml
+++ b/Source/platformProject/pom.xml
@@ -20,6 +20,8 @@
<old.spring.version>3.2.0.RELEASE</old.spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
+ <lombok.version>1.18.22</lombok.version>
+ <jackson.version>2.13.3</jackson.version>
</properties>
<!-- <distributionManagement>
diff --git a/Source/platformProject/vci-platform-web/pom.xml b/Source/platformProject/vci-platform-web/pom.xml
index 2923196..7043531 100644
--- a/Source/platformProject/vci-platform-web/pom.xml
+++ b/Source/platformProject/vci-platform-web/pom.xml
@@ -12,183 +12,192 @@
<artifactId>vci-platform-web</artifactId>
<dependencies>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- <type>pom</type>
- </dependency>
- <dependency>
- <groupId>com.vci.corba</groupId>
- <artifactId>plt-slice</artifactId>
- <version>1.0.RELEASE</version>
- </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>com.vci.corba</groupId>
+ <artifactId>plt-slice</artifactId>
+ <version>1.0.RELEASE</version>
+ </dependency>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-web</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-corba</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency><!--鏂囦欢鐨勪俊鎭�-->
- <groupId>com.vci</groupId>
- <artifactId>vci-file-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-file-integration</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-word</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-web</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-poi</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.vci</groupId>
- <artifactId>vci-starter-web</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>eu.bitwalker</groupId>
- <artifactId>UserAgentUtils</artifactId>
- <version>1.20</version>
- </dependency>
- <!--寮�鍚� cache 缂撳瓨 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- <version>2.1.3.RELEASE</version>
- </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-web</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-corba</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency><!--鏂囦欢鐨勪俊鎭�-->
+ <groupId>com.vci</groupId>
+ <artifactId>vci-file-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-file-integration</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-word</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-web</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-poi</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-starter-web</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>eu.bitwalker</groupId>
+ <artifactId>UserAgentUtils</artifactId>
+ <version>1.20</version>
+ </dependency>
+ <!--寮�鍚� cache 缂撳瓨 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-cache</artifactId>
+ <version>2.1.3.RELEASE</version>
+ </dependency>
- <!-- ehcache缂撳瓨 -->
- <dependency>
- <groupId>net.sf.ehcache</groupId>
- <artifactId>ehcache</artifactId>
- <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
- </dependency>
+ <!-- ehcache缂撳瓨 -->
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
+ </dependency>
- <dependency><!--java bean 鍜寈ml杞崲-->
- <groupId>com.thoughtworks.xstream</groupId>
- <artifactId>xstream</artifactId>
- <version>1.4.10</version>
- </dependency>
- <dependency><!--浠g爜鐢熸垚鍣ㄦ墍闇�妯℃澘-->
- <artifactId>velocity</artifactId>
- <groupId>org.apache.velocity</groupId>
- <version>1.7</version>
- </dependency>
- <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
- <groupId>com.vci.platform</groupId>
- <artifactId>ddlTool-client</artifactId>
- <version>${vciplt.version}</version>
- </dependency>
- <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
- <groupId>com.vci.platform</groupId>
- <artifactId>ddlTool-common</artifactId>
- <version>${vciplt.version}</version>
- </dependency>
- <dependency>
- <groupId>com.vci.client</groupId>
- <artifactId>plt-clientbase</artifactId>
- <version>1.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>com.zeroc</groupId>
- <artifactId>icegridgui</artifactId>
- <version>1.0.RELEASE</version>
- </dependency>
+ <dependency><!--java bean 鍜寈ml杞崲-->
+ <groupId>com.thoughtworks.xstream</groupId>
+ <artifactId>xstream</artifactId>
+ <version>1.4.10</version>
+ </dependency>
+ <dependency><!--浠g爜鐢熸垚鍣ㄦ墍闇�妯℃澘-->
+ <artifactId>velocity</artifactId>
+ <groupId>org.apache.velocity</groupId>
+ <version>1.7</version>
+ </dependency>
+ <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
+ <groupId>com.vci.platform</groupId>
+ <artifactId>ddlTool-client</artifactId>
+ <version>${vciplt.version}</version>
+ </dependency>
+ <dependency><!--鏁版嵁搴撴搷浣滃伐鍏�-->
+ <groupId>com.vci.platform</groupId>
+ <artifactId>ddlTool-common</artifactId>
+ <version>${vciplt.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.vci.client</groupId>
+ <artifactId>plt-clientbase</artifactId>
+ <version>1.0.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>com.zeroc</groupId>
+ <artifactId>icegridgui</artifactId>
+ <version>1.0.RELEASE</version>
+ </dependency>
<dependency>
<groupId>com.vci.common</groupId>
<artifactId>plt-common</artifactId>
<version>1.0.RELEASE</version>
</dependency>
- <dependency>
- <groupId>com.vci</groupId>
- <artifactId>vci-platform-starter</artifactId>
- <version>2022.1-SNAPSHOT</version>
- </dependency>
+ <dependency>
+ <groupId>com.vci</groupId>
+ <artifactId>vci-platform-starter</artifactId>
+ <version>2022.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.reflections</groupId>
+ <artifactId>reflections</artifactId>
+ <version>0.9.11</version>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>${lombok.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
- <dependency>
- <groupId>org.reflections</groupId>
- <artifactId>reflections</artifactId>
- <version>0.9.11</version>
- </dependency>
-
- <!--redis start-->
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-redis</artifactId>
- <version>2.1.5.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.9.0</version>
- </dependency>
- <!--redis end-->
- </dependencies>
+ <!--redis start-->
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-redis</artifactId>
+ <version>2.1.5.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>redis.clients</groupId>
+ <artifactId>jedis</artifactId>
+ <version>2.9.0</version>
+ </dependency>
+ <!--redis end-->
+ </dependencies>
<build>
<finalName>vci-platform-web</finalName>
@@ -211,34 +220,34 @@
</excludes>
</configuration>
</plugin>
-<!-- <plugin>-->
-<!-- <groupId>org.springframework.boot</groupId>-->
-<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
-<!-- <configuration>-->
-<!-- <!–閲嶅啓鍖呭惈渚濊禆锛屽寘鍚笉瀛樺湪鐨勪緷璧栵紝jar閲屾病鏈塸om閲岀殑渚濊禆–>-->
-<!-- <includes>-->
-<!-- <include>-->
-<!-- <groupId>null</groupId>-->
-<!-- <artifactId>null</artifactId>-->
-<!-- </include>-->
-<!-- </includes>-->
-<!-- <layout>ZIP</layout>-->
-<!-- <!–浣跨敤澶栭儴閰嶇疆鏂囦欢锛宩ar鍖呴噷娌℃湁璧勬簮鏂囦欢–>-->
-<!-- <addResources>true</addResources>-->
-<!-- </configuration>-->
-<!-- <executions>-->
-<!-- <execution>-->
-<!-- <goals>-->
-<!-- <goal>repackage</goal>-->
-<!-- </goals>-->
-<!-- <configuration>-->
-<!-- <!–閰嶇疆jar鍖呯壒娈婃爣璇� 閰嶇疆鍚庯紝淇濈暀鍘熸枃浠讹紝鐢熸垚鏂版枃浠� *-run.jar –>-->
-<!-- <!–閰嶇疆jar鍖呯壒娈婃爣璇� 涓嶉厤缃紝鍘熸枃浠跺懡鍚嶄负 *.jar.original锛岀敓鎴愭柊鏂囦欢 *.jar –>-->
-<!-- <!–<classifier>run</classifier>–>-->
-<!-- </configuration>-->
-<!-- </execution>-->
-<!-- </executions>-->
-<!-- </plugin>-->
+ <!-- <plugin>-->
+ <!-- <groupId>org.springframework.boot</groupId>-->
+ <!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
+ <!-- <configuration>-->
+ <!-- <!–閲嶅啓鍖呭惈渚濊禆锛屽寘鍚笉瀛樺湪鐨勪緷璧栵紝jar閲屾病鏈塸om閲岀殑渚濊禆–>-->
+ <!-- <includes>-->
+ <!-- <include>-->
+ <!-- <groupId>null</groupId>-->
+ <!-- <artifactId>null</artifactId>-->
+ <!-- </include>-->
+ <!-- </includes>-->
+ <!-- <layout>ZIP</layout>-->
+ <!-- <!–浣跨敤澶栭儴閰嶇疆鏂囦欢锛宩ar鍖呴噷娌℃湁璧勬簮鏂囦欢–>-->
+ <!-- <addResources>true</addResources>-->
+ <!-- </configuration>-->
+ <!-- <executions>-->
+ <!-- <execution>-->
+ <!-- <goals>-->
+ <!-- <goal>repackage</goal>-->
+ <!-- </goals>-->
+ <!-- <configuration>-->
+ <!-- <!–閰嶇疆jar鍖呯壒娈婃爣璇� 閰嶇疆鍚庯紝淇濈暀鍘熸枃浠讹紝鐢熸垚鏂版枃浠� *-run.jar –>-->
+ <!-- <!–閰嶇疆jar鍖呯壒娈婃爣璇� 涓嶉厤缃紝鍘熸枃浠跺懡鍚嶄负 *.jar.original锛岀敓鎴愭柊鏂囦欢 *.jar –>-->
+ <!-- <!–<classifier>run</classifier>–>-->
+ <!-- </configuration>-->
+ <!-- </execution>-->
+ <!-- </executions>-->
+ <!-- </plugin>-->
</plugins>
</build>
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
index 7c79482..5e6e69a 100644
--- a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
@@ -5,7 +5,6 @@
import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
import com.vci.frameworkcore.lcstatuspck.ReleaseDataLCStatus;
import com.vci.starter.revision.bo.TreeWrapperOptions;
-import com.vci.starter.revision.service.RevisionModelUtil;
import com.vci.starter.web.annotation.bus.VciChangeDataAfter;
import com.vci.starter.web.annotation.bus.VciChangeDataBefore;
import com.vci.starter.web.annotation.bus.VciChangeDataPlugin;
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
index 47b838d..4a69509 100644
--- a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/service/impl/UIEngineServiceImpl.java
@@ -507,7 +507,9 @@
@Override
@VciUnLog
public UITableDefineVO tableDO2VO(PortalVI portal, boolean queryDetail) {
+ if(){
+ }
UITableDefineVO tableDefineVO = new UITableDefineVO();
tableDefineVO.setOid(portal.id);
tableDefineVO.setId(portal.viName);
@@ -1275,6 +1277,7 @@
throw new VciBaseException("{0}閲岀殑琛ㄦ牸{1}涓嶅瓨鍦�", new String[]{btmType, componentDefineXO.getTemplateId()});
}
componentVO.setTableDefineVO(tableDefineVOMap.get(key));
+
}else{
try {
componentVO.setTableDefineVO(tableDO2VO(ServiceProvider.getUIService().getPortalVIByTypeNameAndVIName(btmType,componentDefineXO.getTemplateId()),true));
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java
new file mode 100644
index 0000000..86ba0db
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/support/StrSpliter.java
@@ -0,0 +1,501 @@
+package com.vci.web.support;
+
+import com.vci.web.util.StringUtil;
+import com.vci.web.util.Func;
+import com.vci.web.util.StringPool;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 瀛楃涓插垏鍒嗗櫒
+ *
+ * @author Looly
+ */
+public class StrSpliter {
+
+ //---------------------------------------------------------------------------------------------- Split by char
+
+ /**
+ * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> splitPath(String str) {
+ return splitPath(str, 0);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static String[] splitPathToArray(String str) {
+ return toArray(splitPath(str));
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> splitPath(String str, int limit) {
+ return split(str, StringPool.SLASH, limit, true, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓茶矾寰勶紝浠呮敮鎸乁nix鍒嗙晫绗︼細/
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static String[] splitPathToArray(String str, int limit) {
+ return toArray(splitPath(str, limit));
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> splitTrim(String str, char separator, boolean ignoreEmpty) {
+ return split(str, separator, 0, true, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(String str, char separator, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, 0, isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝澶у皬鍐欐晱鎰燂紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌虹櫧绗�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> splitTrim(String str, char separator, int limit, boolean ignoreEmpty) {
+ return split(str, separator, limit, true, ignoreEmpty, false);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝澶у皬鍐欐晱鎰�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, limit, isTrim, ignoreEmpty, false);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝蹇界暐澶у皬鍐�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> splitIgnoreCase(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, limit, isTrim, ignoreEmpty, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
+ if (StringUtil.isEmpty(str)) {
+ return new ArrayList<String>(0);
+ }
+ if (limit == 1) {
+ return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
+ }
+
+ final ArrayList<String> list = new ArrayList<>(limit > 0 ? limit : 16);
+ int len = str.length();
+ int start = 0;
+ for (int i = 0; i < len; i++) {
+ if (Func.equals(separator, str.charAt(i))) {
+ addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
+ start = i + 1;
+
+ //妫�鏌ユ槸鍚﹁秴鍑鸿寖鍥达紙鏈�澶у厑璁竘imit-1涓紝鍓╀笅涓�涓暀缁欐湯灏惧瓧绗︿覆锛�
+ if (limit > 0 && list.size() > limit - 2) {
+ break;
+ }
+ }
+ }
+ return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static String[] splitToArray(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
+ }
+
+ //---------------------------------------------------------------------------------------------- Split by String
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝涓嶅拷鐣ュぇ灏忓啓
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(String str, String separator, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, -1, isTrim, ignoreEmpty, false);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌烘牸锛屽拷鐣ュぇ灏忓啓
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> splitTrim(String str, String separator, boolean ignoreEmpty) {
+ return split(str, separator, true, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝涓嶅拷鐣ュぇ灏忓啓
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, limit, isTrim, ignoreEmpty, false);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌烘牸锛屽拷鐣ュぇ灏忓啓
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> splitTrim(String str, String separator, int limit, boolean ignoreEmpty) {
+ return split(str, separator, limit, true, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝蹇界暐澶у皬鍐�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> splitIgnoreCase(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, limit, isTrim, ignoreEmpty, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎姣忎釜鍏冪礌涓よ竟绌烘牸锛屽拷鐣ュぇ灏忓啓
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> splitTrimIgnoreCase(String str, String separator, int limit, boolean ignoreEmpty) {
+ return split(str, separator, limit, true, ignoreEmpty, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗︿覆
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.1
+ */
+ public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
+ if (StringUtil.isEmpty(str)) {
+ return new ArrayList<String>(0);
+ }
+ if (limit == 1) {
+ return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
+ }
+
+ if (StringUtil.isEmpty(separator)) {
+ return split(str, limit);
+ } else if (separator.length() == 1) {
+ return split(str, separator.charAt(0), limit, isTrim, ignoreEmpty, ignoreCase);
+ }
+
+ final ArrayList<String> list = new ArrayList<>();
+ int len = str.length();
+ int separatorLen = separator.length();
+ int start = 0;
+ int i = 0;
+ while (i < len) {
+ i = StringUtil.indexOf(str, separator, start, ignoreCase);
+ if (i > -1) {
+ addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
+ start = i + separatorLen;
+
+ //妫�鏌ユ槸鍚﹁秴鍑鸿寖鍥达紙鏈�澶у厑璁竘imit-1涓紝鍓╀笅涓�涓暀缁欐湯灏惧瓧绗︿覆锛�
+ if (limit > 0 && list.size() > limit - 2) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static String[] splitToArray(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
+ }
+
+ //---------------------------------------------------------------------------------------------- Split by Whitespace
+
+ /**
+ * 浣跨敤绌虹櫧绗﹀垏鍒嗗瓧绗︿覆<br>
+ * 鍒囧垎鍚庣殑瀛楃涓蹭袱杈逛笉鍖呭惈绌虹櫧绗︼紝绌轰覆鎴栫┖鐧界涓插苟涓嶅仛涓哄厓绱犱箣涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(String str, int limit) {
+ if (StringUtil.isEmpty(str)) {
+ return new ArrayList<String>(0);
+ }
+ if (limit == 1) {
+ return addToList(new ArrayList<String>(1), str, true, true);
+ }
+
+ final ArrayList<String> list = new ArrayList<>();
+ int len = str.length();
+ int start = 0;
+ for (int i = 0; i < len; i++) {
+ if (Func.isEmpty(str.charAt(i))) {
+ addToList(list, str.substring(start, i), true, true);
+ start = i + 1;
+ if (limit > 0 && list.size() > limit - 2) {
+ break;
+ }
+ }
+ }
+ return addToList(list, str.substring(start, len), true, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static String[] splitToArray(String str, int limit) {
+ return toArray(split(str, limit));
+ }
+
+ //---------------------------------------------------------------------------------------------- Split by regex
+
+ /**
+ * 閫氳繃姝e垯鍒囧垎瀛楃涓�
+ *
+ * @param str 瀛楃涓�
+ * @param separatorPattern 鍒嗛殧绗︽鍒檣@link Pattern}
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
+ if (StringUtil.isEmpty(str)) {
+ return new ArrayList<String>(0);
+ }
+ if (limit == 1) {
+ return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
+ }
+
+ if (null == separatorPattern) {
+ return split(str, limit);
+ }
+
+ final Matcher matcher = separatorPattern.matcher(str);
+ final ArrayList<String> list = new ArrayList<>();
+ int len = str.length();
+ int start = 0;
+ while (matcher.find()) {
+ addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty);
+ start = matcher.end();
+
+ if (limit > 0 && list.size() > limit - 2) {
+ break;
+ }
+ }
+ return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 閫氳繃姝e垯鍒囧垎瀛楃涓蹭负瀛楃涓叉暟缁�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separatorPattern 鍒嗛殧绗︽鍒檣@link Pattern}
+ * @param limit 闄愬埗鍒嗙墖鏁�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static String[] splitToArray(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
+ return toArray(split(str, separatorPattern, limit, isTrim, ignoreEmpty));
+ }
+
+ //---------------------------------------------------------------------------------------------- Split by length
+
+ /**
+ * 鏍规嵁缁欏畾闀垮害锛屽皢缁欏畾瀛楃涓叉埅鍙栦负澶氫釜閮ㄥ垎
+ *
+ * @param str 瀛楃涓�
+ * @param len 姣忎竴涓皬鑺傜殑闀垮害
+ * @return 鎴彇鍚庣殑瀛楃涓叉暟缁�
+ */
+ public static String[] splitByLength(String str, int len) {
+ int partCount = str.length() / len;
+ int lastPartCount = str.length() % len;
+ int fixPart = 0;
+ if (lastPartCount != 0) {
+ fixPart = 1;
+ }
+
+ final String[] strs = new String[partCount + fixPart];
+ for (int i = 0; i < partCount + fixPart; i++) {
+ if (i == partCount + fixPart - 1 && lastPartCount != 0) {
+ strs[i] = str.substring(i * len, i * len + lastPartCount);
+ } else {
+ strs[i] = str.substring(i * len, i * len + len);
+ }
+ }
+ return strs;
+ }
+
+ //---------------------------------------------------------------------------------------------------------- Private method start
+
+ /**
+ * 灏嗗瓧绗︿覆鍔犲叆List涓�
+ *
+ * @param list 鍒楄〃
+ * @param part 琚姞鍏ョ殑閮ㄥ垎
+ * @param isTrim 鏄惁鍘婚櫎涓ょ绌虹櫧绗�
+ * @param ignoreEmpty 鏄惁鐣ヨ繃绌哄瓧绗︿覆锛堢┖瀛楃涓蹭笉鍋氫负涓�涓厓绱狅級
+ * @return 鍒楄〃
+ */
+ private static List<String> addToList(List<String> list, String part, boolean isTrim, boolean ignoreEmpty) {
+ part = part.toString();
+ if (isTrim) {
+ part = part.trim();
+ }
+ if (false == ignoreEmpty || false == part.isEmpty()) {
+ list.add(part);
+ }
+ return list;
+ }
+
+ /**
+ * List杞珹rray
+ *
+ * @param list List
+ * @return Array
+ */
+ private static String[] toArray(List<String> list) {
+ return list.toArray(new String[list.size()]);
+ }
+ //---------------------------------------------------------------------------------------------------------- Private method end
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java
new file mode 100644
index 0000000..56a3003
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Base64Util.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+/**
+ * Base64宸ュ叿
+ *
+ * @author L.cm
+ */
+public class Base64Util extends org.springframework.util.Base64Utils {
+
+ /**
+ * 缂栫爜
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String encode(String value) {
+ return Base64Util.encode(value, Charsets.UTF_8);
+ }
+
+ /**
+ * 缂栫爜
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String encode(String value, java.nio.charset.Charset charset) {
+ byte[] val = value.getBytes(charset);
+ return new String(Base64Util.encode(val), charset);
+ }
+
+ /**
+ * 缂栫爜URL瀹夊叏
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String encodeUrlSafe(String value) {
+ return Base64Util.encodeUrlSafe(value, Charsets.UTF_8);
+ }
+
+ /**
+ * 缂栫爜URL瀹夊叏
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String encodeUrlSafe(String value, java.nio.charset.Charset charset) {
+ byte[] val = value.getBytes(charset);
+ return new String(Base64Util.encodeUrlSafe(val), charset);
+ }
+
+ /**
+ * 瑙g爜
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String decode(String value) {
+ return Base64Util.decode(value, Charsets.UTF_8);
+ }
+
+ /**
+ * 瑙g爜
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String decode(String value, java.nio.charset.Charset charset) {
+ byte[] val = value.getBytes(charset);
+ byte[] decodedValue = Base64Util.decode(val);
+ return new String(decodedValue, charset);
+ }
+
+ /**
+ * 瑙g爜URL瀹夊叏
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String decodeUrlSafe(String value) {
+ return Base64Util.decodeUrlSafe(value, Charsets.UTF_8);
+ }
+
+ /**
+ * 瑙g爜URL瀹夊叏
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String decodeUrlSafe(String value, java.nio.charset.Charset charset) {
+ byte[] val = value.getBytes(charset);
+ byte[] decodedValue = Base64Util.decodeUrlSafe(val);
+ return new String(decodedValue, charset);
+ }
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java
new file mode 100644
index 0000000..dd99d9a
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CharPool.java
@@ -0,0 +1,58 @@
+package com.vci.web.util;
+
+/**
+ * char 甯搁噺姹�
+ *
+ * @author L.cm
+ */
+public interface CharPool {
+
+ // @formatter:off
+ char UPPER_A = 'A';
+ char LOWER_A = 'a';
+ char UPPER_Z = 'Z';
+ char LOWER_Z = 'z';
+ char DOT = '.';
+ char AT = '@';
+ char LEFT_BRACE = '{';
+ char RIGHT_BRACE = '}';
+ char LEFT_BRACKET = '(';
+ char RIGHT_BRACKET = ')';
+ char DASH = '-';
+ char PERCENT = '%';
+ char PIPE = '|';
+ char PLUS = '+';
+ char QUESTION_MARK = '?';
+ char EXCLAMATION_MARK = '!';
+ char EQUALS = '=';
+ char AMPERSAND = '&';
+ char ASTERISK = '*';
+ char STAR = ASTERISK;
+ char BACK_SLASH = '\\';
+ char COLON = ':';
+ char COMMA = ',';
+ char DOLLAR = '$';
+ char SLASH = '/';
+ char HASH = '#';
+ char HAT = '^';
+ char LEFT_CHEV = '<';
+ char NEWLINE = '\n';
+ char N = 'n';
+ char Y = 'y';
+ char QUOTE = '\"';
+ char RETURN = '\r';
+ char TAB = '\t';
+ char RIGHT_CHEV = '>';
+ char SEMICOLON = ';';
+ char SINGLE_QUOTE = '\'';
+ char BACKTICK = '`';
+ char SPACE = ' ';
+ char TILDA = '~';
+ char LEFT_SQ_BRACKET = '[';
+ char RIGHT_SQ_BRACKET = ']';
+ char UNDERSCORE = '_';
+ char ONE = '1';
+ char ZERO = '0';
+ // @formatter:on
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java
new file mode 100644
index 0000000..1a18b47
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Charsets.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+
+/**
+ * 瀛楃闆嗗伐鍏风被
+ *
+ * @author L.cm
+ */
+public class Charsets {
+
+ /**
+ * 瀛楃闆咺SO-8859-1
+ */
+ public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
+ public static final String ISO_8859_1_NAME = ISO_8859_1.name();
+
+ /**
+ * 瀛楃闆咷BK
+ */
+ public static final Charset GBK = Charset.forName(StringPool.GBK);
+ public static final String GBK_NAME = GBK.name();
+
+ /**
+ * 瀛楃闆唘tf-8
+ */
+ public static final Charset UTF_8 = StandardCharsets.UTF_8;
+ public static final String UTF_8_NAME = UTF_8.name();
+
+ /**
+ * 杞崲涓篊harset瀵硅薄
+ *
+ * @param charsetName 瀛楃闆嗭紝涓虹┖鍒欒繑鍥為粯璁ゅ瓧绗﹂泦
+ * @return Charsets
+ * @throws UnsupportedCharsetException 缂栫爜涓嶆敮鎸�
+ */
+ public static Charset charset(String charsetName) throws UnsupportedCharsetException {
+ return StringUtil.isBlank(charsetName) ? Charset.defaultCharset() : Charset.forName(charsetName);
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java
new file mode 100644
index 0000000..2b4aae9
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/CollectionUtil.java
@@ -0,0 +1,161 @@
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Array;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 闆嗗悎宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class CollectionUtil extends CollectionUtils {
+
+ /**
+ * Return {@code true} if the supplied Collection is not {@code null} or empty.
+ * Otherwise, return {@code false}.
+ *
+ * @param collection the Collection to check
+ * @return whether the given Collection is not empty
+ */
+ public static boolean isNotEmpty(@Nullable Collection<?> collection) {
+ return !CollectionUtil.isEmpty(collection);
+ }
+
+ /**
+ * Return {@code true} if the supplied Map is not {@code null} or empty.
+ * Otherwise, return {@code false}.
+ *
+ * @param map the Map to check
+ * @return whether the given Map is not empty
+ */
+ public static boolean isNotEmpty(@Nullable Map<?, ?> map) {
+ return !CollectionUtil.isEmpty(map);
+ }
+
+ /**
+ * Check whether the given Array contains the given element.
+ *
+ * @param array the Array to check
+ * @param element the element to look for
+ * @param <T> The generic tag
+ * @return {@code true} if found, {@code false} else
+ */
+ public static <T> boolean contains(@Nullable T[] array, final T element) {
+ if (array == null) {
+ return false;
+ }
+ return Arrays.stream(array).anyMatch(x -> ObjectUtil.nullSafeEquals(x, element));
+ }
+
+ /**
+ * Concatenates 2 arrays
+ *
+ * @param one 鏁扮粍1
+ * @param other 鏁扮粍2
+ * @return 鏂版暟缁�
+ */
+ public static String[] concat(String[] one, String[] other) {
+ return concat(one, other, String.class);
+ }
+
+ /**
+ * Concatenates 2 arrays
+ *
+ * @param one 鏁扮粍1
+ * @param other 鏁扮粍2
+ * @param clazz 鏁扮粍绫�
+ * @return 鏂版暟缁�
+ */
+ public static <T> T[] concat(T[] one, T[] other, Class<T> clazz) {
+ T[] target = (T[]) Array.newInstance(clazz, one.length + other.length);
+ System.arraycopy(one, 0, target, 0, one.length);
+ System.arraycopy(other, 0, target, one.length, other.length);
+ return target;
+ }
+
+ /**
+ * 瀵硅薄鏄惁涓烘暟缁勫璞�
+ *
+ * @param obj 瀵硅薄
+ * @return 鏄惁涓烘暟缁勫璞★紝濡傛灉涓簕@code null} 杩斿洖false
+ */
+ public static boolean isArray(Object obj) {
+ if (null == obj) {
+ return false;
+ }
+ return obj.getClass().isArray();
+ }
+
+ /**
+ * 涓嶅彲鍙� Set
+ *
+ * @param es 瀵硅薄
+ * @param <E> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ @SafeVarargs
+ public static <E> Set<E> ofImmutableSet(E... es) {
+ Objects.requireNonNull(es, "args es is null.");
+ return Arrays.stream(es).collect(Collectors.toSet());
+ }
+
+ /**
+ * 涓嶅彲鍙� List
+ *
+ * @param es 瀵硅薄
+ * @param <E> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ @SafeVarargs
+ public static <E> List<E> ofImmutableList(E... es) {
+ Objects.requireNonNull(es, "args es is null.");
+ return Arrays.stream(es).collect(Collectors.toList());
+ }
+
+ /**
+ * Iterable 杞崲涓篖ist闆嗗悎
+ *
+ * @param elements Iterable
+ * @param <E> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <E> List<E> toList(Iterable<E> elements) {
+ Objects.requireNonNull(elements, "elements es is null.");
+ if (elements instanceof Collection) {
+ return new ArrayList((Collection) elements);
+ }
+ Iterator<E> iterator = elements.iterator();
+ List<E> list = new ArrayList<>();
+ while (iterator.hasNext()) {
+ list.add(iterator.next());
+ }
+ return list;
+ }
+
+ /**
+ * 灏唊ey value 鏁扮粍杞负 map
+ *
+ * @param keysValues key value 鏁扮粍
+ * @param <K> key
+ * @param <V> value
+ * @return map 闆嗗悎
+ */
+ public static <K, V> Map<K, V> toMap(Object... keysValues) {
+ int kvLength = keysValues.length;
+ if (kvLength % 2 != 0) {
+ throw new IllegalArgumentException("wrong number of arguments for met, keysValues length can not be odd");
+ }
+ Map<K, V> keyValueMap = new HashMap<>(kvLength);
+ for (int i = kvLength - 2; i >= 0; i -= 2) {
+ Object key = keysValues[i];
+ Object value = keysValues[i + 1];
+ keyValueMap.put((K) key, (V) value);
+ }
+ return keyValueMap;
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java
new file mode 100644
index 0000000..722de89
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ConcurrentDateFormat.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Queue;
+import java.util.TimeZone;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * 鍙傝�僼omcat8涓殑骞跺彂DateFormat
+ * <p>
+ * {@link SimpleDateFormat}鐨勭嚎绋嬪畨鍏ㄥ寘瑁呭櫒銆�
+ * 涓嶄娇鐢═hreadLocal锛屽垱寤鸿冻澶熺殑SimpleDateFormat瀵硅薄鏉ユ弧瓒冲苟鍙戞�ц姹傘��
+ * </p>
+ *
+ * @author L.cm
+ */
+public class ConcurrentDateFormat {
+ private final String format;
+ private final Locale locale;
+ private final TimeZone timezone;
+ private final Queue<SimpleDateFormat> queue = new ConcurrentLinkedQueue<>();
+
+ private ConcurrentDateFormat(String format, Locale locale, TimeZone timezone) {
+ this.format = format;
+ this.locale = locale;
+ this.timezone = timezone;
+ SimpleDateFormat initial = createInstance();
+ queue.add(initial);
+ }
+
+ public static ConcurrentDateFormat of(String format) {
+ return new ConcurrentDateFormat(format, Locale.getDefault(), TimeZone.getDefault());
+ }
+
+ public static ConcurrentDateFormat of(String format, TimeZone timezone) {
+ return new ConcurrentDateFormat(format, Locale.getDefault(), timezone);
+ }
+
+ public static ConcurrentDateFormat of(String format, Locale locale, TimeZone timezone) {
+ return new ConcurrentDateFormat(format, locale, timezone);
+ }
+
+ public String format(Date date) {
+ SimpleDateFormat sdf = queue.poll();
+ if (sdf == null) {
+ sdf = createInstance();
+ }
+ String result = sdf.format(date);
+ queue.add(sdf);
+ return result;
+ }
+
+ public Date parse(String source) throws ParseException {
+ SimpleDateFormat sdf = queue.poll();
+ if (sdf == null) {
+ sdf = createInstance();
+ }
+ Date result = sdf.parse(source);
+ queue.add(sdf);
+ return result;
+ }
+
+ private SimpleDateFormat createInstance() {
+ SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
+ sdf.setTimeZone(timezone);
+ return sdf;
+ }
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java
new file mode 100644
index 0000000..47d545c
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DatatypeConverterUtil.java
@@ -0,0 +1,57 @@
+package com.vci.web.util;
+
+/**
+ * 鏁版嵁绫诲瀷杞崲宸ュ叿绫�
+ *
+ * @author Chill
+ */
+public class DatatypeConverterUtil {
+
+ /**
+ * hex鏂囨湰杞崲涓轰簩杩涘埗
+ *
+ * @param hexStr hex鏂囨湰
+ * @return byte[]
+ */
+ public static byte[] parseHexBinary(String hexStr) {
+ final int len = hexStr.length();
+
+ if (len % 2 != 0) {
+ throw new IllegalArgumentException("hexBinary needs to be even-length: " + hexStr);
+ }
+
+ byte[] out = new byte[len / 2];
+
+ for (int i = 0; i < len; i += 2) {
+ int h = hexToBin(hexStr.charAt(i));
+ int l = hexToBin(hexStr.charAt(i + 1));
+ if (h == -1 || l == -1) {
+ throw new IllegalArgumentException("contains illegal character for hexBinary: " + hexStr);
+ }
+
+ out[i / 2] = (byte) (h * 16 + l);
+ }
+
+ return out;
+ }
+
+ /**
+ * hex鏂囨湰杞崲涓篿nt
+ *
+ * @param ch hex鏂囨湰
+ * @return int
+ */
+ private static int hexToBin(char ch) {
+ if ('0' <= ch && ch <= '9') {
+ return ch - '0';
+ }
+ if ('A' <= ch && ch <= 'F') {
+ return ch - 'A' + 10;
+ }
+ if ('a' <= ch && ch <= 'f') {
+ return ch - 'a' + 10;
+ }
+ return -1;
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java
new file mode 100644
index 0000000..09c62d5
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateTimeUtil.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package com.vci.web.util;
+
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.util.Date;
+
+/**
+ * DateTime 宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class DateTimeUtil {
+ public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
+ public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
+ public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTime(TemporalAccessor temporal) {
+ return DATETIME_FORMAT.format(temporal);
+ }
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDate(TemporalAccessor temporal) {
+ return DATE_FORMAT.format(temporal);
+ }
+
+ /**
+ * 鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatTime(TemporalAccessor temporal) {
+ return TIME_FORMAT.format(temporal);
+ }
+
+ /**
+ * 鏃ユ湡鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String format(TemporalAccessor temporal, String pattern) {
+ return DateTimeFormatter.ofPattern(pattern).format(temporal);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏃堕棿
+ */
+ public static LocalDateTime parseDateTime(String dateStr, String pattern) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+ return DateTimeUtil.parseDateTime(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param formatter DateTimeFormatter
+ * @return 鏃堕棿
+ */
+ public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
+ return LocalDateTime.parse(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @return 鏃堕棿
+ */
+ public static LocalDateTime parseDateTime(String dateStr) {
+ return DateTimeUtil.parseDateTime(dateStr, DateTimeUtil.DATETIME_FORMAT);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏃堕棿
+ */
+ public static LocalDate parseDate(String dateStr, String pattern) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+ return DateTimeUtil.parseDate(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param formatter DateTimeFormatter
+ * @return 鏃堕棿
+ */
+ public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
+ return LocalDate.parse(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘棩鏈�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @return 鏃堕棿
+ */
+ public static LocalDate parseDate(String dateStr) {
+ return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param pattern 鏃堕棿姝e垯
+ * @return 鏃堕棿
+ */
+ public static LocalTime parseTime(String dateStr, String pattern) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+ return DateTimeUtil.parseTime(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param formatter DateTimeFormatter
+ * @return 鏃堕棿
+ */
+ public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
+ return LocalTime.parse(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @return 鏃堕棿
+ */
+ public static LocalTime parseTime(String dateStr) {
+ return DateTimeUtil.parseTime(dateStr, DateTimeUtil.TIME_FORMAT);
+ }
+
+ /**
+ * 鏃堕棿杞� Instant
+ *
+ * @param dateTime 鏃堕棿
+ * @return Instant
+ */
+ public static Instant toInstant(LocalDateTime dateTime) {
+ return dateTime.atZone(ZoneId.systemDefault()).toInstant();
+ }
+
+ /**
+ * Instant 杞� 鏃堕棿
+ *
+ * @param instant Instant
+ * @return Instant
+ */
+ public static LocalDateTime toDateTime(Instant instant) {
+ return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+ }
+
+ /**
+ * 杞崲鎴� date
+ *
+ * @param dateTime LocalDateTime
+ * @return Date
+ */
+ public static Date toDate(LocalDateTime dateTime) {
+ return Date.from(DateTimeUtil.toInstant(dateTime));
+ }
+
+ /**
+ * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨皬
+ *
+ * @param startInclusive 寮�濮嬫椂闂�
+ * @param endExclusive 缁撴潫鏃堕棿
+ * @return 鏃堕棿闂撮殧
+ */
+ public static Duration between(Temporal startInclusive, Temporal endExclusive) {
+ return Duration.between(startInclusive, endExclusive);
+ }
+
+ /**
+ * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨ぇ锛屽勾鏈堟棩涓哄崟浣�
+ *
+ * @param startDate 寮�濮嬫椂闂�
+ * @param endDate 缁撴潫鏃堕棿
+ * @return 鏃堕棿闂撮殧
+ */
+ public static Period between(LocalDate startDate, LocalDate endDate) {
+ return Period.between(startDate, endDate);
+ }
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java
new file mode 100644
index 0000000..6b86fbe
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DateUtil.java
@@ -0,0 +1,634 @@
+package com.vci.web.util;
+
+import org.springframework.util.Assert;
+
+import java.text.ParseException;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalQuery;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * 鏃ユ湡宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class DateUtil {
+
+ public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
+ public static final String PATTERN_DATETIME_MINI = "yyyyMMddHHmmss";
+ public static final String PATTERN_DATE = "yyyy-MM-dd";
+ public static final String PATTERN_TIME = "HH:mm:ss";
+ /**
+ * 鑰� date 鏍煎紡鍖�
+ */
+ public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
+ public static final ConcurrentDateFormat DATETIME_MINI_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME_MINI);
+ public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
+ public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
+ /**
+ * java 8 鏃堕棿鏍煎紡鍖�
+ */
+ public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
+ public static final DateTimeFormatter DATETIME_MINI_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_MINI);
+ public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
+ public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡
+ *
+ * @return 褰撳墠鏃ユ湡
+ */
+ public static Date now() {
+ return new Date();
+ }
+
+ /**
+ * 娣诲姞骞�
+ *
+ * @param date 鏃堕棿
+ * @param yearsToAdd 娣诲姞鐨勫勾鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusYears(Date date, int yearsToAdd) {
+ return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
+ }
+
+ /**
+ * 娣诲姞鏈�
+ *
+ * @param date 鏃堕棿
+ * @param monthsToAdd 娣诲姞鐨勬湀鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusMonths(Date date, int monthsToAdd) {
+ return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
+ }
+
+ /**
+ * 娣诲姞鍛�
+ *
+ * @param date 鏃堕棿
+ * @param weeksToAdd 娣诲姞鐨勫懆鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusWeeks(Date date, int weeksToAdd) {
+ return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
+ }
+
+ /**
+ * 娣诲姞澶�
+ *
+ * @param date 鏃堕棿
+ * @param daysToAdd 娣诲姞鐨勫ぉ鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusDays(Date date, long daysToAdd) {
+ return DateUtil.plus(date, Duration.ofDays(daysToAdd));
+ }
+
+ /**
+ * 娣诲姞灏忔椂
+ *
+ * @param date 鏃堕棿
+ * @param hoursToAdd 娣诲姞鐨勫皬鏃舵暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusHours(Date date, long hoursToAdd) {
+ return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
+ }
+
+ /**
+ * 娣诲姞鍒嗛挓
+ *
+ * @param date 鏃堕棿
+ * @param minutesToAdd 娣诲姞鐨勫垎閽熸暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusMinutes(Date date, long minutesToAdd) {
+ return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
+ }
+
+ /**
+ * 娣诲姞绉�
+ *
+ * @param date 鏃堕棿
+ * @param secondsToAdd 娣诲姞鐨勭鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusSeconds(Date date, long secondsToAdd) {
+ return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
+ }
+
+ /**
+ * 娣诲姞姣
+ *
+ * @param date 鏃堕棿
+ * @param millisToAdd 娣诲姞鐨勬绉掓暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusMillis(Date date, long millisToAdd) {
+ return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
+ }
+
+ /**
+ * 娣诲姞绾崇
+ *
+ * @param date 鏃堕棿
+ * @param nanosToAdd 娣诲姞鐨勭撼绉掓暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plusNanos(Date date, long nanosToAdd) {
+ return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
+ }
+
+ /**
+ * 鏃ユ湡娣诲姞鏃堕棿閲�
+ *
+ * @param date 鏃堕棿
+ * @param amount 鏃堕棿閲�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date plus(Date date, TemporalAmount amount) {
+ Instant instant = date.toInstant();
+ return Date.from(instant.plus(amount));
+ }
+
+ /**
+ * 鍑忓皯骞�
+ *
+ * @param date 鏃堕棿
+ * @param years 鍑忓皯鐨勫勾鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusYears(Date date, int years) {
+ return DateUtil.set(date, Calendar.YEAR, -years);
+ }
+
+ /**
+ * 鍑忓皯鏈�
+ *
+ * @param date 鏃堕棿
+ * @param months 鍑忓皯鐨勬湀鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusMonths(Date date, int months) {
+ return DateUtil.set(date, Calendar.MONTH, -months);
+ }
+
+ /**
+ * 鍑忓皯鍛�
+ *
+ * @param date 鏃堕棿
+ * @param weeks 鍑忓皯鐨勫懆鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusWeeks(Date date, int weeks) {
+ return DateUtil.minus(date, Period.ofWeeks(weeks));
+ }
+
+ /**
+ * 鍑忓皯澶�
+ *
+ * @param date 鏃堕棿
+ * @param days 鍑忓皯鐨勫ぉ鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusDays(Date date, long days) {
+ return DateUtil.minus(date, Duration.ofDays(days));
+ }
+
+ /**
+ * 鍑忓皯灏忔椂
+ *
+ * @param date 鏃堕棿
+ * @param hours 鍑忓皯鐨勫皬鏃舵暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusHours(Date date, long hours) {
+ return DateUtil.minus(date, Duration.ofHours(hours));
+ }
+
+ /**
+ * 鍑忓皯鍒嗛挓
+ *
+ * @param date 鏃堕棿
+ * @param minutes 鍑忓皯鐨勫垎閽熸暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusMinutes(Date date, long minutes) {
+ return DateUtil.minus(date, Duration.ofMinutes(minutes));
+ }
+
+ /**
+ * 鍑忓皯绉�
+ *
+ * @param date 鏃堕棿
+ * @param seconds 鍑忓皯鐨勭鏁�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusSeconds(Date date, long seconds) {
+ return DateUtil.minus(date, Duration.ofSeconds(seconds));
+ }
+
+ /**
+ * 鍑忓皯姣
+ *
+ * @param date 鏃堕棿
+ * @param millis 鍑忓皯鐨勬绉掓暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusMillis(Date date, long millis) {
+ return DateUtil.minus(date, Duration.ofMillis(millis));
+ }
+
+ /**
+ * 鍑忓皯绾崇
+ *
+ * @param date 鏃堕棿
+ * @param nanos 鍑忓皯鐨勭撼绉掓暟
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minusNanos(Date date, long nanos) {
+ return DateUtil.minus(date, Duration.ofNanos(nanos));
+ }
+
+ /**
+ * 鏃ユ湡鍑忓皯鏃堕棿閲�
+ *
+ * @param date 鏃堕棿
+ * @param amount 鏃堕棿閲�
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ public static Date minus(Date date, TemporalAmount amount) {
+ Instant instant = date.toInstant();
+ return Date.from(instant.minus(amount));
+ }
+
+ /**
+ * 璁剧疆鏃ユ湡灞炴��
+ *
+ * @param date 鏃堕棿
+ * @param calendarField 鏇存敼鐨勫睘鎬�
+ * @param amount 鏇存敼鏁帮紝-1琛ㄧず鍑忓皯
+ * @return 璁剧疆鍚庣殑鏃堕棿
+ */
+ private static Date set(Date date, int calendarField, int amount) {
+ Assert.notNull(date, "The date must not be null");
+ Calendar c = Calendar.getInstance();
+ c.setLenient(false);
+ c.setTime(date);
+ c.add(calendarField, amount);
+ return c.getTime();
+ }
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTime(Date date) {
+ return DATETIME_FORMAT.format(date);
+ }
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTimeMini(Date date) {
+ return DATETIME_MINI_FORMAT.format(date);
+ }
+
+ /**
+ * 鏃ユ湡鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDate(Date date) {
+ return DATE_FORMAT.format(date);
+ }
+
+ /**
+ * 鏃堕棿鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatTime(Date date) {
+ return TIME_FORMAT.format(date);
+ }
+
+ /**
+ * 鏃ユ湡鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String format(Date date, String pattern) {
+ return ConcurrentDateFormat.of(pattern).format(date);
+ }
+
+ /**
+ * java8 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTime(TemporalAccessor temporal) {
+ return DATETIME_FORMATTER.format(temporal);
+ }
+
+ /**
+ * java8 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTimeMini(TemporalAccessor temporal) {
+ return DATETIME_MINI_FORMATTER.format(temporal);
+ }
+
+ /**
+ * java8 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDate(TemporalAccessor temporal) {
+ return DATE_FORMATTER.format(temporal);
+ }
+
+ /**
+ * java8 鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatTime(TemporalAccessor temporal) {
+ return TIME_FORMATTER.format(temporal);
+ }
+
+ /**
+ * java8 鏃ユ湡鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String format(TemporalAccessor temporal, String pattern) {
+ return DateTimeFormatter.ofPattern(pattern).format(temporal);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏃堕棿
+ */
+ public static Date parse(String dateStr, String pattern) {
+ ConcurrentDateFormat format = ConcurrentDateFormat.of(pattern);
+ try {
+ return format.parse(dateStr);
+ } catch (ParseException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param format ConcurrentDateFormat
+ * @return 鏃堕棿
+ */
+ public static Date parse(String dateStr, ConcurrentDateFormat format) {
+ try {
+ return format.parse(dateStr);
+ } catch (ParseException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏃堕棿
+ */
+ public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
+ return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
+ }
+
+ /**
+ * 鏃堕棿杞� Instant
+ *
+ * @param dateTime 鏃堕棿
+ * @return Instant
+ */
+ public static Instant toInstant(LocalDateTime dateTime) {
+ return dateTime.atZone(ZoneId.systemDefault()).toInstant();
+ }
+
+ /**
+ * Instant 杞� 鏃堕棿
+ *
+ * @param instant Instant
+ * @return Instant
+ */
+ public static LocalDateTime toDateTime(Instant instant) {
+ return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+ }
+
+ /**
+ * 杞崲鎴� date
+ *
+ * @param dateTime LocalDateTime
+ * @return Date
+ */
+ public static Date toDate(LocalDateTime dateTime) {
+ return Date.from(DateUtil.toInstant(dateTime));
+ }
+
+ /**
+ * 杞崲鎴� date
+ *
+ * @param localDate LocalDate
+ * @return Date
+ */
+ public static Date toDate(final LocalDate localDate) {
+ return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+ }
+
+ /**
+ * Converts local date time to Calendar.
+ */
+ public static Calendar toCalendar(final LocalDateTime localDateTime) {
+ return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
+ }
+
+ /**
+ * localDateTime 杞崲鎴愭绉掓暟
+ *
+ * @param localDateTime LocalDateTime
+ * @return long
+ */
+ public static long toMilliseconds(final LocalDateTime localDateTime) {
+ return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+ }
+
+ /**
+ * localDate 杞崲鎴愭绉掓暟
+ *
+ * @param localDate LocalDate
+ * @return long
+ */
+ public static long toMilliseconds(LocalDate localDate) {
+ return toMilliseconds(localDate.atStartOfDay());
+ }
+
+ /**
+ * 杞崲鎴恓ava8 鏃堕棿
+ *
+ * @param calendar 鏃ュ巻
+ * @return LocalDateTime
+ */
+ public static LocalDateTime fromCalendar(final Calendar calendar) {
+ TimeZone tz = calendar.getTimeZone();
+ ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
+ return LocalDateTime.ofInstant(calendar.toInstant(), zid);
+ }
+
+ /**
+ * 杞崲鎴恓ava8 鏃堕棿
+ *
+ * @param instant Instant
+ * @return LocalDateTime
+ */
+ public static LocalDateTime fromInstant(final Instant instant) {
+ return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+ }
+
+ /**
+ * 杞崲鎴恓ava8 鏃堕棿
+ *
+ * @param date Date
+ * @return LocalDateTime
+ */
+ public static LocalDateTime fromDate(final Date date) {
+ return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
+ }
+
+ /**
+ * 杞崲鎴恓ava8 鏃堕棿
+ *
+ * @param milliseconds 姣鏁�
+ * @return LocalDateTime
+ */
+ public static LocalDateTime fromMilliseconds(final long milliseconds) {
+ return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
+ }
+
+ /**
+ * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨皬
+ *
+ * @param startInclusive 寮�濮嬫椂闂�
+ * @param endExclusive 缁撴潫鏃堕棿
+ * @return 鏃堕棿闂撮殧
+ */
+ public static Duration between(Temporal startInclusive, Temporal endExclusive) {
+ return Duration.between(startInclusive, endExclusive);
+ }
+
+ /**
+ * 姣旇緝2涓椂闂村樊锛岃法搴︽瘮杈冨ぇ锛屽勾鏈堟棩涓哄崟浣�
+ *
+ * @param startDate 寮�濮嬫椂闂�
+ * @param endDate 缁撴潫鏃堕棿
+ * @return 鏃堕棿闂撮殧
+ */
+ public static Period between(LocalDate startDate, LocalDate endDate) {
+ return Period.between(startDate, endDate);
+ }
+
+ /**
+ * 姣旇緝2涓� 鏃堕棿宸�
+ *
+ * @param startDate 寮�濮嬫椂闂�
+ * @param endDate 缁撴潫鏃堕棿
+ * @return 鏃堕棿闂撮殧
+ */
+ public static Duration between(Date startDate, Date endDate) {
+ return Duration.between(startDate.toInstant(), endDate.toInstant());
+ }
+
+ /**
+ * 灏嗙鏁拌浆鎹负鏃ユ椂鍒嗙
+ *
+ * @param second 绉掓暟
+ * @return 鏃堕棿
+ */
+ public static String secondToTime(Long second) {
+ // 鍒ゆ柇鏄惁涓虹┖
+ if (second == null || second == 0L) {
+ return StringPool.EMPTY;
+ }
+ //杞崲澶╂暟
+ long days = second / 86400;
+ //鍓╀綑绉掓暟
+ second = second % 86400;
+ //杞崲灏忔椂
+ long hours = second / 3600;
+ //鍓╀綑绉掓暟
+ second = second % 3600;
+ //杞崲鍒嗛挓
+ long minutes = second / 60;
+ //鍓╀綑绉掓暟
+ second = second % 60;
+ if (days > 0) {
+ return StringUtil.format("{}澶﹞}灏忔椂{}鍒唟}绉�", days, hours, minutes, second);
+ } else {
+ return StringUtil.format("{}灏忔椂{}鍒唟}绉�", hours, minutes, second);
+ }
+ }
+
+ /**
+ * 鑾峰彇浠婂ぉ鐨勬棩鏈�
+ *
+ * @return 鏃堕棿
+ */
+ public static String today() {
+ return format(new Date(), "yyyyMMdd");
+ }
+
+ /**
+ * 鑾峰彇浠婂ぉ鐨勬椂闂�
+ *
+ * @return 鏃堕棿
+ */
+ public static String time() {
+ return format(new Date(), PATTERN_DATETIME_MINI);
+ }
+
+ /**
+ * 鑾峰彇浠婂ぉ鐨勫皬鏃舵暟
+ *
+ * @return 鏃堕棿
+ */
+ public static Integer hour() {
+ return NumberUtil.toInt(format(new Date(), "HH"));
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java
new file mode 100644
index 0000000..5daa93e
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/DigestUtil.java
@@ -0,0 +1,433 @@
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.DigestUtils;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 鍔犲瘑鐩稿叧宸ュ叿绫荤洿鎺ヤ娇鐢⊿pring util灏佽锛屽噺灏慾ar渚濊禆
+ *
+ * @author L.cm
+ */
+public class DigestUtil extends org.springframework.util.DigestUtils {
+ private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ /**
+ * Calculates the MD5 digest and returns the value as a 32 character hex string.
+ *
+ * @param data Data to digest
+ * @return MD5 digest as a hex string
+ */
+ public static String md5Hex(final String data) {
+ return DigestUtils.md5DigestAsHex(data.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * Return a hexadecimal string representation of the MD5 digest of the given bytes.
+ *
+ * @param bytes the bytes to calculate the digest over
+ * @return a hexadecimal digest string
+ */
+ public static String md5Hex(final byte[] bytes) {
+ return DigestUtils.md5DigestAsHex(bytes);
+ }
+
+ /**
+ * sha1Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha1Hex(String data) {
+ return DigestUtil.sha1Hex(data.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * sha1Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha1Hex(final byte[] bytes) {
+ return DigestUtil.digestHex("SHA-1", bytes);
+ }
+
+ /**
+ * SHA224Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha224Hex(String data) {
+ return DigestUtil.sha224Hex(data.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * SHA224Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha224Hex(final byte[] bytes) {
+ return DigestUtil.digestHex("SHA-224", bytes);
+ }
+
+ /**
+ * sha256Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha256Hex(String data) {
+ return DigestUtil.sha256Hex(data.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * sha256Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha256Hex(final byte[] bytes) {
+ return DigestUtil.digestHex("SHA-256", bytes);
+ }
+
+ /**
+ * sha384Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha384Hex(String data) {
+ return DigestUtil.sha384Hex(data.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * sha384Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha384Hex(final byte[] bytes) {
+ return DigestUtil.digestHex("SHA-384", bytes);
+ }
+
+ /**
+ * sha512Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha512Hex(String data) {
+ return DigestUtil.sha512Hex(data.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * sha512Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha512Hex(final byte[] bytes) {
+ return DigestUtil.digestHex("SHA-512", bytes);
+ }
+
+ /**
+ * digest Hex
+ *
+ * @param algorithm 绠楁硶
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String digestHex(String algorithm, byte[] bytes) {
+ try {
+ MessageDigest md = MessageDigest.getInstance(algorithm);
+ return encodeHex(md.digest(bytes));
+ } catch (NoSuchAlgorithmException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * hmacMd5 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacMd5Hex(String data, String key) {
+ return DigestUtil.hmacMd5Hex(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacMd5 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacMd5Hex(final byte[] bytes, String key) {
+ return DigestUtil.digestHMacHex("HmacMD5", bytes, key);
+ }
+
+ /**
+ * hmacSha1 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha1Hex(String data, String key) {
+ return DigestUtil.hmacSha1Hex(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacSha1 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha1Hex(final byte[] bytes, String key) {
+ return DigestUtil.digestHMacHex("HmacSHA1", bytes, key);
+ }
+
+ /**
+ * hmacSha224 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha224Hex(String data, String key) {
+ return DigestUtil.hmacSha224Hex(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacSha224 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha224Hex(final byte[] bytes, String key) {
+ return DigestUtil.digestHMacHex("HmacSHA224", bytes, key);
+ }
+
+ /**
+ * hmacSha256
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static byte[] hmacSha256(String data, String key) {
+ return DigestUtil.hmacSha256(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacSha256
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a byte array
+ */
+ public static byte[] hmacSha256(final byte[] bytes, String key) {
+ return DigestUtil.digestHMac("HmacSHA256", bytes, key);
+ }
+
+ /**
+ * hmacSha256 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha256Hex(String data, String key) {
+ return DigestUtil.hmacSha256Hex(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacSha256 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha256Hex(final byte[] bytes, String key) {
+ return DigestUtil.digestHMacHex("HmacSHA256", bytes, key);
+ }
+
+ /**
+ * hmacSha384 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha384Hex(String data, String key) {
+ return DigestUtil.hmacSha384Hex(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacSha384 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha384Hex(final byte[] bytes, String key) {
+ return DigestUtil.digestHMacHex("HmacSHA384", bytes, key);
+ }
+
+ /**
+ * hmacSha512 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha512Hex(String data, String key) {
+ return DigestUtil.hmacSha512Hex(data.getBytes(Charsets.UTF_8), key);
+ }
+
+ /**
+ * hmacSha512 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha512Hex(final byte[] bytes, String key) {
+ return DigestUtil.digestHMacHex("HmacSHA512", bytes, key);
+ }
+
+ /**
+ * digest HMac Hex
+ *
+ * @param algorithm 绠楁硶
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String digestHMacHex(String algorithm, final byte[] bytes, String key) {
+ SecretKey secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
+ try {
+ Mac mac = Mac.getInstance(secretKey.getAlgorithm());
+ mac.init(secretKey);
+ return DigestUtil.encodeHex(mac.doFinal(bytes));
+ } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * digest HMac
+ *
+ * @param algorithm 绠楁硶
+ * @param bytes Data to digest
+ * @return digest as a byte array
+ */
+ public static byte[] digestHMac(String algorithm, final byte[] bytes, String key) {
+ SecretKey secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
+ try {
+ Mac mac = Mac.getInstance(secretKey.getAlgorithm());
+ mac.init(secretKey);
+ return mac.doFinal(bytes);
+ } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * encode Hex
+ *
+ * @param bytes Data to Hex
+ * @return bytes as a hex string
+ */
+ public static String encodeHex(byte[] bytes) {
+ StringBuilder r = new StringBuilder(bytes.length * 2);
+ for (byte b : bytes) {
+ r.append(HEX_CODE[(b >> 4) & 0xF]);
+ r.append(HEX_CODE[(b & 0xF)]);
+ }
+ return r.toString();
+ }
+
+ /**
+ * decode Hex
+ *
+ * @param hexStr Hex string
+ * @return decode hex to bytes
+ */
+ public static byte[] decodeHex(final String hexStr) {
+ return DatatypeConverterUtil.parseHexBinary(hexStr);
+ }
+
+ /**
+ * 姣旇緝瀛楃涓诧紝閬垮厤瀛楃涓插洜涓鸿繃闀匡紝浜х敓鑰楁椂
+ *
+ * @param a String
+ * @param b String
+ * @return 鏄惁鐩稿悓
+ */
+ public static boolean slowEquals(@Nullable String a, @Nullable String b) {
+ if (a == null || b == null) {
+ return false;
+ }
+ return DigestUtil.slowEquals(a.getBytes(Charsets.UTF_8), b.getBytes(Charsets.UTF_8));
+ }
+
+ /**
+ * 姣旇緝 byte 鏁扮粍锛岄伩鍏嶅瓧绗︿覆鍥犱负杩囬暱锛屼骇鐢熻�楁椂
+ *
+ * @param a byte array
+ * @param b byte array
+ * @return 鏄惁鐩稿悓
+ */
+ public static boolean slowEquals(@Nullable byte[] a, @Nullable byte[] b) {
+ if (a == null || b == null) {
+ return false;
+ }
+ if (a.length != b.length) {
+ return false;
+ }
+ int diff = a.length ^ b.length;
+ for (int i = 0; i < a.length; i++) {
+ diff |= a[i] ^ b[i];
+ }
+ return diff == 0;
+ }
+
+ /**
+ * 鑷畾涔夊姞瀵� 灏嗗墠绔紶閫掔殑瀵嗙爜鍐嶆鍔犲瘑
+ *
+ * @param data 鏁版嵁
+ * @return {String}
+ */
+ public static String hex(String data) {
+ if (StringUtil.isBlank(data)) {
+ return StringPool.EMPTY;
+ }
+ return sha1Hex(data);
+ }
+
+ /**
+ * 鐢ㄦ埛瀵嗙爜鍔犲瘑瑙勫垯 鍏圡D5鍐峉HA1
+ *
+ * @param data 鏁版嵁
+ * @return {String}
+ */
+ public static String encrypt(String data) {
+ if (StringUtil.isBlank(data)) {
+ return StringPool.EMPTY;
+ }
+ return sha1Hex(md5Hex(data));
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java
new file mode 100644
index 0000000..b43a584
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Exceptions.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package com.vci.web.util;
+
+import cn.hutool.core.io.FastStringWriter;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+
+/**
+ * 寮傚父澶勭悊宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class Exceptions {
+
+ /**
+ * 灏咰heckedException杞崲涓篣ncheckedException.
+ *
+ * @param e Throwable
+ * @return {RuntimeException}
+ */
+ public static RuntimeException unchecked(Throwable e) {
+ if (e instanceof Error) {
+ throw (Error) e;
+ } else if (e instanceof IllegalAccessException ||
+ e instanceof IllegalArgumentException ||
+ e instanceof NoSuchMethodException) {
+ return new IllegalArgumentException(e);
+ } else if (e instanceof InvocationTargetException) {
+ return new RuntimeException(((InvocationTargetException) e).getTargetException());
+ } else if (e instanceof RuntimeException) {
+ return (RuntimeException) e;
+ } else if (e instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ }
+ return Exceptions.runtime(e);
+ }
+
+ /**
+ * 涓嶉噰鐢� RuntimeException 鍖呰锛岀洿鎺ユ姏鍑猴紝浣垮紓甯告洿鍔犵簿鍑�
+ *
+ * @param throwable Throwable
+ * @param <T> 娉涘瀷鏍囪
+ * @return Throwable
+ * @throws T 娉涘瀷
+ */
+ @SuppressWarnings("unchecked")
+ private static <T extends Throwable> T runtime(Throwable throwable) throws T {
+ throw (T) throwable;
+ }
+
+ /**
+ * 浠g悊寮傚父瑙e寘
+ *
+ * @param wrapped 鍖呰杩囧緱寮傚父
+ * @return 瑙e寘鍚庣殑寮傚父
+ */
+ public static Throwable unwrap(Throwable wrapped) {
+ Throwable unwrapped = wrapped;
+ while (true) {
+ if (unwrapped instanceof InvocationTargetException) {
+ unwrapped = ((InvocationTargetException) unwrapped).getTargetException();
+ } else if (unwrapped instanceof UndeclaredThrowableException) {
+ unwrapped = ((UndeclaredThrowableException) unwrapped).getUndeclaredThrowable();
+ } else {
+ return unwrapped;
+ }
+ }
+ }
+
+ /**
+ * 灏咵rrorStack杞寲涓篠tring.
+ *
+ * @param ex Throwable
+ * @return {String}
+ */
+ public static String getStackTraceAsString(Throwable ex) {
+ FastStringWriter stringWriter = new FastStringWriter();
+ ex.printStackTrace(new PrintWriter(stringWriter));
+ return stringWriter.toString();
+ }
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java
new file mode 100644
index 0000000..be66a55
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/FileUtil.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.FileSystemUtils;
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鏂囦欢宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class FileUtil extends org.springframework.util.FileCopyUtils {
+
+ /**
+ * 榛樿涓簍rue
+ *
+ * @author L.cm
+ */
+ public static class TrueFilter implements FileFilter, Serializable {
+ private static final long serialVersionUID = -6420452043795072619L;
+
+ public final static TrueFilter TRUE = new TrueFilter();
+
+ @Override
+ public boolean accept(File pathname) {
+ return true;
+ }
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param path 璺緞
+ * @return 鏂囦欢闆嗗悎
+ */
+ public static List<File> list(String path) {
+ File file = new File(path);
+ return list(file, TrueFilter.TRUE);
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param path 璺緞
+ * @param fileNamePattern 鏂囦欢鍚� * 鍙�
+ * @return 鏂囦欢闆嗗悎
+ */
+ public static List<File> list(String path, final String fileNamePattern) {
+ File file = new File(path);
+ return list(file, pathname -> {
+ String fileName = pathname.getName();
+ return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
+ });
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param path 璺緞
+ * @param filter 鏂囦欢杩囨护
+ * @return 鏂囦欢闆嗗悎
+ */
+ public static List<File> list(String path, FileFilter filter) {
+ File file = new File(path);
+ return list(file, filter);
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param file 鏂囦欢
+ * @return 鏂囦欢闆嗗悎
+ */
+ public static List<File> list(File file) {
+ List<File> fileList = new ArrayList<>();
+ return list(file, fileList, TrueFilter.TRUE);
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param file 鏂囦欢
+ * @param fileNamePattern Spring AntPathMatcher 瑙勫垯
+ * @return 鏂囦欢闆嗗悎
+ */
+ public static List<File> list(File file, final String fileNamePattern) {
+ List<File> fileList = new ArrayList<>();
+ return list(file, fileList, pathname -> {
+ String fileName = pathname.getName();
+ return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
+ });
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param file 鏂囦欢
+ * @param filter 鏂囦欢杩囨护
+ * @return 鏂囦欢闆嗗悎
+ */
+ public static List<File> list(File file, FileFilter filter) {
+ List<File> fileList = new ArrayList<>();
+ return list(file, fileList, filter);
+ }
+
+ /**
+ * 鎵弿鐩綍涓嬬殑鏂囦欢
+ *
+ * @param file 鏂囦欢
+ * @param filter 鏂囦欢杩囨护
+ * @return 鏂囦欢闆嗗悎
+ */
+ private static List<File> list(File file, List<File> fileList, FileFilter filter) {
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ if (files != null) {
+ for (File f : files) {
+ list(f, fileList, filter);
+ }
+ }
+ } else {
+ // 杩囨护鏂囦欢
+ boolean accept = filter.accept(file);
+ if (file.exists() && accept) {
+ fileList.add(file);
+ }
+ }
+ return fileList;
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢鍚庣紑鍚�
+ * @param fullName 鏂囦欢鍏ㄥ悕
+ * @return {String}
+ */
+ public static String getFileExtension(String fullName) {
+ if (StringUtil.isBlank(fullName)) return StringPool.EMPTY;
+ String fileName = new File(fullName).getName();
+ int dotIndex = fileName.lastIndexOf(CharPool.DOT);
+ return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢鍚嶏紝鍘婚櫎鍚庣紑鍚�
+ * @param fullName 鏂囦欢鍏ㄥ悕
+ * @return {String}
+ */
+ public static String getNameWithoutExtension(String fullName) {
+ if (StringUtil.isBlank(fullName)) return StringPool.EMPTY;
+ String fileName = new File(fullName).getName();
+ int dotIndex = fileName.lastIndexOf(CharPool.DOT);
+ return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
+ }
+
+ /**
+ * Returns the path to the system temporary directory.
+ *
+ * @return the path to the system temporary directory.
+ */
+ public static String getTempDirPath() {
+ return System.getProperty("java.io.tmpdir");
+ }
+
+ /**
+ * Returns a {@link File} representing the system temporary directory.
+ *
+ * @return the system temporary directory.
+ */
+ public static File getTempDir() {
+ return new File(getTempDirPath());
+ }
+
+ /**
+ * Reads the contents of a file into a String.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be {@code null}
+ * @return the file contents, never {@code null}
+ */
+ public static String readToString(final File file) {
+ return readToString(file, Charsets.UTF_8);
+ }
+
+ /**
+ * Reads the contents of a file into a String.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be {@code null}
+ * @param encoding the encoding to use, {@code null} means platform default
+ * @return the file contents, never {@code null}
+ */
+ public static String readToString(final File file, final Charset encoding) {
+ try (InputStream in = Files.newInputStream(file.toPath())) {
+ return IoUtil.readToString(in, encoding);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * Reads the contents of a file into a String.
+ * The file is always closed.
+ *
+ * @param file the file to read, must not be {@code null}
+ * @return the file contents, never {@code null}
+ */
+ public static byte[] readToByteArray(final File file) {
+ try (InputStream in = Files.newInputStream(file.toPath())) {
+ return IoUtil.readToByteArray(in);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * Writes a String to a file creating the file if it does not exist.
+ *
+ * @param file the file to write
+ * @param data the content to write to the file
+ */
+ public static void writeToFile(final File file, final String data) {
+ writeToFile(file, data, Charsets.UTF_8, false);
+ }
+
+ /**
+ * Writes a String to a file creating the file if it does not exist.
+ *
+ * @param file the file to write
+ * @param data the content to write to the file
+ * @param append if {@code true}, then the String will be added to the
+ * end of the file rather than overwriting
+ */
+ public static void writeToFile(final File file, final String data, final boolean append){
+ writeToFile(file, data, Charsets.UTF_8, append);
+ }
+
+ /**
+ * Writes a String to a file creating the file if it does not exist.
+ *
+ * @param file the file to write
+ * @param data the content to write to the file
+ * @param encoding the encoding to use, {@code null} means platform default
+ */
+ public static void writeToFile(final File file, final String data, final Charset encoding) {
+ writeToFile(file, data, encoding, false);
+ }
+
+ /**
+ * Writes a String to a file creating the file if it does not exist.
+ *
+ * @param file the file to write
+ * @param data the content to write to the file
+ * @param encoding the encoding to use, {@code null} means platform default
+ * @param append if {@code true}, then the String will be added to the
+ * end of the file rather than overwriting
+ */
+ public static void writeToFile(final File file, final String data, final Charset encoding, final boolean append) {
+ try (OutputStream out = new FileOutputStream(file, append)) {
+ IoUtil.write(data, out, encoding);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 杞垚file
+ * @param multipartFile MultipartFile
+ * @param file File
+ */
+ public static void toFile(MultipartFile multipartFile, final File file) {
+ try {
+ FileUtil.toFile(multipartFile.getInputStream(), file);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 杞垚file
+ * @param in InputStream
+ * @param file File
+ */
+ public static void toFile(InputStream in, final File file) {
+ try (OutputStream out = new FileOutputStream(file)) {
+ FileUtil.copy(in, out);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * Moves a file.
+ * <p>
+ * When the destination file is on another file system, do a "copy and delete".
+ *
+ * @param srcFile the file to be moved
+ * @param destFile the destination file
+ * @throws NullPointerException if source or destination is {@code null}
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs moving the file
+ */
+ public static void moveFile(final File srcFile, final File destFile) throws IOException {
+ Assert.notNull(srcFile, "Source must not be null");
+ Assert.notNull(destFile, "Destination must not be null");
+ if (!srcFile.exists()) {
+ throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
+ }
+ if (srcFile.isDirectory()) {
+ throw new IOException("Source '" + srcFile + "' is a directory");
+ }
+ if (destFile.exists()) {
+ throw new IOException("Destination '" + destFile + "' already exists");
+ }
+ if (destFile.isDirectory()) {
+ throw new IOException("Destination '" + destFile + "' is a directory");
+ }
+ final boolean rename = srcFile.renameTo(destFile);
+ if (!rename) {
+ FileUtil.copy(srcFile, destFile);
+ if (!srcFile.delete()) {
+ FileUtil.deleteQuietly(destFile);
+ throw new IOException("Failed to delete original file '" + srcFile + "' after copy to '" + destFile + "'");
+ }
+ }
+ }
+
+ /**
+ * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
+ * <p>
+ * The difference between File.delete() and this method are:
+ * <ul>
+ * <li>A directory to be deleted does not have to be empty.</li>
+ * <li>No exceptions are thrown when a file or directory cannot be deleted.</li>
+ * </ul>
+ *
+ * @param file file or directory to delete, can be {@code null}
+ * @return {@code true} if the file or directory was deleted, otherwise
+ * {@code false}
+ */
+ public static boolean deleteQuietly(@Nullable final File file) {
+ if (file == null) {
+ return false;
+ }
+ try {
+ if (file.isDirectory()) {
+ FileSystemUtils.deleteRecursively(file);
+ }
+ } catch (final Exception ignored) {
+ }
+
+ try {
+ return file.delete();
+ } catch (final Exception ignored) {
+ return false;
+ }
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java
new file mode 100644
index 0000000..4d14c13
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Func.java
@@ -0,0 +1,2144 @@
+package com.vci.web.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import com.aspose.words.ConvertUtil;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jndi.toolkit.url.UrlUtil;
+import com.vci.web.util.jackson.JsonUtil;
+import org.springframework.util.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.lang.Nullable;
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.method.HandlerMethod;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.text.DecimalFormat;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.util.*;
+import java.util.function.Supplier;
+
+/**
+ * 宸ュ叿鍖呴泦鍚堬紝宸ュ叿绫诲揩鎹锋柟寮�
+ *
+ * @author L.cm
+ */
+public class Func {
+
+ /**
+ * 鏂█锛屽繀椤讳笉鑳戒负 null
+ * <blockquote><pre>
+ * public Foo(Bar bar) {
+ * this.bar = $.requireNotNull(bar);
+ * }
+ * </pre></blockquote>
+ *
+ * @param obj the object reference to check for nullity
+ * @param <T> the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ */
+ public static <T> T requireNotNull(T obj) {
+ return Objects.requireNonNull(obj);
+ }
+
+ /**
+ * 鏂█锛屽繀椤讳笉鑳戒负 null
+ * <blockquote><pre>
+ * public Foo(Bar bar, Baz baz) {
+ * this.bar = $.requireNotNull(bar, "bar must not be null");
+ * this.baz = $.requireNotNull(baz, "baz must not be null");
+ * }
+ * </pre></blockquote>
+ *
+ * @param obj the object reference to check for nullity
+ * @param message detail message to be used in the event that a {@code
+ * NullPointerException} is thrown
+ * @param <T> the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ */
+ public static <T> T requireNotNull(T obj, String message) {
+ return Objects.requireNonNull(obj, message);
+ }
+
+ /**
+ * 鏂█锛屽繀椤讳笉鑳戒负 null
+ * <blockquote><pre>
+ * public Foo(Bar bar, Baz baz) {
+ * this.bar = $.requireNotNull(bar, () -> "bar must not be null");
+ * }
+ * </pre></blockquote>
+ *
+ * @param obj the object reference to check for nullity
+ * @param messageSupplier supplier of the detail message to be
+ * used in the event that a {@code NullPointerException} is thrown
+ * @param <T> the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ */
+ public static <T> T requireNotNull(T obj, Supplier<String> messageSupplier) {
+ return Objects.requireNonNull(obj, messageSupplier);
+ }
+
+ /**
+ * 鍒ゆ柇瀵硅薄鏄惁涓簄ull
+ * <p>
+ * This method exists to be used as a
+ * {@link java.util.function.Predicate}, {@code filter($::isNull)}
+ * </p>
+ *
+ * @param obj a reference to be checked against {@code null}
+ * @return {@code true} if the provided reference is {@code null} otherwise
+ * {@code false}
+ * @see java.util.function.Predicate
+ */
+ public static boolean isNull(@Nullable Object obj) {
+ return Objects.isNull(obj);
+ }
+
+ /**
+ * 鍒ゆ柇瀵硅薄鏄惁 not null
+ * <p>
+ * This method exists to be used as a
+ * {@link java.util.function.Predicate}, {@code filter($::notNull)}
+ * </p>
+ *
+ * @param obj a reference to be checked against {@code null}
+ * @return {@code true} if the provided reference is non-{@code null}
+ * otherwise {@code false}
+ * @see java.util.function.Predicate
+ */
+ public static boolean notNull(@Nullable Object obj) {
+ return Objects.nonNull(obj);
+ }
+
+ /**
+ * 棣栧瓧姣嶅彉灏忓啓
+ *
+ * @param str 瀛楃涓�
+ * @return {String}
+ */
+ public static String firstCharToLower(String str) {
+ return StringUtil.firstCharToLower(str);
+ }
+
+ /**
+ * 棣栧瓧姣嶅彉澶у啓
+ *
+ * @param str 瀛楃涓�
+ * @return {String}
+ */
+ public static String firstCharToUpper(String str) {
+ return StringUtil.firstCharToUpper(str);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓虹┖瀛楃涓�
+ * <pre class="code">
+ * $.isBlank(null) = true
+ * $.isBlank("") = true
+ * $.isBlank(" ") = true
+ * $.isBlank("12345") = false
+ * $.isBlank(" 12345 ") = false
+ * </pre>
+ *
+ * @param cs the {@code CharSequence} to check (may be {@code null})
+ * @return {@code true} if the {@code CharSequence} is not {@code null},
+ * its length is greater than 0, and it does not contain whitespace only
+ * @see Character#isWhitespace
+ */
+ public static boolean isBlank(@Nullable final CharSequence cs) {
+ return StringUtil.isBlank(cs);
+ }
+
+ /**
+ * 鍒ゆ柇涓嶄负绌哄瓧绗︿覆
+ * <pre>
+ * $.isNotBlank(null) = false
+ * $.isNotBlank("") = false
+ * $.isNotBlank(" ") = false
+ * $.isNotBlank("bob") = true
+ * $.isNotBlank(" bob ") = true
+ * </pre>
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {@code true} if the CharSequence is
+ * not empty and not null and not whitespace
+ * @see Character#isWhitespace
+ */
+ public static boolean isNotBlank(@Nullable final CharSequence cs) {
+ return StringUtil.isNotBlank(cs);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁鏈変换鎰忎竴涓� 绌哄瓧绗︿覆
+ *
+ * @param css CharSequence
+ * @return boolean
+ */
+ public static boolean isAnyBlank(final CharSequence... css) {
+ return StringUtil.isAnyBlank(css);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁鍏ㄤ负闈炵┖瀛楃涓�
+ *
+ * @param css CharSequence
+ * @return boolean
+ */
+ public static boolean isNoneBlank(final CharSequence... css) {
+ return StringUtil.isNoneBlank(css);
+ }
+
+ /**
+ * 鍒ゆ柇瀵硅薄鏄暟缁�
+ *
+ * @param obj the object to check
+ * @return 鏄惁鏁扮粍
+ */
+ public static boolean isArray(@Nullable Object obj) {
+ return ObjectUtil.isArray(obj);
+ }
+
+ /**
+ * 鍒ゆ柇绌哄璞� object銆乵ap銆乴ist銆乻et銆佸瓧绗︿覆銆佹暟缁�
+ *
+ * @param obj the object to check
+ * @return 鏁扮粍鏄惁涓虹┖
+ */
+ public static boolean isEmpty(@Nullable Object obj) {
+ return ObjectUtil.isEmpty(obj);
+ }
+
+ /**
+ * 瀵硅薄涓嶄负绌� object銆乵ap銆乴ist銆乻et銆佸瓧绗︿覆銆佹暟缁�
+ *
+ * @param obj the object to check
+ * @return 鏄惁涓嶄负绌�
+ */
+ public static boolean isNotEmpty(@Nullable Object obj) {
+ return !ObjectUtil.isEmpty(obj);
+ }
+
+ /**
+ * 鍒ゆ柇鏁扮粍涓虹┖
+ *
+ * @param array the array to check
+ * @return 鏁扮粍鏄惁涓虹┖
+ */
+ public static boolean isEmpty(@Nullable Object[] array) {
+ return ObjectUtil.isEmpty(array);
+ }
+
+ /**
+ * 鍒ゆ柇鏁扮粍涓嶄负绌�
+ *
+ * @param array 鏁扮粍
+ * @return 鏁扮粍鏄惁涓嶄负绌�
+ */
+ public static boolean isNotEmpty(@Nullable Object[] array) {
+ return ObjectUtil.isNotEmpty(array);
+ }
+
+ /**
+ * 瀵硅薄缁勪腑鏄惁瀛樺湪 Empty Object
+ *
+ * @param os 瀵硅薄缁�
+ * @return boolean
+ */
+ public static boolean hasEmpty(Object... os) {
+ for (Object o : os) {
+ if (isEmpty(o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 瀵硅薄缁勪腑鏄惁鍏ㄩ儴涓� Empty Object
+ *
+ * @param os 瀵硅薄缁�
+ * @return boolean
+ */
+ public static boolean isAllEmpty(Object... os) {
+ for (Object o : os) {
+ if (isNotEmpty(o)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆涓壒瀹氭ā寮忕殑瀛楃杞崲鎴恗ap涓搴旂殑鍊�
+ * <p>
+ * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
+ *
+ * @param message 闇�瑕佽浆鎹㈢殑瀛楃涓�
+ * @param params 杞崲鎵�闇�鐨勯敭鍊煎闆嗗悎
+ * @return 杞崲鍚庣殑瀛楃涓�
+ */
+ public static String format(@Nullable String message, @Nullable Map<String, ?> params) {
+ return StringUtil.format(message, params);
+ }
+
+ /**
+ * 鍚� log 鏍煎紡鐨� format 瑙勫垯
+ * <p>
+ * use: format("my name is {}, and i like {}!", "L.cm", "Java")
+ *
+ * @param message 闇�瑕佽浆鎹㈢殑瀛楃涓�
+ * @param arguments 闇�瑕佹浛鎹㈢殑鍙橀噺
+ * @return 杞崲鍚庣殑瀛楃涓�
+ */
+ public static String format(@Nullable String message, @Nullable Object... arguments) {
+ return StringUtil.format(message, arguments);
+ }
+
+ /**
+ * 鏍煎紡鍖栨墽琛屾椂闂达紝鍗曚綅涓� ms 鍜� s锛屼繚鐣欎笁浣嶅皬鏁�
+ *
+ * @param nanos 绾崇
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String format(long nanos) {
+ return StringUtil.format(nanos);
+ }
+
+ /**
+ * 姣旇緝涓や釜瀵硅薄鏄惁鐩哥瓑銆�<br>
+ * 鐩稿悓鐨勬潯浠舵湁涓や釜锛屾弧瓒冲叾涓�鍗冲彲锛�<br>
+ *
+ * @param obj1 瀵硅薄1
+ * @param obj2 瀵硅薄2
+ * @return 鏄惁鐩哥瓑
+ */
+ public static boolean equals(Object obj1, Object obj2) {
+ return Objects.equals(obj1, obj2);
+ }
+
+ /**
+ * 瀹夊叏鐨� equals
+ *
+ * @param o1 first Object to compare
+ * @param o2 second Object to compare
+ * @return whether the given objects are equal
+ * @see Object#equals(Object)
+ * @see java.util.Arrays#equals
+ */
+ public static boolean equalsSafe(@Nullable Object o1, @Nullable Object o2) {
+ return ObjectUtil.nullSafeEquals(o1, o2);
+ }
+
+ /**
+ * 鍒ゆ柇鏁扮粍涓槸鍚﹀寘鍚厓绱�
+ *
+ * @param array the Array to check
+ * @param element the element to look for
+ * @param <T> The generic tag
+ * @return {@code true} if found, {@code false} else
+ */
+ public static <T> boolean contains(@Nullable T[] array, final T element) {
+ return CollectionUtil.contains(array, element);
+ }
+
+ /**
+ * 鍒ゆ柇杩唬鍣ㄤ腑鏄惁鍖呭惈鍏冪礌
+ *
+ * @param iterator the Iterator to check
+ * @param element the element to look for
+ * @return {@code true} if found, {@code false} otherwise
+ */
+ public static boolean contains(@Nullable Iterator<?> iterator, Object element) {
+ return CollectionUtil.contains(iterator, element);
+ }
+
+ /**
+ * 鍒ゆ柇鏋氫妇鏄惁鍖呭惈璇ュ厓绱�
+ *
+ * @param enumeration the Enumeration to check
+ * @param element the element to look for
+ * @return {@code true} if found, {@code false} otherwise
+ */
+ public static boolean contains(@Nullable Enumeration<?> enumeration, Object element) {
+ return CollectionUtil.contains(enumeration, element);
+ }
+
+ /**
+ * 涓嶅彲鍙� Set
+ *
+ * @param es 瀵硅薄
+ * @param <E> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ @SafeVarargs
+ public static <E> Set<E> ofImmutableSet(E... es) {
+ return CollectionUtil.ofImmutableSet(es);
+ }
+
+ /**
+ * 涓嶅彲鍙� List
+ *
+ * @param es 瀵硅薄
+ * @param <E> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ @SafeVarargs
+ public static <E> List<E> ofImmutableList(E... es) {
+ return CollectionUtil.ofImmutableList(es);
+ }
+
+ /**
+ * 寮鸿浆string,骞跺幓鎺夊浣欑┖鏍�
+ *
+ * @param str 瀛楃涓�
+ * @return {String}
+ */
+ public static String toStr(Object str) {
+ return toStr(str, "");
+ }
+
+ /**
+ * 寮鸿浆string,骞跺幓鎺夊浣欑┖鏍�
+ *
+ * @param str 瀛楃涓�
+ * @param defaultValue 榛樿鍊�
+ * @return {String}
+ */
+ public static String toStr(Object str, String defaultValue) {
+ if (null == str || str.equals(StringPool.NULL)) {
+ return defaultValue;
+ }
+ return String.valueOf(str);
+ }
+
+ /**
+ * 寮鸿浆string(鍖呭惈绌哄瓧绗︿覆),骞跺幓鎺夊浣欑┖鏍�
+ *
+ * @param str 瀛楃涓�
+ * @param defaultValue 榛樿鍊�
+ * @return {String}
+ */
+ public static String toStrWithEmpty(Object str, String defaultValue) {
+ if (null == str || str.equals(StringPool.NULL) || str.equals(StringPool.EMPTY)) {
+ return defaultValue;
+ }
+ return String.valueOf(str);
+ }
+
+
+ /**
+ * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁鏄暟瀛�
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {boolean}
+ */
+ public static boolean isNumeric(final CharSequence cs) {
+ return StringUtil.isNumeric(cs);
+ }
+
+ /**
+ * 瀛楃涓茶浆 int锛屼负绌哄垯杩斿洖0
+ *
+ * <pre>
+ * $.toInt(null) = 0
+ * $.toInt("") = 0
+ * $.toInt("1") = 1
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @return the int represented by the string, or <code>zero</code> if
+ * conversion fails
+ */
+ public static int toInt(final Object str) {
+ return NumberUtil.toInt(String.valueOf(str));
+ }
+
+ /**
+ * 瀛楃涓茶浆 int锛屼负绌哄垯杩斿洖榛樿鍊�
+ *
+ * <pre>
+ * $.toInt(null, 1) = 1
+ * $.toInt("", 1) = 1
+ * $.toInt("1", 0) = 1
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static int toInt(@Nullable final Object str, final int defaultValue) {
+ return NumberUtil.toInt(String.valueOf(str), defaultValue);
+ }
+
+ /**
+ * 瀛楃涓茶浆 long锛屼负绌哄垯杩斿洖0
+ *
+ * <pre>
+ * $.toLong(null) = 0L
+ * $.toLong("") = 0L
+ * $.toLong("1") = 1L
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @return the long represented by the string, or <code>0</code> if
+ * conversion fails
+ */
+ public static long toLong(final Object str) {
+ return NumberUtil.toLong(String.valueOf(str));
+ }
+
+ /**
+ * 瀛楃涓茶浆 long锛屼负绌哄垯杩斿洖榛樿鍊�
+ *
+ * <pre>
+ * $.toLong(null, 1L) = 1L
+ * $.toLong("", 1L) = 1L
+ * $.toLong("1", 0L) = 1L
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the long represented by the string, or the default if conversion fails
+ */
+ public static long toLong(@Nullable final Object str, final long defaultValue) {
+ return NumberUtil.toLong(String.valueOf(str), defaultValue);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>Double</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * $.toDouble(null, 1) = 1.0
+ * $.toDouble("", 1) = 1.0
+ * $.toDouble("1", 0) = 1.0
+ * </pre>
+ *
+ * @param value the string to convert, may be null
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static Double toDouble(Object value) {
+ return toDouble(String.valueOf(value), -1.00);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>Double</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * $.toDouble(null, 1) = 1.0
+ * $.toDouble("", 1) = 1.0
+ * $.toDouble("1", 0) = 1.0
+ * </pre>
+ *
+ * @param value the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static Double toDouble(Object value, Double defaultValue) {
+ return NumberUtil.toDouble(String.valueOf(value), defaultValue);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>Float</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * $.toFloat(null, 1) = 1.00f
+ * $.toFloat("", 1) = 1.00f
+ * $.toFloat("1", 0) = 1.00f
+ * </pre>
+ *
+ * @param value the string to convert, may be null
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static Float toFloat(Object value) {
+ return toFloat(String.valueOf(value), -1.0f);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>Float</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * $.toFloat(null, 1) = 1.00f
+ * $.toFloat("", 1) = 1.00f
+ * $.toFloat("1", 0) = 1.00f
+ * </pre>
+ *
+ * @param value the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static Float toFloat(Object value, Float defaultValue) {
+ return NumberUtil.toFloat(String.valueOf(value), defaultValue);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>Boolean</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * $.toBoolean("true", true) = true
+ * $.toBoolean("false") = false
+ * $.toBoolean("", false) = false
+ * </pre>
+ *
+ * @param value the string to convert, may be null
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static Boolean toBoolean(Object value) {
+ return toBoolean(value, null);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>Boolean</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * $.toBoolean("true", true) = true
+ * $.toBoolean("false") = false
+ * $.toBoolean("", false) = false
+ * </pre>
+ *
+ * @param value the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static Boolean toBoolean(Object value, Boolean defaultValue) {
+ if (value != null) {
+ String val = String.valueOf(value);
+ val = val.toLowerCase().trim();
+ return Boolean.parseBoolean(val);
+ }
+ return defaultValue;
+ }
+
+ /**
+ * 杞崲涓篒nteger鏁扮粍<br>
+ *
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Integer[] toIntArray(String str) {
+ return toIntArray(",", str);
+ }
+
+ /**
+ * 杞崲涓篒nteger鏁扮粍<br>
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Integer[] toIntArray(String split, String str) {
+ if (StringUtil.isEmpty(str)) {
+ return new Integer[]{};
+ }
+ String[] arr = str.split(split);
+ final Integer[] ints = new Integer[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ final Integer v = toInt(arr[i], 0);
+ ints[i] = v;
+ }
+ return ints;
+ }
+
+ /**
+ * 杞崲涓篒nteger闆嗗悎<br>
+ *
+ * @param str 缁撴灉琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static List<Integer> toIntList(String str) {
+ return Arrays.asList(toIntArray(str));
+ }
+
+ /**
+ * 杞崲涓篒nteger闆嗗悎<br>
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static List<Integer> toIntList(String split, String str) {
+ return Arrays.asList(toIntArray(split, str));
+ }
+
+ /**
+ * 鑾峰彇绗竴浣岻nteger鏁板��
+ *
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Integer firstInt(String str) {
+ return firstInt(",", str);
+ }
+
+ /**
+ * 鑾峰彇绗竴浣岻nteger鏁板��
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Integer firstInt(String split, String str) {
+ List<Integer> ints = toIntList(split, str);
+ if (isEmpty(ints)) {
+ return null;
+ } else {
+ return ints.get(0);
+ }
+ }
+
+ /**
+ * 杞崲涓篖ong鏁扮粍<br>
+ *
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Long[] toLongArray(String str) {
+ return toLongArray(",", str);
+ }
+
+ /**
+ * 杞崲涓篖ong鏁扮粍<br>
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Long[] toLongArray(String split, String str) {
+ if (StringUtil.isEmpty(str)) {
+ return new Long[]{};
+ }
+ String[] arr = str.split(split);
+ final Long[] longs = new Long[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ final Long v = toLong(arr[i], 0);
+ longs[i] = v;
+ }
+ return longs;
+ }
+
+ /**
+ * 杞崲涓篖ong闆嗗悎<br>
+ *
+ * @param str 缁撴灉琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static List<Long> toLongList(String str) {
+ return Arrays.asList(toLongArray(str));
+ }
+
+ /**
+ * 杞崲涓篖ong闆嗗悎<br>
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static List<Long> toLongList(String split, String str) {
+ return Arrays.asList(toLongArray(split, str));
+ }
+
+ /**
+ * 鑾峰彇绗竴浣峀ong鏁板��
+ *
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Long firstLong(String str) {
+ return firstLong(",", str);
+ }
+
+ /**
+ * 鑾峰彇绗竴浣峀ong鏁板��
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static Long firstLong(String split, String str) {
+ List<Long> longs = toLongList(split, str);
+ if (isEmpty(longs)) {
+ return null;
+ } else {
+ return longs.get(0);
+ }
+ }
+
+ /**
+ * 杞崲涓篠tring鏁扮粍<br>
+ *
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static String[] toStrArray(String str) {
+ return toStrArray(",", str);
+ }
+
+ /**
+ * 杞崲涓篠tring鏁扮粍<br>
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static String[] toStrArray(String split, String str) {
+ if (isBlank(str)) {
+ return new String[]{};
+ }
+ return str.split(split);
+ }
+
+ /**
+ * 杞崲涓篠tring闆嗗悎<br>
+ *
+ * @param str 缁撴灉琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static List<String> toStrList(String str) {
+ return Arrays.asList(toStrArray(str));
+ }
+
+ /**
+ * 杞崲涓篠tring闆嗗悎<br>
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static List<String> toStrList(String split, String str) {
+ return Arrays.asList(toStrArray(split, str));
+ }
+
+ /**
+ * 鑾峰彇绗竴浣峉tring鏁板��
+ *
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static String firstStr(String str) {
+ return firstStr(",", str);
+ }
+
+ /**
+ * 鑾峰彇绗竴浣峉tring鏁板��
+ *
+ * @param split 鍒嗛殧绗�
+ * @param str 琚浆鎹㈢殑鍊�
+ * @return 缁撴灉
+ */
+ public static String firstStr(String split, String str) {
+ List<String> strs = toStrList(split, str);
+ if (isEmpty(strs)) {
+ return null;
+ } else {
+ return strs.get(0);
+ }
+ }
+
+ /**
+ * 灏� long 杞煭瀛楃涓� 涓� 62 杩涘埗
+ *
+ * @param num 鏁板瓧
+ * @return 鐭瓧绗︿覆
+ */
+ public static String to62String(long num) {
+ return NumberUtil.to62String(num);
+ }
+
+ /**
+ * 灏嗛泦鍚堟嫾鎺ユ垚瀛楃涓诧紝榛樿浣跨敤`,`鎷兼帴
+ *
+ * @param coll the {@code Collection} to convert
+ * @return the delimited {@code String}
+ */
+ public static String join(Collection<?> coll) {
+ return StringUtil.join(coll);
+ }
+
+ /**
+ * 灏嗛泦鍚堟嫾鎺ユ垚瀛楃涓诧紝榛樿鎸囧畾鍒嗛殧绗�
+ *
+ * @param coll the {@code Collection} to convert
+ * @param delim the delimiter to use (typically a ",")
+ * @return the delimited {@code String}
+ */
+ public static String join(Collection<?> coll, String delim) {
+ return StringUtil.join(coll, delim);
+ }
+
+ /**
+ * 灏嗘暟缁勬嫾鎺ユ垚瀛楃涓诧紝榛樿浣跨敤`,`鎷兼帴
+ *
+ * @param arr the array to display
+ * @return the delimited {@code String}
+ */
+ public static String join(Object[] arr) {
+ return StringUtil.join(arr);
+ }
+
+ /**
+ * 灏嗘暟缁勬嫾鎺ユ垚瀛楃涓诧紝榛樿鎸囧畾鍒嗛殧绗�
+ *
+ * @param arr the array to display
+ * @param delim the delimiter to use (typically a ",")
+ * @return the delimited {@code String}
+ */
+ public static String join(Object[] arr, String delim) {
+ return StringUtil.join(arr, delim);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝涓嶅幓闄ゅ垏鍒嗗悗姣忎釜鍏冪礌涓よ竟鐨勭┖鐧界锛屼笉鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ */
+ public static List<String> split(CharSequence str, char separator) {
+ return StringUtil.split(str, separator, -1);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ */
+ public static List<String> splitTrim(CharSequence str, char separator) {
+ return StringUtil.splitTrim(str, separator);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ */
+ public static List<String> splitTrim(CharSequence str, CharSequence separator) {
+ return StringUtil.splitTrim(str, separator);
+ }
+
+ /**
+ * 鍒嗗壊 瀛楃涓�
+ *
+ * @param str 瀛楃涓�
+ * @param delimiter 鍒嗗壊绗�
+ * @return 瀛楃涓叉暟缁�
+ */
+ public static String[] split(@Nullable String str, @Nullable String delimiter) {
+ return StringUtil.delimitedListToStringArray(str, delimiter);
+ }
+
+ /**
+ * 鍒嗗壊 瀛楃涓� 鍒犻櫎甯歌 绌虹櫧绗�
+ *
+ * @param str 瀛楃涓�
+ * @param delimiter 鍒嗗壊绗�
+ * @return 瀛楃涓叉暟缁�
+ */
+ public static String[] splitTrim(@Nullable String str, @Nullable String delimiter) {
+ return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
+ }
+
+ /**
+ * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+ *
+ * <p>
+ * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+ * </p>
+ *
+ * @param pattern 琛ㄨ揪寮�
+ * @param str 瀛楃涓�
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
+ return PatternMatchUtils.simpleMatch(pattern, str);
+ }
+
+ /**
+ * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+ *
+ * <p>
+ * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+ * </p>
+ *
+ * @param patterns 琛ㄨ揪寮� 鏁扮粍
+ * @param str 瀛楃涓�
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean simpleMatch(@Nullable String[] patterns, String str) {
+ return PatternMatchUtils.simpleMatch(patterns, str);
+ }
+
+ /**
+ * 鐢熸垚uuid
+ *
+ * @return UUID
+ */
+ public static String randomUUID() {
+ return StringUtil.randomUUID();
+ }
+
+ /**
+ * 杞箟HTML鐢ㄤ簬瀹夊叏杩囨护
+ *
+ * @param html html
+ * @return {String}
+ */
+ public static String escapeHtml(String html) {
+ return StringUtil.escapeHtml(html);
+ }
+
+ /**
+ * 闅忔満鏁扮敓鎴�
+ *
+ * @param count 瀛楃闀垮害
+ * @return 闅忔満鏁�
+ */
+ public static String random(int count) {
+ return StringUtil.random(count);
+ }
+
+ /**
+ * 闅忔満鏁扮敓鎴�
+ *
+ * @param count 瀛楃闀垮害
+ * @param randomType 闅忔満鏁扮被鍒�
+ * @return 闅忔満鏁�
+ */
+ public static String random(int count, RandomType randomType) {
+ return StringUtil.random(count, randomType);
+ }
+
+ /**
+ * 瀛楃涓插簭鍒楀寲鎴� md5
+ *
+ * @param data Data to digest
+ * @return MD5 digest as a hex string
+ */
+ public static String md5Hex(final String data) {
+ return DigestUtil.md5Hex(data);
+ }
+
+ /**
+ * 鏁扮粍搴忓垪鍖栨垚 md5
+ *
+ * @param bytes the bytes to calculate the digest over
+ * @return md5 digest string
+ */
+ public static String md5Hex(final byte[] bytes) {
+ return DigestUtil.md5Hex(bytes);
+ }
+
+
+ /**
+ * sha1Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha1Hex(String data) {
+ return DigestUtil.sha1Hex(data);
+ }
+
+ /**
+ * sha1Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha1Hex(final byte[] bytes) {
+ return DigestUtil.sha1Hex(bytes);
+ }
+
+ /**
+ * SHA224Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha224Hex(String data) {
+ return DigestUtil.sha224Hex(data);
+ }
+
+ /**
+ * SHA224Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha224Hex(final byte[] bytes) {
+ return DigestUtil.sha224Hex(bytes);
+ }
+
+ /**
+ * sha256Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha256Hex(String data) {
+ return DigestUtil.sha256Hex(data);
+ }
+
+ /**
+ * sha256Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha256Hex(final byte[] bytes) {
+ return DigestUtil.sha256Hex(bytes);
+ }
+
+ /**
+ * sha384Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha384Hex(String data) {
+ return DigestUtil.sha384Hex(data);
+ }
+
+ /**
+ * sha384Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha384Hex(final byte[] bytes) {
+ return DigestUtil.sha384Hex(bytes);
+ }
+
+ /**
+ * sha512Hex
+ *
+ * @param data Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha512Hex(String data) {
+ return DigestUtil.sha512Hex(data);
+ }
+
+ /**
+ * sha512Hex
+ *
+ * @param bytes Data to digest
+ * @return digest as a hex string
+ */
+ public static String sha512Hex(final byte[] bytes) {
+ return DigestUtil.sha512Hex(bytes);
+ }
+
+ /**
+ * hmacMd5 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacMd5Hex(String data, String key) {
+ return DigestUtil.hmacMd5Hex(data, key);
+ }
+
+ /**
+ * hmacMd5 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacMd5Hex(final byte[] bytes, String key) {
+ return DigestUtil.hmacMd5Hex(bytes, key);
+ }
+
+ /**
+ * hmacSha1 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha1Hex(String data, String key) {
+ return DigestUtil.hmacSha1Hex(data, key);
+ }
+
+ /**
+ * hmacSha1 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha1Hex(final byte[] bytes, String key) {
+ return DigestUtil.hmacSha1Hex(bytes, key);
+ }
+
+ /**
+ * hmacSha224 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha224Hex(String data, String key) {
+ return DigestUtil.hmacSha224Hex(data, key);
+ }
+
+ /**
+ * hmacSha224 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha224Hex(final byte[] bytes, String key) {
+ return DigestUtil.hmacSha224Hex(bytes, key);
+ }
+
+ /**
+ * hmacSha256 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha256Hex(String data, String key) {
+ return DigestUtil.hmacSha256Hex(data, key);
+ }
+
+ /**
+ * hmacSha256 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha256Hex(final byte[] bytes, String key) {
+ return DigestUtil.hmacSha256Hex(bytes, key);
+ }
+
+ /**
+ * hmacSha384 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha384Hex(String data, String key) {
+ return DigestUtil.hmacSha384Hex(data, key);
+ }
+
+ /**
+ * hmacSha384 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha384Hex(final byte[] bytes, String key) {
+ return DigestUtil.hmacSha384Hex(bytes, key);
+ }
+
+ /**
+ * hmacSha512 Hex
+ *
+ * @param data Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha512Hex(String data, String key) {
+ return DigestUtil.hmacSha512Hex(data, key);
+ }
+
+ /**
+ * hmacSha512 Hex
+ *
+ * @param bytes Data to digest
+ * @param key key
+ * @return digest as a hex string
+ */
+ public static String hmacSha512Hex(final byte[] bytes, String key) {
+ return DigestUtil.hmacSha512Hex(bytes, key);
+ }
+
+ /**
+ * byte 鏁扮粍搴忓垪鍖栨垚 hex
+ *
+ * @param bytes bytes to encode
+ * @return MD5 digest as a hex string
+ */
+ public static String encodeHex(byte[] bytes) {
+ return DigestUtil.encodeHex(bytes);
+ }
+
+ /**
+ * 瀛楃涓插弽搴忓垪鍖栨垚 hex
+ *
+ * @param hexString String to decode
+ * @return MD5 digest as a hex string
+ */
+ public static byte[] decodeHex(final String hexString) {
+ return DigestUtil.decodeHex(hexString);
+ }
+
+ /**
+ * Base64缂栫爜
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String encodeBase64(String value) {
+ return Base64Util.encode(value);
+ }
+
+ /**
+ * Base64缂栫爜
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String encodeBase64(String value, Charset charset) {
+ return Base64Util.encode(value, charset);
+ }
+
+ /**
+ * Base64缂栫爜涓篣RL瀹夊叏
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String encodeBase64UrlSafe(String value) {
+ return Base64Util.encodeUrlSafe(value);
+ }
+
+ /**
+ * Base64缂栫爜涓篣RL瀹夊叏
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String encodeBase64UrlSafe(String value, Charset charset) {
+ return Base64Util.encodeUrlSafe(value, charset);
+ }
+
+ /**
+ * Base64瑙g爜
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String decodeBase64(String value) {
+ return Base64Util.decode(value);
+ }
+
+ /**
+ * Base64瑙g爜
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String decodeBase64(String value, Charset charset) {
+ return Base64Util.decode(value, charset);
+ }
+
+ /**
+ * Base64URL瀹夊叏瑙g爜
+ *
+ * @param value 瀛楃涓�
+ * @return {String}
+ */
+ public static String decodeBase64UrlSafe(String value) {
+ return Base64Util.decodeUrlSafe(value);
+ }
+
+ /**
+ * Base64URL瀹夊叏瑙g爜
+ *
+ * @param value 瀛楃涓�
+ * @param charset 瀛楃闆�
+ * @return {String}
+ */
+ public static String decodeBase64UrlSafe(String value, Charset charset) {
+ return Base64Util.decodeUrlSafe(value, charset);
+ }
+
+ /**
+ * 鍏抽棴 Closeable
+ *
+ * @param closeable 鑷姩鍏抽棴
+ */
+ public static void closeQuietly(@Nullable Closeable closeable) {
+ IoUtil.closeQuietly(closeable);
+ }
+
+ /**
+ * InputStream to String utf-8
+ *
+ * @param input the <code>InputStream</code> to read from
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ */
+ public static String readToString(InputStream input) {
+ return IoUtil.readToString(input);
+ }
+
+ /**
+ * InputStream to String
+ *
+ * @param input the <code>InputStream</code> to read from
+ * @param charset the <code>Charset</code>
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ */
+ public static String readToString(@Nullable InputStream input, Charset charset) {
+ return IoUtil.readToString(input, charset);
+ }
+
+ /**
+ * InputStream to bytes 鏁扮粍
+ *
+ * @param input InputStream
+ * @return the requested byte array
+ */
+ public static byte[] readToByteArray(@Nullable InputStream input) {
+ return IoUtil.readToByteArray(input);
+ }
+
+ /**
+ * 璇诲彇鏂囦欢涓哄瓧绗︿覆
+ *
+ * @param file the file to read, must not be {@code null}
+ * @return the file contents, never {@code null}
+ */
+ public static String readToString(final File file) {
+ return FileUtil.readToString(file);
+ }
+
+ /**
+ * 璇诲彇鏂囦欢涓哄瓧绗︿覆
+ *
+ * @param file the file to read, must not be {@code null}
+ * @param encoding the encoding to use, {@code null} means platform default
+ * @return the file contents, never {@code null}
+ */
+ public static String readToString(File file, Charset encoding) {
+ return FileUtil.readToString(file, encoding);
+ }
+
+ /**
+ * 璇诲彇鏂囦欢涓� byte 鏁扮粍
+ *
+ * @param file the file to read, must not be {@code null}
+ * @return the file contents, never {@code null}
+ */
+ public static byte[] readToByteArray(File file) {
+ return FileUtil.readToByteArray(file);
+ }
+
+ /**
+ * 灏嗗璞″簭鍒楀寲鎴恓son瀛楃涓�
+ *
+ * @param object javaBean
+ * @return jsonString json瀛楃涓�
+ */
+ public static String toJson(Object object) {
+ return JsonUtil.toJson(object);
+ }
+
+ /**
+ * 灏嗗璞″簭鍒楀寲鎴� json byte 鏁扮粍
+ *
+ * @param object javaBean
+ * @return jsonString json瀛楃涓�
+ */
+ public static byte[] toJsonAsBytes(Object object) {
+ return JsonUtil.toJsonAsBytes(object);
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param jsonString jsonString
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(String jsonString) {
+ return JsonUtil.readTree(jsonString);
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param in InputStream
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(InputStream in) {
+ return JsonUtil.readTree(in);
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param content content
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(byte[] content) {
+ return JsonUtil.readTree(content);
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param jsonParser JsonParser
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(JsonParser jsonParser) {
+ return JsonUtil.readTree(jsonParser);
+ }
+
+ /**
+ * 灏唈son byte 鏁扮粍鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param bytes json bytes
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T readJson(byte[] bytes, Class<T> valueType) {
+ return JsonUtil.parse(bytes, valueType);
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param jsonString jsonString
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T readJson(String jsonString, Class<T> valueType) {
+ return JsonUtil.parse(jsonString, valueType);
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param in InputStream
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T readJson(InputStream in, Class<T> valueType) {
+ return JsonUtil.parse(in, valueType);
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param bytes bytes
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T readJson(byte[] bytes, TypeReference<T> typeReference) {
+ return JsonUtil.parse(bytes, typeReference);
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param jsonString jsonString
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T readJson(String jsonString, TypeReference<T> typeReference) {
+ return JsonUtil.parse(jsonString, typeReference);
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param in InputStream
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T readJson(InputStream in, TypeReference<T> typeReference) {
+ return JsonUtil.parse(in, typeReference);
+ }
+
+ /**
+ * url 缂栫爜
+ *
+ * @param source the String to be encoded
+ * @return the encoded String
+ */
+ public static String urlEncode(String source) {
+ return UrlUtil.encode(source, Charsets.UTF_8);
+ }
+
+ /**
+ * url 缂栫爜
+ *
+ * @param source the String to be encoded
+ * @param charset the character encoding to encode to
+ * @return the encoded String
+ */
+ public static String urlEncode(String source, Charset charset) {
+ return UrlUtil.encode(source, charset);
+ }
+
+ /**
+ * url 瑙g爜
+ *
+ * @param source the encoded String
+ * @return the decoded value
+ * @throws IllegalArgumentException when the given source contains invalid encoded sequences
+ * @see StringUtils#uriDecode(String, Charset)
+ * @see java.net.URLDecoder#decode(String, String)
+ */
+ public static String urlDecode(String source) {
+ return StringUtils.uriDecode(source, Charsets.UTF_8);
+ }
+
+ /**
+ * url 瑙g爜
+ *
+ * @param source the encoded String
+ * @param charset the character encoding to use
+ * @return the decoded value
+ * @throws IllegalArgumentException when the given source contains invalid encoded sequences
+ * @see StringUtils#uriDecode(String, Charset)
+ * @see java.net.URLDecoder#decode(String, String)
+ */
+ public static String urlDecode(String source, Charset charset) {
+ return StringUtils.uriDecode(source, charset);
+ }
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTime(Date date) {
+ return DateUtil.formatDateTime(date);
+ }
+
+ /**
+ * 鏃ユ湡鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDate(Date date) {
+ return DateUtil.formatDate(date);
+ }
+
+ /**
+ * 鏃堕棿鏍煎紡鍖�
+ *
+ * @param date 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatTime(Date date) {
+ return DateUtil.formatTime(date);
+ }
+
+ /**
+ * 瀵硅薄鏍煎紡鍖� 鏀寔鏁板瓧锛宒ate锛宩ava8鏃堕棿
+ *
+ * @param object 鏍煎紡鍖栧璞�
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String format(Object object, String pattern) {
+ if (object instanceof Number) {
+ DecimalFormat decimalFormat = new DecimalFormat(pattern);
+ return decimalFormat.format(object);
+ } else if (object instanceof Date) {
+ return DateUtil.format((Date) object, pattern);
+ } else if (object instanceof TemporalAccessor) {
+ return DateTimeUtil.format((TemporalAccessor) object, pattern);
+ }
+ throw new IllegalArgumentException("鏈敮鎸佺殑瀵硅薄:" + object + ",鏍煎紡:" + object);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param pattern 琛ㄨ揪寮�
+ * @return 鏃堕棿
+ */
+ public static Date parseDate(String dateStr, String pattern) {
+ return DateUtil.parse(dateStr, pattern);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param format ConcurrentDateFormat
+ * @return 鏃堕棿
+ */
+ public static Date parse(String dateStr, ConcurrentDateFormat format) {
+ return DateUtil.parse(dateStr, format);
+ }
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDateTime(TemporalAccessor temporal) {
+ return DateTimeUtil.formatDateTime(temporal);
+ }
+
+ /**
+ * 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatDate(TemporalAccessor temporal) {
+ return DateTimeUtil.formatDate(temporal);
+ }
+
+ /**
+ * 鏃堕棿鏍煎紡鍖�
+ *
+ * @param temporal 鏃堕棿
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String formatTime(TemporalAccessor temporal) {
+ return DateTimeUtil.formatTime(temporal);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param formatter DateTimeFormatter
+ * @return 鏃堕棿
+ */
+ public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
+ return DateTimeUtil.parseDateTime(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @return 鏃堕棿
+ */
+ public static LocalDateTime parseDateTime(String dateStr) {
+ return DateTimeUtil.parseDateTime(dateStr);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param formatter DateTimeFormatter
+ * @return 鏃堕棿
+ */
+ public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
+ return DateTimeUtil.parseDate(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘棩鏈�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @return 鏃堕棿
+ */
+ public static LocalDate parseDate(String dateStr) {
+ return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @param formatter DateTimeFormatter
+ * @return 鏃堕棿
+ */
+ public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
+ return DateTimeUtil.parseTime(dateStr, formatter);
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆杞崲涓烘椂闂�
+ *
+ * @param dateStr 鏃堕棿瀛楃涓�
+ * @return 鏃堕棿
+ */
+ public static LocalTime parseTime(String dateStr) {
+ return DateTimeUtil.parseTime(dateStr);
+ }
+
+ /**
+ * 鏃堕棿姣旇緝
+ *
+ * @param startInclusive the start instant, inclusive, not null
+ * @param endExclusive the end instant, exclusive, not null
+ * @return a {@code Duration}, not null
+ */
+ public static Duration between(Temporal startInclusive, Temporal endExclusive) {
+ return Duration.between(startInclusive, endExclusive);
+ }
+
+ /**
+ * 姣旇緝2涓� 鏃堕棿宸�
+ *
+ * @param startDate 寮�濮嬫椂闂�
+ * @param endDate 缁撴潫鏃堕棿
+ * @return 鏃堕棿闂撮殧
+ */
+ public static Duration between(Date startDate, Date endDate) {
+ return DateUtil.between(startDate, endDate);
+ }
+
+ /**
+ * 瀵硅薄绫诲瀷杞崲
+ *
+ * @param source the source object
+ * @param targetType the target type
+ * @param <T> 娉涘瀷鏍囪
+ * @return the converted value
+ * @throws IllegalArgumentException if targetType is {@code null},
+ * or sourceType is {@code null} but source is not {@code null}
+ */
+ @Nullable
+ public static <T> T convert(@Nullable Object source, Class<T> targetType) {
+ return ConvertUtil.convert(source, targetType);
+ }
+
+ /**
+ * 瀵硅薄绫诲瀷杞崲
+ *
+ * @param source the source object
+ * @param sourceType the source type
+ * @param targetType the target type
+ * @param <T> 娉涘瀷鏍囪
+ * @return the converted value
+ * @throws IllegalArgumentException if targetType is {@code null},
+ * or sourceType is {@code null} but source is not {@code null}
+ */
+ @Nullable
+ public static <T> T convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
+ return ConvertUtil.convert(source, sourceType, targetType);
+ }
+
+ /**
+ * 瀵硅薄绫诲瀷杞崲
+ *
+ * @param source the source object
+ * @param targetType the target type
+ * @param <T> 娉涘瀷鏍囪
+ * @return the converted value
+ * @throws IllegalArgumentException if targetType is {@code null},
+ * or sourceType is {@code null} but source is not {@code null}
+ */
+ @Nullable
+ public static <T> T convert(@Nullable Object source, TypeDescriptor targetType) {
+ return ConvertUtil.convert(source, targetType);
+ }
+
+ /**
+ * 鑾峰彇鏂规硶鍙傛暟淇℃伅
+ *
+ * @param constructor 鏋勯�犲櫒
+ * @param parameterIndex 鍙傛暟搴忓彿
+ * @return {MethodParameter}
+ */
+ public static MethodParameter getMethodParameter(Constructor<?> constructor, int parameterIndex) {
+ return ClassUtil.getMethodParameter(constructor, parameterIndex);
+ }
+
+ /**
+ * 鑾峰彇鏂规硶鍙傛暟淇℃伅
+ *
+ * @param method 鏂规硶
+ * @param parameterIndex 鍙傛暟搴忓彿
+ * @return {MethodParameter}
+ */
+ public static MethodParameter getMethodParameter(Method method, int parameterIndex) {
+ return ClassUtil.getMethodParameter(method, parameterIndex);
+ }
+
+ /**
+ * 鑾峰彇Annotation娉ㄨВ
+ *
+ * @param annotatedElement AnnotatedElement
+ * @param annotationType 娉ㄨВ绫�
+ * @param <A> 娉涘瀷鏍囪
+ * @return {Annotation}
+ */
+ @Nullable
+ public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
+ return AnnotatedElementUtils.findMergedAnnotation(annotatedElement, annotationType);
+ }
+
+ /**
+ * 鑾峰彇Annotation锛屽厛鎵炬柟娉曪紝娌℃湁鍒欏啀鎵炬柟娉曚笂鐨勭被
+ *
+ * @param method Method
+ * @param annotationType 娉ㄨВ绫�
+ * @param <A> 娉涘瀷鏍囪
+ * @return {Annotation}
+ */
+ @Nullable
+ public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
+ return ClassUtil.getAnnotation(method, annotationType);
+ }
+
+ /**
+ * 鑾峰彇Annotation锛屽厛鎵綡andlerMethod锛屾病鏈夊垯鍐嶆壘瀵瑰簲鐨勭被
+ *
+ * @param handlerMethod HandlerMethod
+ * @param annotationType 娉ㄨВ绫�
+ * @param <A> 娉涘瀷鏍囪
+ * @return {Annotation}
+ */
+ @Nullable
+ public static <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
+ return ClassUtil.getAnnotation(handlerMethod, annotationType);
+ }
+
+ /**
+ * 瀹炰緥鍖栧璞�
+ *
+ * @param clazz 绫�
+ * @param <T> 娉涘瀷鏍囪
+ * @return 瀵硅薄
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T newInstance(Class<?> clazz) {
+ return (T) BeanUtil.instantiateClass(clazz);
+ }
+
+ /**
+ * 瀹炰緥鍖栧璞�
+ *
+ * @param clazzStr 绫诲悕
+ * @param <T> 娉涘瀷鏍囪
+ * @return 瀵硅薄
+ */
+ public static <T> T newInstance(String clazzStr) {
+ return BeanUtil.newInstance(clazzStr);
+ }
+
+ /**
+ * 鑾峰彇Bean鐨勫睘鎬�
+ *
+ * @param bean bean
+ * @param propertyName 灞炴�у悕
+ * @return 灞炴�у��
+ */
+ @Nullable
+ public static Object getProperty(@Nullable Object bean, String propertyName) {
+ return BeanUtil.getProperty(bean, propertyName);
+ }
+
+ /**
+ * 璁剧疆Bean灞炴��
+ *
+ * @param bean bean
+ * @param propertyName 灞炴�у悕
+ * @param value 灞炴�у��
+ */
+ public static void setProperty(Object bean, String propertyName, Object value) {
+ BeanUtil.setProperty(bean, propertyName, value);
+ }
+
+ /**
+ * 娴呭鍒�
+ *
+ * @param source 婧愬璞�
+ * @param <T> 娉涘瀷鏍囪
+ * @return T
+ */
+ @Nullable
+ public static <T> T clone(@Nullable T source) {
+ return BeanUtil.clone(source);
+ }
+
+ /**
+ * 鎷疯礉瀵硅薄锛屾敮鎸� Map 鍜� Bean
+ *
+ * @param source 婧愬璞�
+ * @param clazz 绫诲悕
+ * @param <T> 娉涘瀷鏍囪
+ * @return T
+ */
+ @Nullable
+ public static <T> T copy(@Nullable Object source, Class<T> clazz) {
+ return BeanUtil.copy(source, clazz);
+ }
+
+ /**
+ * 鎷疯礉瀵硅薄锛屾敮鎸� Map 鍜� Bean
+ *
+ * @param source 婧愬璞�
+ * @param targetBean 闇�瑕佽祴鍊肩殑瀵硅薄
+ */
+ public static void copy(@Nullable Object source, @Nullable Object targetBean) {
+ BeanUtil.copy(source, targetBean);
+ }
+
+ /**
+ * 鎷疯礉瀵硅薄锛宻ource 瀵硅薄灞炴�у仛闈� null 鍒ゆ柇
+ *
+ * <p>
+ * 鏀寔 map bean copy
+ * </p>
+ *
+ * @param source 婧愬璞�
+ * @param targetBean 闇�瑕佽祴鍊肩殑瀵硅薄
+ */
+ public static void copyNonNull(@Nullable Object source, @Nullable Object targetBean) {
+ BeanUtil.copyNonNull(source, targetBean);
+ }
+
+ /**
+ * 鎷疯礉瀵硅薄锛屽苟瀵逛笉鍚岀被鍨嬪睘鎬ц繘琛岃浆鎹�
+ *
+ * @param source 婧愬璞�
+ * @param clazz 绫诲悕
+ * @param <T> 娉涘瀷鏍囪
+ * @return T
+ */
+ @Nullable
+ public static <T> T copyWithConvert(@Nullable Object source, Class<T> clazz) {
+ return BeanUtil.copyWithConvert(source, clazz);
+ }
+
+ /**
+ * 鎷疯礉鍒楄〃瀵硅薄
+ *
+ * <p>
+ * 鏀寔 map bean copy
+ * </p>
+ *
+ * @param sourceList 婧愬垪琛�
+ * @param targetClazz 杞崲鎴愮殑绫诲瀷
+ * @param <T> 娉涘瀷鏍囪
+ * @return T
+ */
+ public static <T> List<T> copy(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
+ return BeanUtil.copy(sourceList, targetClazz);
+ }
+
+ /**
+ * 鎷疯礉鍒楄〃瀵硅薄锛屽苟瀵逛笉鍚岀被鍨嬪睘鎬ц繘琛岃浆鎹�
+ *
+ * <p>
+ * 鏀寔 map bean copy
+ * </p>
+ *
+ * @param sourceList 婧愬璞″垪琛�
+ * @param targetClazz 杞崲鎴愮殑绫�
+ * @param <T> 娉涘瀷鏍囪
+ * @return List
+ */
+ public static <T> List<T> copyWithConvert(@Nullable Collection<?> sourceList, Class<T> targetClazz) {
+ return BeanUtil.copyWithConvert(sourceList, targetClazz);
+ }
+
+ /**
+ * 鎷疯礉瀵硅薄锛屾墿灞� Spring 鐨勬嫹璐濇柟娉�
+ *
+ * @param source the source bean
+ * @param clazz the target bean class
+ * @param <T> 娉涘瀷鏍囪
+ * @return T
+ * @throws BeansException if the copying failed
+ */
+ @Nullable
+ public static <T> T copyProperties(@Nullable Object source, Class<T> clazz) throws BeansException {
+ return BeanUtil.copyProperties(source, clazz);
+ }
+
+ /**
+ * 鎷疯礉鍒楄〃瀵硅薄锛屾墿灞� Spring 鐨勬嫹璐濇柟娉�
+ *
+ * @param sourceList the source list bean
+ * @param targetClazz the target bean class
+ * @param <T> 娉涘瀷鏍囪
+ * @return List
+ * @throws BeansException if the copying failed
+ */
+ public static <T> List<T> copyProperties(@Nullable Collection<?> sourceList, Class<T> targetClazz) throws BeansException {
+ return BeanUtil.copyProperties(sourceList, targetClazz);
+ }
+
+ /**
+ * 灏嗗璞¤鎴恗ap褰㈠紡
+ *
+ * @param bean 婧愬璞�
+ * @return {Map}
+ */
+ public static Map<String, Object> toMap(@Nullable Object bean) {
+ return BeanUtil.toMap(bean);
+ }
+
+ /**
+ * 灏唌ap 杞负 bean
+ *
+ * @param beanMap map
+ * @param valueType 瀵硅薄绫诲瀷
+ * @param <T> 娉涘瀷鏍囪
+ * @return {T}
+ */
+ public static <T> T toBean(Map<String, Object> beanMap, Class<T> valueType) {
+ return BeanUtil.toBean(beanMap, valueType);
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java
new file mode 100644
index 0000000..ec11d04
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/Holder.java
@@ -0,0 +1,22 @@
+package com.vci.web.util;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+/**
+ * 涓�浜涘父鐢ㄧ殑鍗曚緥瀵硅薄
+ *
+ * @author L.cm
+ */
+public class Holder {
+
+ /**
+ * RANDOM
+ */
+ public final static Random RANDOM = new Random();
+
+ /**
+ * SECURE_RANDOM
+ */
+ public final static SecureRandom SECURE_RANDOM = new SecureRandom();
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java
new file mode 100644
index 0000000..836380e
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/IoUtil.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+/**
+ * 娴佸伐鍏风被
+ *
+ * @author L.cm
+ */
+public class IoUtil extends org.springframework.util.StreamUtils {
+
+ /**
+ * closeQuietly
+ *
+ * @param closeable 鑷姩鍏抽棴
+ */
+ public static void closeQuietly(@Nullable Closeable closeable) {
+ if (closeable == null) {
+ return;
+ }
+ if (closeable instanceof Flushable) {
+ try {
+ ((Flushable) closeable).flush();
+ } catch (IOException ignored) {
+ // ignore
+ }
+ }
+ try {
+ closeable.close();
+ } catch (IOException ignored) {
+ // ignore
+ }
+ }
+
+ /**
+ * InputStream to String utf-8
+ *
+ * @param input the <code>InputStream</code> to read from
+ * @return the requested String
+ */
+ public static String readToString(InputStream input) {
+ return readToString(input, Charsets.UTF_8);
+ }
+
+ /**
+ * InputStream to String
+ *
+ * @param input the <code>InputStream</code> to read from
+ * @param charset the <code>Charset</code>
+ * @return the requested String
+ */
+ public static String readToString(@Nullable InputStream input, Charset charset) {
+ try {
+ return IoUtil.copyToString(input, charset);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ } finally {
+ IoUtil.closeQuietly(input);
+ }
+ }
+
+ public static byte[] readToByteArray(@Nullable InputStream input) {
+ try {
+ return IoUtil.copyToByteArray(input);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ } finally {
+ IoUtil.closeQuietly(input);
+ }
+ }
+
+ /**
+ * Writes chars from a <code>String</code> to bytes on an
+ * <code>OutputStream</code> using the specified character encoding.
+ * <p>
+ * This method uses {@link String#getBytes(String)}.
+ * </p>
+ * @param data the <code>String</code> to write, null ignored
+ * @param output the <code>OutputStream</code> to write to
+ * @param encoding the encoding to use, null means platform default
+ * @throws NullPointerException if output is null
+ * @throws IOException if an I/O error occurs
+ */
+ public static void write(@Nullable final String data, final OutputStream output, final Charset encoding) throws IOException {
+ if (data != null) {
+ output.write(data.getBytes(encoding));
+ }
+ }
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java
new file mode 100644
index 0000000..c493791
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/NumberUtil.java
@@ -0,0 +1,195 @@
+package com.vci.web.util;
+
+
+import org.springframework.lang.Nullable;
+
+/**
+ * 鏁板瓧绫诲瀷宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class NumberUtil extends org.springframework.util.NumberUtils {
+
+ //-----------------------------------------------------------------------
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>int</code>, returning
+ * <code>zero</code> if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
+ *
+ * <pre>
+ * NumberUtil.toInt(null) = 0
+ * NumberUtil.toInt("") = 0
+ * NumberUtil.toInt("1") = 1
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @return the int represented by the string, or <code>zero</code> if
+ * conversion fails
+ */
+ public static int toInt(final String str) {
+ return toInt(str, -1);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to an <code>int</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * NumberUtil.toInt(null, 1) = 1
+ * NumberUtil.toInt("", 1) = 1
+ * NumberUtil.toInt("1", 0) = 1
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the int represented by the string, or the default if conversion fails
+ */
+ public static int toInt(@Nullable final String str, final int defaultValue) {
+ if (str == null) {
+ return defaultValue;
+ }
+ try {
+ return Integer.valueOf(str);
+ } catch (final NumberFormatException nfe) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to a <code>long</code>, returning
+ * <code>zero</code> if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
+ *
+ * <pre>
+ * NumberUtil.toLong(null) = 0L
+ * NumberUtil.toLong("") = 0L
+ * NumberUtil.toLong("1") = 1L
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @return the long represented by the string, or <code>0</code> if
+ * conversion fails
+ */
+ public static long toLong(final String str) {
+ return toLong(str, 0L);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to a <code>long</code>, returning a
+ * default value if the conversion fails.</p>
+ *
+ * <p>If the string is <code>null</code>, the default value is returned.</p>
+ *
+ * <pre>
+ * NumberUtil.toLong(null, 1L) = 1L
+ * NumberUtil.toLong("", 1L) = 1L
+ * NumberUtil.toLong("1", 0L) = 1L
+ * </pre>
+ *
+ * @param str the string to convert, may be null
+ * @param defaultValue the default value
+ * @return the long represented by the string, or the default if conversion fails
+ */
+ public static long toLong(@Nullable final String str, final long defaultValue) {
+ if (str == null) {
+ return defaultValue;
+ }
+ try {
+ return Long.valueOf(str);
+ } catch (final NumberFormatException nfe) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to a <code>Double</code>
+ *
+ * @param value value
+ * @return double value
+ */
+ public static Double toDouble(String value) {
+ return toDouble(value, null);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to a <code>Double</code>
+ *
+ * @param value value
+ * @param defaultValue 榛樿鍊�
+ * @return double value
+ */
+ public static Double toDouble(@Nullable String value, Double defaultValue) {
+ if (value != null) {
+ return Double.valueOf(value.trim());
+ }
+ return defaultValue;
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to a <code>Double</code>
+ *
+ * @param value value
+ * @return double value
+ */
+ public static Float toFloat(String value) {
+ return toFloat(value, null);
+ }
+
+ /**
+ * <p>Convert a <code>String</code> to a <code>Double</code>
+ *
+ * @param value value
+ * @param defaultValue 榛樿鍊�
+ * @return double value
+ */
+ public static Float toFloat(@Nullable String value, Float defaultValue) {
+ if (value != null) {
+ return Float.valueOf(value.trim());
+ }
+ return defaultValue;
+ }
+
+ /**
+ * All possible chars for representing a number as a String
+ */
+ private final static char[] DIGITS = {
+ '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'a', 'b',
+ 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z',
+ 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L',
+ 'M', 'N', 'O', 'P', 'Q', 'R',
+ 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z'
+ };
+
+ /**
+ * 灏� long 杞煭瀛楃涓� 涓� 62 杩涘埗
+ *
+ * @param i 鏁板瓧
+ * @return 鐭瓧绗︿覆
+ */
+ public static String to62String(long i) {
+ int radix = DIGITS.length;
+ char[] buf = new char[65];
+ int charPos = 64;
+ i = -i;
+ while (i <= -radix) {
+ buf[charPos--] = DIGITS[(int) (-(i % radix))];
+ i = i / radix;
+ }
+ buf[charPos] = DIGITS[(int) (-i)];
+
+ return new String(buf, charPos, (65 - charPos));
+ }
+
+}
+
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java
new file mode 100644
index 0000000..da05460
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/ObjectUtil.java
@@ -0,0 +1,21 @@
+package com.vci.web.util;
+
+import org.springframework.lang.Nullable;
+
+/**
+ * 瀵硅薄宸ュ叿绫�
+ *
+ * @author L.cm
+ */
+public class ObjectUtil extends org.springframework.util.ObjectUtils {
+
+ /**
+ * 鍒ゆ柇鍏冪礌涓嶄负绌�
+ * @param obj object
+ * @return boolean
+ */
+ public static boolean isNotEmpty(@Nullable Object obj) {
+ return !ObjectUtil.isEmpty(obj);
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java
new file mode 100644
index 0000000..98da4bc
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/RandomType.java
@@ -0,0 +1,30 @@
+package com.vci.web.util;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 鐢熸垚鐨勯殢鏈烘暟绫诲瀷
+ *
+ * @author L.cm
+ */
+@Getter
+@RequiredArgsConstructor
+public enum RandomType {
+ /**
+ * INT STRING ALL
+ */
+ INT(RandomType.INT_STR),
+ STRING(RandomType.STR_STR),
+ ALL(RandomType.ALL_STR);
+
+ private final String factor;
+
+ /**
+ * 闅忔満瀛楃涓插洜瀛�
+ */
+ private static final String INT_STR = "0123456789";
+ private static final String STR_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ private static final String ALL_STR = INT_STR + STR_STR;
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java
new file mode 100644
index 0000000..5dd92d7
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringPool.java
@@ -0,0 +1,71 @@
+package com.vci.web.util;
+
+/**
+ * 闈欐�� String 姹�
+ *
+ * @author L.cm
+ */
+public interface StringPool {
+
+ String AMPERSAND = "&";
+ String AND = "and";
+ String AT = "@";
+ String ASTERISK = "*";
+ String STAR = ASTERISK;
+ String SLASH = "/";
+ String BACK_SLASH = "\\";
+ String DOUBLE_SLASH = "#//";
+ String COLON = ":";
+ String COMMA = ",";
+ String DASH = "-";
+ String DOLLAR = "$";
+ String DOT = ".";
+ String EMPTY = "";
+ String EMPTY_JSON = "{}";
+ String EQUALS = "=";
+ String FALSE = "false";
+ String HASH = "#";
+ String HAT = "^";
+ String LEFT_BRACE = "{";
+ String LEFT_BRACKET = "(";
+ String LEFT_CHEV = "<";
+ String NEWLINE = "\n";
+ String N = "n";
+ String NO = "no";
+ String NULL = "null";
+ String OFF = "off";
+ String ON = "on";
+ String PERCENT = "%";
+ String PIPE = "|";
+ String PLUS = "+";
+ String QUESTION_MARK = "?";
+ String EXCLAMATION_MARK = "!";
+ String QUOTE = "\"";
+ String RETURN = "\r";
+ String TAB = "\t";
+ String RIGHT_BRACE = "}";
+ String RIGHT_BRACKET = ")";
+ String RIGHT_CHEV = ">";
+ String SEMICOLON = ";";
+ String SINGLE_QUOTE = "'";
+ String BACKTICK = "`";
+ String SPACE = " ";
+ String TILDA = "~";
+ String LEFT_SQ_BRACKET = "[";
+ String RIGHT_SQ_BRACKET = "]";
+ String TRUE = "true";
+ String UNDERSCORE = "_";
+ String UTF_8 = "UTF-8";
+ String GBK = "GBK";
+ String ISO_8859_1 = "ISO-8859-1";
+ String Y = "y";
+ String YES = "yes";
+ String ONE = "1";
+ String ZERO = "0";
+ String MINUS_ONE = "-1";
+ String DOLLAR_LEFT_BRACE= "${";
+ String UNKNOWN = "unknown";
+ String GET = "GET";
+ String POST = "POST";
+
+}
\ No newline at end of file
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java
new file mode 100644
index 0000000..c062a75
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/StringUtil.java
@@ -0,0 +1,1560 @@
+package com.vci.web.util;
+
+import cn.hutool.core.util.ObjectUtil;
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.PatternMatchUtils;
+import org.springframework.web.util.HtmlUtils;
+import com.vci.web.support.StrSpliter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+/**
+ * 缁ф壙鑷猄pring util鐨勫伐鍏风被锛屽噺灏慾ar渚濊禆
+ *
+ * @author L.cm
+ */
+public class StringUtil extends org.springframework.util.StringUtils {
+
+ public static final int INDEX_NOT_FOUND = -1;
+ // public static final int INDEX_NOT_FOUND = 0;
+
+ /**
+ * Check whether the given {@code CharSequence} contains actual <em>text</em>.
+ * <p>More specifically, this method returns {@code true} if the
+ * {@code CharSequence} is not {@code null}, its length is greater than
+ * 0, and it contains at least one non-whitespace character.
+ * <pre class="code">
+ * StringUtil.isBlank(null) = true
+ * StringUtil.isBlank("") = true
+ * StringUtil.isBlank(" ") = true
+ * StringUtil.isBlank("12345") = false
+ * StringUtil.isBlank(" 12345 ") = false
+ * </pre>
+ *
+ * @param cs the {@code CharSequence} to check (may be {@code null})
+ * @return {@code true} if the {@code CharSequence} is not {@code null},
+ * its length is greater than 0, and it does not contain whitespace only
+ * @see Character#isWhitespace
+ */
+ public static boolean isBlank(final CharSequence cs) {
+ return !StringUtil.hasText(cs);
+ }
+
+ /**
+ * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
+ * <pre>
+ * StringUtil.isNotBlank(null) = false
+ * StringUtil.isNotBlank("") = false
+ * StringUtil.isNotBlank(" ") = false
+ * StringUtil.isNotBlank("bob") = true
+ * StringUtil.isNotBlank(" bob ") = true
+ * </pre>
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {@code true} if the CharSequence is
+ * not empty and not null and not whitespace
+ * @see Character#isWhitespace
+ */
+ public static boolean isNotBlank(final CharSequence cs) {
+ return StringUtil.hasText(cs);
+ }
+
+ /**
+ * 鏈� 浠绘剰 涓�涓� Blank
+ *
+ * @param css CharSequence
+ * @return boolean
+ */
+ public static boolean isAnyBlank(final CharSequence... css) {
+ if (ObjectUtil.isEmpty(css)) {
+ return true;
+ }
+ return Stream.of(css).anyMatch(StringUtil::isBlank);
+ }
+
+ /**
+ * 鏄惁鍏ㄩ潪 Blank
+ *
+ * @param css CharSequence
+ * @return boolean
+ */
+ public static boolean isNoneBlank(final CharSequence... css) {
+ if (ObjectUtil.isEmpty(css)) {
+ return false;
+ }
+ return Stream.of(css).allMatch(StringUtil::isNotBlank);
+ }
+
+ /**
+ * 鏄惁鍏ㄤ负 Blank
+ *
+ * @param css CharSequence
+ * @return boolean
+ */
+ public static boolean isAllBlank(final CharSequence... css) {
+ return Stream.of(css).allMatch(StringUtil::isBlank);
+ }
+
+ /**
+ * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁鏄暟瀛�
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {boolean}
+ */
+ public static boolean isNumeric(final CharSequence cs) {
+ if (isBlank(cs)) {
+ return false;
+ }
+ for (int i = cs.length(); --i >= 0; ) {
+ int chr = cs.charAt(i);
+ if (chr < 48 || chr > 57) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆涓壒瀹氭ā寮忕殑瀛楃杞崲鎴恗ap涓搴旂殑鍊�
+ * <p>
+ * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
+ *
+ * @param message 闇�瑕佽浆鎹㈢殑瀛楃涓�
+ * @param params 杞崲鎵�闇�鐨勯敭鍊煎闆嗗悎
+ * @return 杞崲鍚庣殑瀛楃涓�
+ */
+ public static String format(@Nullable String message, @Nullable Map<String, ?> params) {
+ // message 涓� null 杩斿洖绌哄瓧绗︿覆
+ if (message == null) {
+ return StringPool.EMPTY;
+ }
+ // 鍙傛暟涓� null 鎴栬�呬负绌�
+ if (params == null || params.isEmpty()) {
+ return message;
+ }
+ // 鏇挎崲鍙橀噺
+ StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
+ int cursor = 0;
+ for (int start, end; (start = message.indexOf(StringPool.DOLLAR_LEFT_BRACE, cursor)) != -1 && (end = message.indexOf(StringPool.RIGHT_BRACE, start)) != -1; ) {
+ sb.append(message, cursor, start);
+ String key = message.substring(start + 2, end);
+ Object value = params.get(StringUtil.trimWhitespace(key));
+ sb.append(value == null ? StringPool.EMPTY : value);
+ cursor = end + 1;
+ }
+ sb.append(message.substring(cursor));
+ return sb.toString();
+ }
+
+ /**
+ * 鍚� log 鏍煎紡鐨� format 瑙勫垯
+ * <p>
+ * use: format("my name is {}, and i like {}!", "L.cm", "Java")
+ *
+ * @param message 闇�瑕佽浆鎹㈢殑瀛楃涓�
+ * @param arguments 闇�瑕佹浛鎹㈢殑鍙橀噺
+ * @return 杞崲鍚庣殑瀛楃涓�
+ */
+ public static String format(@Nullable String message, @Nullable Object... arguments) {
+ // message 涓� null 杩斿洖绌哄瓧绗︿覆
+ if (message == null) {
+ return StringPool.EMPTY;
+ }
+ // 鍙傛暟涓� null 鎴栬�呬负绌�
+ if (arguments == null || arguments.length == 0) {
+ return message;
+ }
+ StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
+ int cursor = 0;
+ int index = 0;
+ int argsLength = arguments.length;
+ for (int start, end; (start = message.indexOf('{', cursor)) != -1 && (end = message.indexOf('}', start)) != -1 && index < argsLength; ) {
+ sb.append(message, cursor, start);
+ sb.append(arguments[index]);
+ cursor = end + 1;
+ index++;
+ }
+ sb.append(message.substring(cursor));
+ return sb.toString();
+ }
+
+ /**
+ * 鏍煎紡鍖栨墽琛屾椂闂达紝鍗曚綅涓� ms 鍜� s锛屼繚鐣欎笁浣嶅皬鏁�
+ *
+ * @param nanos 绾崇
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂�
+ */
+ public static String format(long nanos) {
+ if (nanos < 1) {
+ return "0ms";
+ }
+ double millis = (double) nanos / (1000 * 1000);
+ // 涓嶅 1 ms锛屾渶灏忓崟浣嶄负 ms
+ if (millis > 1000) {
+ return String.format("%.3fs", millis / 1000);
+ } else {
+ return String.format("%.3fms", millis);
+ }
+ }
+
+ /**
+ * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV).
+ * <p>Useful for {@code toString()} implementations.
+ *
+ * @param coll the {@code Collection} to convert
+ * @return the delimited {@code String}
+ */
+ public static String join(Collection<?> coll) {
+ return StringUtil.collectionToCommaDelimitedString(coll);
+ }
+
+ /**
+ * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV).
+ * <p>Useful for {@code toString()} implementations.
+ *
+ * @param coll the {@code Collection} to convert
+ * @param delim the delimiter to use (typically a ",")
+ * @return the delimited {@code String}
+ */
+ public static String join(Collection<?> coll, String delim) {
+ return StringUtil.collectionToDelimitedString(coll, delim);
+ }
+
+ /**
+ * Convert a {@code String} array into a comma delimited {@code String}
+ * (i.e., CSV).
+ * <p>Useful for {@code toString()} implementations.
+ *
+ * @param arr the array to display
+ * @return the delimited {@code String}
+ */
+ public static String join(Object[] arr) {
+ return StringUtil.arrayToCommaDelimitedString(arr);
+ }
+
+ /**
+ * Convert a {@code String} array into a delimited {@code String} (e.g. CSV).
+ * <p>Useful for {@code toString()} implementations.
+ *
+ * @param arr the array to display
+ * @param delim the delimiter to use (typically a ",")
+ * @return the delimited {@code String}
+ */
+ public static String join(Object[] arr, String delim) {
+ return StringUtil.arrayToDelimitedString(arr, delim);
+ }
+
+ /**
+ * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+ *
+ * <p>
+ * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+ * </p>
+ *
+ * @param pattern 琛ㄨ揪寮�
+ * @param str 瀛楃涓�
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
+ return PatternMatchUtils.simpleMatch(pattern, str);
+ }
+
+ /**
+ * 瀛楃涓叉槸鍚︾鍚堟寚瀹氱殑 琛ㄨ揪寮�
+ *
+ * <p>
+ * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
+ * </p>
+ *
+ * @param patterns 琛ㄨ揪寮� 鏁扮粍
+ * @param str 瀛楃涓�
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean simpleMatch(@Nullable String[] patterns, String str) {
+ return PatternMatchUtils.simpleMatch(patterns, str);
+ }
+
+ /**
+ * 鐢熸垚uuid
+ *
+ * @return UUID
+ */
+ public static String randomUUID() {
+ ThreadLocalRandom random = ThreadLocalRandom.current();
+ return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
+ }
+
+ /**
+ * 杞箟HTML鐢ㄤ簬瀹夊叏杩囨护
+ *
+ * @param html html
+ * @return {String}
+ */
+ public static String escapeHtml(String html) {
+ return StringUtil.isBlank(html) ? StringPool.EMPTY : HtmlUtils.htmlEscape(html);
+ }
+
+ /**
+ * 娓呯悊瀛楃涓诧紝娓呯悊鍑烘煇浜涗笉鍙瀛楃
+ *
+ * @param txt 瀛楃涓�
+ * @return {String}
+ */
+ public static String cleanChars(String txt) {
+ return txt.replaceAll("[ 銆�`路鈥拷\\f\\t\\v\\s]", "");
+ }
+
+ /**
+ * 鐗规畩瀛楃姝e垯锛宻ql鐗规畩瀛楃鍜岀┖鐧界
+ */
+ private final static Pattern SPECIAL_CHARS_REGEX = Pattern.compile("[`'\"|/,;()-+*%#路鈥拷銆�\\s]");
+
+ /**
+ * 娓呯悊瀛楃涓诧紝娓呯悊鍑烘煇浜涗笉鍙瀛楃鍜屼竴浜泂ql鐗规畩瀛楃
+ *
+ * @param txt 鏂囨湰
+ * @return {String}
+ */
+ @Nullable
+ public static String cleanText(@Nullable String txt) {
+ if (txt == null) {
+ return null;
+ }
+ return SPECIAL_CHARS_REGEX.matcher(txt).replaceAll(StringPool.EMPTY);
+ }
+
+ /**
+ * 鑾峰彇鏍囪瘑绗︼紝鐢ㄤ簬鍙傛暟娓呯悊
+ *
+ * @param param 鍙傛暟
+ * @return 娓呯悊鍚庣殑鏍囪瘑绗�
+ */
+ @Nullable
+ public static String cleanIdentifier(@Nullable String param) {
+ if (param == null) {
+ return null;
+ }
+ StringBuilder paramBuilder = new StringBuilder();
+ for (int i = 0; i < param.length(); i++) {
+ char c = param.charAt(i);
+ if (Character.isJavaIdentifierPart(c)) {
+ paramBuilder.append(c);
+ }
+ }
+ return paramBuilder.toString();
+ }
+
+ /**
+ * 闅忔満鏁扮敓鎴�
+ *
+ * @param count 瀛楃闀垮害
+ * @return 闅忔満鏁�
+ */
+ public static String random(int count) {
+ return StringUtil.random(count, RandomType.ALL);
+ }
+
+ /**
+ * 闅忔満鏁扮敓鎴�
+ *
+ * @param count 瀛楃闀垮害
+ * @param randomType 闅忔満鏁扮被鍒�
+ * @return 闅忔満鏁�
+ */
+ public static String random(int count, RandomType randomType) {
+ if (count == 0) {
+ return StringPool.EMPTY;
+ }
+ Assert.isTrue(count > 0, "Requested random string length " + count + " is less than 0.");
+ final Random random = Holder.SECURE_RANDOM;
+ char[] buffer = new char[count];
+ for (int i = 0; i < count; i++) {
+ String factor = randomType.getFactor();
+ buffer[i] = factor.charAt(random.nextInt(factor.length()));
+ }
+ return new String(buffer);
+ }
+
+ /**
+ * 鏈夊簭鐨勬牸寮忓寲鏂囨湰锛屼娇鐢▄number}鍋氫负鍗犱綅绗�<br>
+ * 渚嬶細<br>
+ * 閫氬父浣跨敤锛歠ormat("this is {0} for {1}", "a", "b") =銆� this is a for b<br>
+ *
+ * @param pattern 鏂囨湰鏍煎紡
+ * @param arguments 鍙傛暟
+ * @return 鏍煎紡鍖栧悗鐨勬枃鏈�
+ */
+ public static String indexedFormat(CharSequence pattern, Object... arguments) {
+ return MessageFormat.format(pattern.toString(), arguments);
+ }
+
+ /**
+ * 鏍煎紡鍖栨枃鏈紝浣跨敤 {varName} 鍗犱綅<br>
+ * map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=銆� aValue and bValue
+ *
+ * @param template 鏂囨湰妯℃澘锛岃鏇挎崲鐨勯儴鍒嗙敤 {key} 琛ㄧず
+ * @param map 鍙傛暟鍊煎
+ * @return 鏍煎紡鍖栧悗鐨勬枃鏈�
+ */
+ public static String format(CharSequence template, Map<?, ?> map) {
+ if (null == template) {
+ return null;
+ }
+ if (null == map || map.isEmpty()) {
+ return template.toString();
+ }
+
+ String template2 = template.toString();
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
+ template2 = template2.replace("{" + entry.getKey() + "}", Func.toStr(entry.getValue()));
+ }
+ return template2;
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝涓嶅幓闄ゅ垏鍒嗗悗姣忎釜鍏冪礌涓よ竟鐨勭┖鐧界锛屼笉鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ */
+ public static List<String> split(CharSequence str, char separator, int limit) {
+ return split(str, separator, limit, false, false);
+ }
+
+ /**
+ * 鍒嗗壊 瀛楃涓� 鍒犻櫎甯歌 绌虹櫧绗�
+ *
+ * @param str 瀛楃涓�
+ * @param delimiter 鍒嗗壊绗�
+ * @return 瀛楃涓叉暟缁�
+ */
+ public static String[] splitTrim(@Nullable String str, @Nullable String delimiter) {
+ return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.1.2
+ */
+ public static List<String> splitTrim(CharSequence str, char separator) {
+ return splitTrim(str, separator, -1);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.0
+ */
+ public static List<String> splitTrim(CharSequence str, CharSequence separator) {
+ return splitTrim(str, separator, -1);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.1.0
+ */
+ public static List<String> splitTrim(CharSequence str, char separator, int limit) {
+ return split(str, separator, limit, true, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝鍘婚櫎鍒囧垎鍚庢瘡涓厓绱犱袱杈圭殑绌虹櫧绗︼紝鍘婚櫎绌虹櫧椤�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.0
+ */
+ public static List<String> splitTrim(CharSequence str, CharSequence separator, int limit) {
+ return split(str, separator, limit, true, true);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓诧紝涓嶉檺鍒跺垎鐗囨暟閲�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(CharSequence str, char separator, boolean isTrim, boolean ignoreEmpty) {
+ return split(str, separator, 0, isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.0.8
+ */
+ public static List<String> split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ if (null == str) {
+ return new ArrayList<>(0);
+ }
+ return StrSpliter.split(str.toString(), separator, limit, isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗﹀瓧绗�
+ * @param limit 闄愬埗鍒嗙墖鏁帮紝-1涓嶉檺鍒�
+ * @param isTrim 鏄惁鍘婚櫎鍒囧垎瀛楃涓插悗姣忎釜鍏冪礌涓よ竟鐨勭┖鏍�
+ * @param ignoreEmpty 鏄惁蹇界暐绌轰覆
+ * @return 鍒囧垎鍚庣殑闆嗗悎
+ * @since 3.2.0
+ */
+ public static List<String> split(CharSequence str, CharSequence separator, int limit, boolean isTrim, boolean ignoreEmpty) {
+ if (null == str) {
+ return new ArrayList<>(0);
+ }
+ final String separatorStr = (null == separator) ? null : separator.toString();
+ return StrSpliter.split(str.toString(), separatorStr, limit, isTrim, ignoreEmpty);
+ }
+
+ /**
+ * 鍒囧垎瀛楃涓�
+ *
+ * @param str 琚垏鍒嗙殑瀛楃涓�
+ * @param separator 鍒嗛殧绗�
+ * @return 瀛楃涓�
+ */
+ public static String[] split(CharSequence str, CharSequence separator) {
+ if (str == null) {
+ return new String[]{};
+ }
+
+ final String separatorStr = (null == separator) ? null : separator.toString();
+ return StrSpliter.splitToArray(str.toString(), separatorStr, 0, false, false);
+ }
+
+ /**
+ * 鏍规嵁缁欏畾闀垮害锛屽皢缁欏畾瀛楃涓叉埅鍙栦负澶氫釜閮ㄥ垎
+ *
+ * @param str 瀛楃涓�
+ * @param len 姣忎竴涓皬鑺傜殑闀垮害
+ * @return 鎴彇鍚庣殑瀛楃涓叉暟缁�
+ * @see StrSpliter#splitByLength(String, int)
+ */
+ public static String[] split(CharSequence str, int len) {
+ if (null == str) {
+ return new String[]{};
+ }
+ return StrSpliter.splitByLength(str.toString(), len);
+ }
+
+ /**
+ * 鎸囧畾瀛楃鏄惁鍦ㄥ瓧绗︿覆涓嚭鐜拌繃
+ *
+ * @param str 瀛楃涓�
+ * @param searchChar 琚煡鎵剧殑瀛楃
+ * @return 鏄惁鍖呭惈
+ * @since 3.1.2
+ */
+ public static boolean contains(CharSequence str, char searchChar) {
+ return indexOf(str, searchChar) > -1;
+ }
+
+ /**
+ * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆
+ *
+ * @param str 鎸囧畾瀛楃涓�
+ * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+ * @return 鏄惁鍖呭惈浠绘剰涓�涓瓧绗︿覆
+ * @since 3.2.0
+ */
+ public static boolean containsAny(CharSequence str, CharSequence... testStrs) {
+ return null != getContainsStr(str, testStrs);
+ }
+
+ /**
+ * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆锛屽鏋滃寘鍚繑鍥炴壘鍒扮殑绗竴涓瓧绗︿覆
+ *
+ * @param str 鎸囧畾瀛楃涓�
+ * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+ * @return 琚寘鍚殑绗竴涓瓧绗︿覆
+ * @since 3.2.0
+ */
+ public static String getContainsStr(CharSequence str, CharSequence... testStrs) {
+ if (isEmpty(str) || Func.isEmpty(testStrs)) {
+ return null;
+ }
+ for (CharSequence checkStr : testStrs) {
+ if (str.toString().contains(checkStr)) {
+ return checkStr.toString();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 鏄惁鍖呭惈鐗瑰畾瀛楃锛屽拷鐣ュぇ灏忓啓锛屽鏋滅粰瀹氫袱涓弬鏁伴兘涓�<code>null</code>锛岃繑鍥瀟rue
+ *
+ * @param str 琚娴嬪瓧绗︿覆
+ * @param testStr 琚祴璇曟槸鍚﹀寘鍚殑瀛楃涓�
+ * @return 鏄惁鍖呭惈
+ */
+ public static boolean containsIgnoreCase(CharSequence str, CharSequence testStr) {
+ if (null == str) {
+ // 濡傛灉琚洃娴嬪瓧绗︿覆鍜�
+ return null == testStr;
+ }
+ return str.toString().toLowerCase().contains(testStr.toString().toLowerCase());
+ }
+
+ /**
+ * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆<br>
+ * 蹇界暐澶у皬鍐�
+ *
+ * @param str 鎸囧畾瀛楃涓�
+ * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+ * @return 鏄惁鍖呭惈浠绘剰涓�涓瓧绗︿覆
+ * @since 3.2.0
+ */
+ public static boolean containsAnyIgnoreCase(CharSequence str, CharSequence... testStrs) {
+ return null != getContainsStrIgnoreCase(str, testStrs);
+ }
+
+ /**
+ * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀寘鍚寚瀹氬瓧绗︿覆鍒楄〃涓殑浠绘剰涓�涓瓧绗︿覆锛屽鏋滃寘鍚繑鍥炴壘鍒扮殑绗竴涓瓧绗︿覆<br>
+ * 蹇界暐澶у皬鍐�
+ *
+ * @param str 鎸囧畾瀛楃涓�
+ * @param testStrs 闇�瑕佹鏌ョ殑瀛楃涓叉暟缁�
+ * @return 琚寘鍚殑绗竴涓瓧绗︿覆
+ * @since 3.2.0
+ */
+ public static String getContainsStrIgnoreCase(CharSequence str, CharSequence... testStrs) {
+ if (isEmpty(str) || Func.isEmpty(testStrs)) {
+ return null;
+ }
+ for (CharSequence testStr : testStrs) {
+ if (containsIgnoreCase(str, testStr)) {
+ return testStr.toString();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 鏀硅繘JDK subString<br>
+ * index浠�0寮�濮嬭绠楋紝鏈�鍚庝竴涓瓧绗︿负-1<br>
+ * 濡傛灉from鍜宼o浣嶇疆涓�鏍凤紝杩斿洖 "" <br>
+ * 濡傛灉from鎴杢o涓鸿礋鏁帮紝鍒欐寜鐓ength浠庡悗鍚戝墠鏁颁綅缃紝濡傛灉缁濆鍊煎ぇ浜庡瓧绗︿覆闀垮害锛屽垯from褰掑埌0锛宼o褰掑埌length<br>
+ * 濡傛灉缁忚繃淇鐨刬ndex涓璮rom澶т簬to锛屽垯浜掓崲from鍜宼o example: <br>
+ * abcdefgh 2 3 =銆� c <br>
+ * abcdefgh 2 -3 =銆� cde <br>
+ *
+ * @param str String
+ * @param fromIndex 寮�濮嬬殑index锛堝寘鎷級
+ * @param toIndex 缁撴潫鐨刬ndex锛堜笉鍖呮嫭锛�
+ * @return 瀛椾覆
+ */
+ public static String sub(CharSequence str, int fromIndex, int toIndex) {
+ if (isEmpty(str)) {
+ return StringPool.EMPTY;
+ }
+ int len = str.length();
+
+ if (fromIndex < 0) {
+ fromIndex = len + fromIndex;
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ } else if (fromIndex > len) {
+ fromIndex = len;
+ }
+
+ if (toIndex < 0) {
+ toIndex = len + toIndex;
+ if (toIndex < 0) {
+ toIndex = len;
+ }
+ } else if (toIndex > len) {
+ toIndex = len;
+ }
+
+ if (toIndex < fromIndex) {
+ int tmp = fromIndex;
+ fromIndex = toIndex;
+ toIndex = tmp;
+ }
+
+ if (fromIndex == toIndex) {
+ return StringPool.EMPTY;
+ }
+
+ return str.toString().substring(fromIndex, toIndex);
+ }
+
+
+ /**
+ * 鎴彇鍒嗛殧瀛楃涓蹭箣鍓嶇殑瀛楃涓诧紝涓嶅寘鎷垎闅斿瓧绗︿覆<br>
+ * 濡傛灉缁欏畾鐨勫瓧绗︿覆涓虹┖涓诧紙null鎴�""锛夋垨鑰呭垎闅斿瓧绗︿覆涓簄ull锛岃繑鍥炲師瀛楃涓�<br>
+ * 濡傛灉鍒嗛殧瀛楃涓蹭负绌轰覆""锛屽垯杩斿洖绌轰覆锛屽鏋滃垎闅斿瓧绗︿覆鏈壘鍒帮紝杩斿洖鍘熷瓧绗︿覆
+ * <p>
+ * 鏍楀瓙锛�
+ *
+ * <pre>
+ * StringUtil.subBefore(null, *) = null
+ * StringUtil.subBefore("", *) = ""
+ * StringUtil.subBefore("abc", "a") = ""
+ * StringUtil.subBefore("abcba", "b") = "a"
+ * StringUtil.subBefore("abc", "c") = "ab"
+ * StringUtil.subBefore("abc", "d") = "abc"
+ * StringUtil.subBefore("abc", "") = ""
+ * StringUtil.subBefore("abc", null) = "abc"
+ * </pre>
+ *
+ * @param string 琚煡鎵剧殑瀛楃涓�
+ * @param separator 鍒嗛殧瀛楃涓诧紙涓嶅寘鎷級
+ * @param isLastSeparator 鏄惁鏌ユ壘鏈�鍚庝竴涓垎闅斿瓧绗︿覆锛堝娆″嚭鐜板垎闅斿瓧绗︿覆鏃堕�夊彇鏈�鍚庝竴涓級锛宼rue涓洪�夊彇鏈�鍚庝竴涓�
+ * @return 鍒囧壊鍚庣殑瀛楃涓�
+ * @since 3.1.1
+ */
+ public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator) {
+ if (isEmpty(string) || separator == null) {
+ return null == string ? null : string.toString();
+ }
+
+ final String str = string.toString();
+ final String sep = separator.toString();
+ if (sep.isEmpty()) {
+ return StringPool.EMPTY;
+ }
+ final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
+ if (pos == INDEX_NOT_FOUND) {
+ return str;
+ }
+ return str.substring(0, pos);
+ }
+
+ /**
+ * 鎴彇鍒嗛殧瀛楃涓蹭箣鍚庣殑瀛楃涓诧紝涓嶅寘鎷垎闅斿瓧绗︿覆<br>
+ * 濡傛灉缁欏畾鐨勫瓧绗︿覆涓虹┖涓诧紙null鎴�""锛夛紝杩斿洖鍘熷瓧绗︿覆<br>
+ * 濡傛灉鍒嗛殧瀛楃涓蹭负绌轰覆锛坣ull鎴�""锛夛紝鍒欒繑鍥炵┖涓诧紝濡傛灉鍒嗛殧瀛楃涓叉湭鎵惧埌锛岃繑鍥炵┖涓�
+ * <p>
+ * 鏍楀瓙锛�
+ *
+ * <pre>
+ * StringUtil.subAfter(null, *) = null
+ * StringUtil.subAfter("", *) = ""
+ * StringUtil.subAfter(*, null) = ""
+ * StringUtil.subAfter("abc", "a") = "bc"
+ * StringUtil.subAfter("abcba", "b") = "cba"
+ * StringUtil.subAfter("abc", "c") = ""
+ * StringUtil.subAfter("abc", "d") = ""
+ * StringUtil.subAfter("abc", "") = "abc"
+ * </pre>
+ *
+ * @param string 琚煡鎵剧殑瀛楃涓�
+ * @param separator 鍒嗛殧瀛楃涓诧紙涓嶅寘鎷級
+ * @param isLastSeparator 鏄惁鏌ユ壘鏈�鍚庝竴涓垎闅斿瓧绗︿覆锛堝娆″嚭鐜板垎闅斿瓧绗︿覆鏃堕�夊彇鏈�鍚庝竴涓級锛宼rue涓洪�夊彇鏈�鍚庝竴涓�
+ * @return 鍒囧壊鍚庣殑瀛楃涓�
+ * @since 3.1.1
+ */
+ public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator) {
+ if (isEmpty(string)) {
+ return null == string ? null : string.toString();
+ }
+ if (separator == null) {
+ return StringPool.EMPTY;
+ }
+ final String str = string.toString();
+ final String sep = separator.toString();
+ final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
+ if (pos == INDEX_NOT_FOUND) {
+ return StringPool.EMPTY;
+ }
+ return str.substring(pos + separator.length());
+ }
+
+ /**
+ * 鎴彇鎸囧畾瀛楃涓蹭腑闂撮儴鍒嗭紝涓嶅寘鎷爣璇嗗瓧绗︿覆<br>
+ * <p>
+ * 鏍楀瓙锛�
+ *
+ * <pre>
+ * StringUtil.subBetween("wx[b]yz", "[", "]") = "b"
+ * StringUtil.subBetween(null, *, *) = null
+ * StringUtil.subBetween(*, null, *) = null
+ * StringUtil.subBetween(*, *, null) = null
+ * StringUtil.subBetween("", "", "") = ""
+ * StringUtil.subBetween("", "", "]") = null
+ * StringUtil.subBetween("", "[", "]") = null
+ * StringUtil.subBetween("yabcz", "", "") = ""
+ * StringUtil.subBetween("yabcz", "y", "z") = "abc"
+ * StringUtil.subBetween("yabczyabcz", "y", "z") = "abc"
+ * </pre>
+ *
+ * @param str 琚垏鍓茬殑瀛楃涓�
+ * @param before 鎴彇寮�濮嬬殑瀛楃涓叉爣璇�
+ * @param after 鎴彇鍒扮殑瀛楃涓叉爣璇�
+ * @return 鎴彇鍚庣殑瀛楃涓�
+ * @since 3.1.1
+ */
+ public static String subBetween(CharSequence str, CharSequence before, CharSequence after) {
+ if (str == null || before == null || after == null) {
+ return null;
+ }
+
+ final String str2 = str.toString();
+ final String before2 = before.toString();
+ final String after2 = after.toString();
+
+ final int start = str2.indexOf(before2);
+ if (start != INDEX_NOT_FOUND) {
+ final int end = str2.indexOf(after2, start + before2.length());
+ if (end != INDEX_NOT_FOUND) {
+ return str2.substring(start + before2.length(), end);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 鎴彇鎸囧畾瀛楃涓蹭腑闂撮儴鍒嗭紝涓嶅寘鎷爣璇嗗瓧绗︿覆<br>
+ * <p>
+ * 鏍楀瓙锛�
+ *
+ * <pre>
+ * StringUtil.subBetween(null, *) = null
+ * StringUtil.subBetween("", "") = ""
+ * StringUtil.subBetween("", "tag") = null
+ * StringUtil.subBetween("tagabctag", null) = null
+ * StringUtil.subBetween("tagabctag", "") = ""
+ * StringUtil.subBetween("tagabctag", "tag") = "abc"
+ * </pre>
+ *
+ * @param str 琚垏鍓茬殑瀛楃涓�
+ * @param beforeAndAfter 鎴彇寮�濮嬪拰缁撴潫鐨勫瓧绗︿覆鏍囪瘑
+ * @return 鎴彇鍚庣殑瀛楃涓�
+ * @since 3.1.1
+ */
+ public static String subBetween(CharSequence str, CharSequence beforeAndAfter) {
+ return subBetween(str, beforeAndAfter, beforeAndAfter);
+ }
+
+ /**
+ * 鍘绘帀鎸囧畾鍓嶇紑
+ *
+ * @param str 瀛楃涓�
+ * @param prefix 鍓嶇紑
+ * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ墠缂�涓嶆槸 preffix锛� 杩斿洖鍘熷瓧绗︿覆
+ */
+ public static String removePrefix(CharSequence str, CharSequence prefix) {
+ if (isEmpty(str) || isEmpty(prefix)) {
+ return StringPool.EMPTY;
+ }
+
+ final String str2 = str.toString();
+ if (str2.startsWith(prefix.toString())) {
+ return subSuf(str2, prefix.length());
+ }
+ return str2;
+ }
+
+ /**
+ * 蹇界暐澶у皬鍐欏幓鎺夋寚瀹氬墠缂�
+ *
+ * @param str 瀛楃涓�
+ * @param prefix 鍓嶇紑
+ * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ墠缂�涓嶆槸 prefix锛� 杩斿洖鍘熷瓧绗︿覆
+ */
+ public static String removePrefixIgnoreCase(CharSequence str, CharSequence prefix) {
+ if (isEmpty(str) || isEmpty(prefix)) {
+ return StringPool.EMPTY;
+ }
+
+ final String str2 = str.toString();
+ if (str2.toLowerCase().startsWith(prefix.toString().toLowerCase())) {
+ return subSuf(str2, prefix.length());
+ }
+ return str2;
+ }
+
+ /**
+ * 鍘绘帀鎸囧畾鍚庣紑
+ *
+ * @param str 瀛楃涓�
+ * @param suffix 鍚庣紑
+ * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ悗缂�涓嶆槸 suffix锛� 杩斿洖鍘熷瓧绗︿覆
+ */
+ public static String removeSuffix(CharSequence str, CharSequence suffix) {
+ if (isEmpty(str) || isEmpty(suffix)) {
+ return StringPool.EMPTY;
+ }
+
+ final String str2 = str.toString();
+ if (str2.endsWith(suffix.toString())) {
+ return subPre(str2, str2.length() - suffix.length());
+ }
+ return str2;
+ }
+
+ /**
+ * 鍘绘帀鎸囧畾鍚庣紑锛屽苟灏忓啓棣栧瓧姣�
+ *
+ * @param str 瀛楃涓�
+ * @param suffix 鍚庣紑
+ * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ悗缂�涓嶆槸 suffix锛� 杩斿洖鍘熷瓧绗︿覆
+ */
+ public static String removeSufAndLowerFirst(CharSequence str, CharSequence suffix) {
+ return firstCharToLower(removeSuffix(str, suffix));
+ }
+
+ /**
+ * 蹇界暐澶у皬鍐欏幓鎺夋寚瀹氬悗缂�
+ *
+ * @param str 瀛楃涓�
+ * @param suffix 鍚庣紑
+ * @return 鍒囨帀鍚庣殑瀛楃涓诧紝鑻ュ悗缂�涓嶆槸 suffix锛� 杩斿洖鍘熷瓧绗︿覆
+ */
+ public static String removeSuffixIgnoreCase(CharSequence str, CharSequence suffix) {
+ if (isEmpty(str) || isEmpty(suffix)) {
+ return StringPool.EMPTY;
+ }
+
+ final String str2 = str.toString();
+ if (str2.toLowerCase().endsWith(suffix.toString().toLowerCase())) {
+ return subPre(str2, str2.length() - suffix.length());
+ }
+ return str2;
+ }
+
+ /**
+ * 棣栧瓧姣嶅彉灏忓啓
+ *
+ * @param str 瀛楃涓�
+ * @return {String}
+ */
+ public static String firstCharToLower(String str) {
+ char firstChar = str.charAt(0);
+ if (firstChar >= CharPool.UPPER_A && firstChar <= CharPool.UPPER_Z) {
+ char[] arr = str.toCharArray();
+ arr[0] += (CharPool.LOWER_A - CharPool.UPPER_A);
+ return new String(arr);
+ }
+ return str;
+ }
+
+ /**
+ * 棣栧瓧姣嶅彉澶у啓
+ *
+ * @param str 瀛楃涓�
+ * @return {String}
+ */
+ public static String firstCharToUpper(String str) {
+ char firstChar = str.charAt(0);
+ if (firstChar >= CharPool.LOWER_A && firstChar <= CharPool.LOWER_Z) {
+ char[] arr = str.toCharArray();
+ arr[0] -= (CharPool.LOWER_A - CharPool.UPPER_A);
+ return new String(arr);
+ }
+ return str;
+ }
+
+ /**
+ * 鍒囧壊鎸囧畾浣嶇疆涔嬪墠閮ㄥ垎鐨勫瓧绗︿覆
+ *
+ * @param string 瀛楃涓�
+ * @param toIndex 鍒囧壊鍒扮殑浣嶇疆锛堜笉鍖呮嫭锛�
+ * @return 鍒囧壊鍚庣殑鍓╀綑鐨勫墠鍗婇儴鍒嗗瓧绗︿覆
+ */
+ public static String subPre(CharSequence string, int toIndex) {
+ return sub(string, 0, toIndex);
+ }
+
+ /**
+ * 鍒囧壊鎸囧畾浣嶇疆涔嬪悗閮ㄥ垎鐨勫瓧绗︿覆
+ *
+ * @param string 瀛楃涓�
+ * @param fromIndex 鍒囧壊寮�濮嬬殑浣嶇疆锛堝寘鎷級
+ * @return 鍒囧壊鍚庡悗鍓╀綑鐨勫悗鍗婇儴鍒嗗瓧绗︿覆
+ */
+ public static String subSuf(CharSequence string, int fromIndex) {
+ if (isEmpty(string)) {
+ return null;
+ }
+ return sub(string, fromIndex, string.length());
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵炬寚瀹氬瓧绗�
+ *
+ * @param str 瀛楃涓�
+ * @param searchChar 琚煡鎵剧殑瀛楃
+ * @return 浣嶇疆
+ */
+ public static int indexOf(final CharSequence str, char searchChar) {
+ return indexOf(str, searchChar, 0);
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵炬寚瀹氬瓧绗�
+ *
+ * @param str 瀛楃涓�
+ * @param searchChar 琚煡鎵剧殑瀛楃
+ * @param start 璧峰浣嶇疆锛屽鏋滃皬浜�0锛屼粠0寮�濮嬫煡鎵�
+ * @return 浣嶇疆
+ */
+ public static int indexOf(final CharSequence str, char searchChar, int start) {
+ if (str instanceof String) {
+ return ((String) str).indexOf(searchChar, start);
+ } else {
+ return indexOf(str, searchChar, start, -1);
+ }
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵炬寚瀹氬瓧绗�
+ *
+ * @param str 瀛楃涓�
+ * @param searchChar 琚煡鎵剧殑瀛楃
+ * @param start 璧峰浣嶇疆锛屽鏋滃皬浜�0锛屼粠0寮�濮嬫煡鎵�
+ * @param end 缁堟浣嶇疆锛屽鏋滆秴杩噑tr.length()鍒欓粯璁ゆ煡鎵惧埌瀛楃涓叉湯灏�
+ * @return 浣嶇疆
+ */
+ public static int indexOf(final CharSequence str, char searchChar, int start, int end) {
+ final int len = str.length();
+ if (start < 0 || start > len) {
+ start = 0;
+ }
+ if (end > len || end < 0) {
+ end = len;
+ }
+ for (int i = start; i < end; i++) {
+ if (str.charAt(i) == searchChar) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆锛屽拷鐣ュぇ灏忓啓<br>
+ *
+ * <pre>
+ * StringUtil.indexOfIgnoreCase(null, *, *) = -1
+ * StringUtil.indexOfIgnoreCase(*, null, *) = -1
+ * StringUtil.indexOfIgnoreCase("", "", 0) = 0
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2) = 2
+ * StringUtil.indexOfIgnoreCase("abc", "", 9) = -1
+ * </pre>
+ *
+ * @param str 瀛楃涓�
+ * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+ * @return 浣嶇疆
+ * @since 3.2.1
+ */
+ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
+ return indexOfIgnoreCase(str, searchStr, 0);
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆
+ *
+ * <pre>
+ * StringUtil.indexOfIgnoreCase(null, *, *) = -1
+ * StringUtil.indexOfIgnoreCase(*, null, *) = -1
+ * StringUtil.indexOfIgnoreCase("", "", 0) = 0
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+ * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2) = 2
+ * StringUtil.indexOfIgnoreCase("abc", "", 9) = -1
+ * </pre>
+ *
+ * @param str 瀛楃涓�
+ * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+ * @param fromIndex 璧峰浣嶇疆
+ * @return 浣嶇疆
+ * @since 3.2.1
+ */
+ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) {
+ return indexOf(str, searchStr, fromIndex, true);
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呭弽鍚戞煡鎵惧瓧绗︿覆
+ *
+ * @param str 瀛楃涓�
+ * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+ * @param fromIndex 璧峰浣嶇疆
+ * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+ * @return 浣嶇疆
+ * @since 3.2.1
+ */
+ public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase) {
+ if (str == null || searchStr == null) {
+ return INDEX_NOT_FOUND;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+
+ final int endLimit = str.length() - searchStr.length() + 1;
+ if (fromIndex > endLimit) {
+ return INDEX_NOT_FOUND;
+ }
+ if (searchStr.length() == 0) {
+ return fromIndex;
+ }
+
+ if (false == ignoreCase) {
+ // 涓嶅拷鐣ュぇ灏忓啓璋冪敤JDK鏂规硶
+ return str.toString().indexOf(searchStr.toString(), fromIndex);
+ }
+
+ for (int i = fromIndex; i < endLimit; i++) {
+ if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) {
+ return i;
+ }
+ }
+ return INDEX_NOT_FOUND;
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆锛屽拷鐣ュぇ灏忓啓<br>
+ *
+ * @param str 瀛楃涓�
+ * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+ * @return 浣嶇疆
+ * @since 3.2.1
+ */
+ public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
+ return lastIndexOfIgnoreCase(str, searchStr, str.length());
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆锛屽拷鐣ュぇ灏忓啓<br>
+ *
+ * @param str 瀛楃涓�
+ * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+ * @param fromIndex 璧峰浣嶇疆锛屼粠鍚庡線鍓嶈鏁�
+ * @return 浣嶇疆
+ * @since 3.2.1
+ */
+ public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) {
+ return lastIndexOf(str, searchStr, fromIndex, true);
+ }
+
+ /**
+ * 鎸囧畾鑼冨洿鍐呮煡鎵惧瓧绗︿覆<br>
+ *
+ * @param str 瀛楃涓�
+ * @param searchStr 闇�瑕佹煡鎵句綅缃殑瀛楃涓�
+ * @param fromIndex 璧峰浣嶇疆锛屼粠鍚庡線鍓嶈鏁�
+ * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+ * @return 浣嶇疆
+ * @since 3.2.1
+ */
+ public static int lastIndexOf(final CharSequence str, final CharSequence searchStr, int fromIndex, boolean ignoreCase) {
+ if (str == null || searchStr == null) {
+ return INDEX_NOT_FOUND;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ fromIndex = Math.min(fromIndex, str.length());
+
+ if (searchStr.length() == 0) {
+ return fromIndex;
+ }
+
+ if (false == ignoreCase) {
+ // 涓嶅拷鐣ュぇ灏忓啓璋冪敤JDK鏂规硶
+ return str.toString().lastIndexOf(searchStr.toString(), fromIndex);
+ }
+
+ for (int i = fromIndex; i > 0; i--) {
+ if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) {
+ return i;
+ }
+ }
+ return INDEX_NOT_FOUND;
+ }
+
+ /**
+ * 杩斿洖瀛楃涓� searchStr 鍦ㄥ瓧绗︿覆 str 涓 ordinal 娆″嚭鐜扮殑浣嶇疆銆�<br>
+ * 姝ゆ柟娉曟潵鑷細Apache-Commons-Lang
+ * <p>
+ * 鏍楀瓙锛�*浠h〃浠绘剰瀛楃锛夛細
+ *
+ * <pre>
+ * StringUtil.ordinalIndexOf(null, *, *) = -1
+ * StringUtil.ordinalIndexOf(*, null, *) = -1
+ * StringUtil.ordinalIndexOf("", "", *) = 0
+ * StringUtil.ordinalIndexOf("aabaabaa", "a", 1) = 0
+ * StringUtil.ordinalIndexOf("aabaabaa", "a", 2) = 1
+ * StringUtil.ordinalIndexOf("aabaabaa", "b", 1) = 2
+ * StringUtil.ordinalIndexOf("aabaabaa", "b", 2) = 5
+ * StringUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
+ * StringUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
+ * StringUtil.ordinalIndexOf("aabaabaa", "", 1) = 0
+ * StringUtil.ordinalIndexOf("aabaabaa", "", 2) = 0
+ * </pre>
+ *
+ * @param str 琚鏌ョ殑瀛楃涓诧紝鍙互涓簄ull
+ * @param searchStr 琚煡鎵剧殑瀛楃涓诧紝鍙互涓簄ull
+ * @param ordinal 绗嚑娆″嚭鐜扮殑浣嶇疆
+ * @return 鏌ユ壘鍒扮殑浣嶇疆
+ * @since 3.2.3
+ */
+ public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
+ if (str == null || searchStr == null || ordinal <= 0) {
+ return INDEX_NOT_FOUND;
+ }
+ if (searchStr.length() == 0) {
+ return 0;
+ }
+ int found = 0;
+ int index = INDEX_NOT_FOUND;
+ do {
+ index = str.indexOf(searchStr, index + 1);
+ if (index < 0) {
+ return index;
+ }
+ found++;
+ } while (found < ordinal);
+ return index;
+ }
+
+ /**
+ * 鎴彇涓や釜瀛楃涓茬殑涓嶅悓閮ㄥ垎锛堥暱搴︿竴鑷达級锛屽垽鏂埅鍙栫殑瀛愪覆鏄惁鐩稿悓<br>
+ * 浠绘剰涓�涓瓧绗︿覆涓簄ull杩斿洖false
+ *
+ * @param str1 绗竴涓瓧绗︿覆
+ * @param start1 绗竴涓瓧绗︿覆寮�濮嬬殑浣嶇疆
+ * @param str2 绗簩涓瓧绗︿覆
+ * @param start2 绗簩涓瓧绗︿覆寮�濮嬬殑浣嶇疆
+ * @param length 鎴彇闀垮害
+ * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+ * @return 瀛愪覆鏄惁鐩稿悓
+ * @since 3.2.1
+ */
+ public static boolean isSubEquals(CharSequence str1, int start1, CharSequence str2, int start2, int length, boolean ignoreCase) {
+ if (null == str1 || null == str2) {
+ return false;
+ }
+
+ return str1.toString().regionMatches(ignoreCase, start1, str2.toString(), start2, length);
+ }
+
+ /**
+ * 姣旇緝涓や釜瀛楃涓诧紙澶у皬鍐欐晱鎰燂級銆�
+ *
+ * <pre>
+ * equalsIgnoreCase(null, null) = true
+ * equalsIgnoreCase(null, "abc") = false
+ * equalsIgnoreCase("abc", null) = false
+ * equalsIgnoreCase("abc", "abc") = true
+ * equalsIgnoreCase("abc", "ABC") = true
+ * </pre>
+ *
+ * @param str1 瑕佹瘮杈冪殑瀛楃涓�1
+ * @param str2 瑕佹瘮杈冪殑瀛楃涓�2
+ * @return 濡傛灉涓や釜瀛楃涓茬浉鍚岋紝鎴栬�呴兘鏄�<code>null</code>锛屽垯杩斿洖<code>true</code>
+ */
+ public static boolean equals(CharSequence str1, CharSequence str2) {
+ return equals(str1, str2, false);
+ }
+
+ /**
+ * 姣旇緝涓や釜瀛楃涓诧紙澶у皬鍐欎笉鏁忔劅锛夈��
+ *
+ * <pre>
+ * equalsIgnoreCase(null, null) = true
+ * equalsIgnoreCase(null, "abc") = false
+ * equalsIgnoreCase("abc", null) = false
+ * equalsIgnoreCase("abc", "abc") = true
+ * equalsIgnoreCase("abc", "ABC") = true
+ * </pre>
+ *
+ * @param str1 瑕佹瘮杈冪殑瀛楃涓�1
+ * @param str2 瑕佹瘮杈冪殑瀛楃涓�2
+ * @return 濡傛灉涓や釜瀛楃涓茬浉鍚岋紝鎴栬�呴兘鏄�<code>null</code>锛屽垯杩斿洖<code>true</code>
+ */
+ public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
+ return equals(str1, str2, true);
+ }
+
+ /**
+ * 姣旇緝涓や釜瀛楃涓叉槸鍚︾浉绛夈��
+ *
+ * @param str1 瑕佹瘮杈冪殑瀛楃涓�1
+ * @param str2 瑕佹瘮杈冪殑瀛楃涓�2
+ * @param ignoreCase 鏄惁蹇界暐澶у皬鍐�
+ * @return 濡傛灉涓や釜瀛楃涓茬浉鍚岋紝鎴栬�呴兘鏄�<code>null</code>锛屽垯杩斿洖<code>true</code>
+ * @since 3.2.0
+ */
+ public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) {
+ if (null == str1) {
+ // 鍙湁涓や釜閮戒负null鎵嶅垽鏂浉绛�
+ return str2 == null;
+ }
+ if (null == str2) {
+ // 瀛楃涓�2绌猴紝瀛楃涓�1闈炵┖锛岀洿鎺alse
+ return false;
+ }
+
+ if (ignoreCase) {
+ return str1.toString().equalsIgnoreCase(str2.toString());
+ } else {
+ return str1.equals(str2);
+ }
+ }
+
+ /**
+ * 鍒涘缓StringBuilder瀵硅薄
+ *
+ * @return {String}Builder瀵硅薄
+ */
+ public static StringBuilder builder() {
+ return new StringBuilder();
+ }
+
+ /**
+ * 鍒涘缓StringBuilder瀵硅薄
+ *
+ * @param capacity 鍒濆澶у皬
+ * @return {String}Builder瀵硅薄
+ */
+ public static StringBuilder builder(int capacity) {
+ return new StringBuilder(capacity);
+ }
+
+ /**
+ * 鍒涘缓StringBuilder瀵硅薄
+ *
+ * @param strs 鍒濆瀛楃涓插垪琛�
+ * @return {String}Builder瀵硅薄
+ */
+ public static StringBuilder builder(CharSequence... strs) {
+ final StringBuilder sb = new StringBuilder();
+ for (CharSequence str : strs) {
+ sb.append(str);
+ }
+ return sb;
+ }
+
+ /**
+ * 鍒涘缓StringBuilder瀵硅薄
+ *
+ * @param sb 鍒濆StringBuilder
+ * @param strs 鍒濆瀛楃涓插垪琛�
+ * @return {String}Builder瀵硅薄
+ */
+ public static StringBuilder appendBuilder(StringBuilder sb, CharSequence... strs) {
+ for (CharSequence str : strs) {
+ sb.append(str);
+ }
+ return sb;
+ }
+
+ /**
+ * 鑾峰緱StringReader
+ *
+ * @param str 瀛楃涓�
+ * @return {String}Reader
+ */
+ public static StringReader getReader(CharSequence str) {
+ if (null == str) {
+ return null;
+ }
+ return new StringReader(str.toString());
+ }
+
+ /**
+ * 鑾峰緱StringWriter
+ *
+ * @return {String}Writer
+ */
+ public static StringWriter getWriter() {
+ return new StringWriter();
+ }
+
+ /**
+ * 缁熻鎸囧畾鍐呭涓寘鍚寚瀹氬瓧绗︿覆鐨勬暟閲�<br>
+ * 鍙傛暟涓� {@code null} 鎴栬�� "" 杩斿洖 {@code 0}.
+ *
+ * <pre>
+ * StringUtil.count(null, *) = 0
+ * StringUtil.count("", *) = 0
+ * StringUtil.count("abba", null) = 0
+ * StringUtil.count("abba", "") = 0
+ * StringUtil.count("abba", "a") = 2
+ * StringUtil.count("abba", "ab") = 1
+ * StringUtil.count("abba", "xxx") = 0
+ * </pre>
+ *
+ * @param content 琚煡鎵剧殑瀛楃涓�
+ * @param strForSearch 闇�瑕佹煡鎵剧殑瀛楃涓�
+ * @return 鏌ユ壘鍒扮殑涓暟
+ */
+ public static int count(CharSequence content, CharSequence strForSearch) {
+ if (Func.hasEmpty(content, strForSearch) || strForSearch.length() > content.length()) {
+ return 0;
+ }
+
+ int count = 0;
+ int idx = 0;
+ final String content2 = content.toString();
+ final String strForSearch2 = strForSearch.toString();
+ while ((idx = content2.indexOf(strForSearch2, idx)) > -1) {
+ count++;
+ idx += strForSearch.length();
+ }
+ return count;
+ }
+
+ /**
+ * 缁熻鎸囧畾鍐呭涓寘鍚寚瀹氬瓧绗︾殑鏁伴噺
+ *
+ * @param content 鍐呭
+ * @param charForSearch 琚粺璁$殑瀛楃
+ * @return 鍖呭惈鏁伴噺
+ */
+ public static int count(CharSequence content, char charForSearch) {
+ int count = 0;
+ if (isEmpty(content)) {
+ return 0;
+ }
+ int contentLength = content.length();
+ for (int i = 0; i < contentLength; i++) {
+ if (charForSearch == content.charAt(i)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * 涓嬪垝绾胯浆椹煎嘲
+ *
+ * @param para 瀛楃涓�
+ * @return {String}
+ */
+ public static String underlineToHump(String para) {
+ if (isBlank(para)) {
+ return StringPool.EMPTY;
+ }
+ StringBuilder result = new StringBuilder();
+ String[] a = para.split("_");
+ for (String s : a) {
+ if (result.length() == 0) {
+ result.append(s.toLowerCase());
+ } else {
+ result.append(s.substring(0, 1).toUpperCase());
+ result.append(s.substring(1).toLowerCase());
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * 椹煎嘲杞笅鍒掔嚎
+ *
+ * @param para 瀛楃涓�
+ * @return {String}
+ */
+ public static String humpToUnderline(String para) {
+ if (isBlank(para)) {
+ return StringPool.EMPTY;
+ }
+ para = firstCharToLower(para);
+ StringBuilder sb = new StringBuilder(para);
+ int temp = 0;
+ for (int i = 0; i < para.length(); i++) {
+ if (Character.isUpperCase(para.charAt(i))) {
+ sb.insert(i + temp, "_");
+ temp += 1;
+ }
+ }
+ return sb.toString().toLowerCase();
+ }
+
+ /**
+ * 妯嚎杞┘宄�
+ *
+ * @param para 瀛楃涓�
+ * @return {String}
+ */
+ public static String lineToHump(String para) {
+ if (isBlank(para)) {
+ return StringPool.EMPTY;
+ }
+ StringBuilder result = new StringBuilder();
+ String[] a = para.split("-");
+ for (String s : a) {
+ if (result.length() == 0) {
+ result.append(s.toLowerCase());
+ } else {
+ result.append(s.substring(0, 1).toUpperCase());
+ result.append(s.substring(1).toLowerCase());
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * 椹煎嘲杞í绾�
+ *
+ * @param para 瀛楃涓�
+ * @return {String}
+ */
+ public static String humpToLine(String para) {
+ if (isBlank(para)) {
+ return StringPool.EMPTY;
+ }
+ para = firstCharToLower(para);
+ StringBuilder sb = new StringBuilder(para);
+ int temp = 0;
+ for (int i = 0; i < para.length(); i++) {
+ if (Character.isUpperCase(para.charAt(i))) {
+ sb.insert(i + temp, "-");
+ temp += 1;
+ }
+ }
+ return sb.toString().toLowerCase();
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java
new file mode 100644
index 0000000..e3ee236
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/BladeJavaTimeModule.java
@@ -0,0 +1,35 @@
+package com.vci.web.util.jackson;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.vci.web.util.DateTimeUtil;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+ * java 8 鏃堕棿榛樿搴忓垪鍖�
+ *
+ * @author L.cm
+ */
+public class BladeJavaTimeModule extends SimpleModule {
+ public static final BladeJavaTimeModule INSTANCE = new BladeJavaTimeModule();
+
+ public BladeJavaTimeModule() {
+ super(PackageVersion.VERSION);
+ this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeUtil.DATETIME_FORMAT));
+ this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeUtil.DATE_FORMAT));
+ this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeUtil.TIME_FORMAT));
+ this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeUtil.DATETIME_FORMAT));
+ this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeUtil.DATE_FORMAT));
+ this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeUtil.TIME_FORMAT));
+ }
+
+}
diff --git a/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java
new file mode 100644
index 0000000..dd459c3
--- /dev/null
+++ b/Source/platformProject/vci-platform-web/src/main/java/com/vci/web/util/jackson/JsonUtil.java
@@ -0,0 +1,705 @@
+/*
+ * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.web.util.jackson;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.TreeNode;
+import com.fasterxml.jackson.core.json.JsonReadFeature;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.type.CollectionLikeType;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.vci.web.util.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.lang.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.time.ZoneId;
+import java.util.*;
+
+/**
+ * Jackson宸ュ叿绫�
+ *
+ * @author Chill
+ */
+@Slf4j
+public class JsonUtil {
+
+ /**
+ * 灏嗗璞″簭鍒楀寲鎴恓son瀛楃涓�
+ *
+ * @param value javaBean
+ * @return jsonString json瀛楃涓�
+ */
+ public static <T> String toJson(T value) {
+ try {
+ return getInstance().writeValueAsString(value);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * 灏嗗璞″簭鍒楀寲鎴� json byte 鏁扮粍
+ *
+ * @param object javaBean
+ * @return jsonString json瀛楃涓�
+ */
+ public static byte[] toJsonAsBytes(Object object) {
+ try {
+ return getInstance().writeValueAsBytes(object);
+ } catch (JsonProcessingException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param content content
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T parse(String content, Class<T> valueType) {
+ try {
+ return getInstance().readValue(content, valueType);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param content content
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T parse(String content, TypeReference<T> typeReference) {
+ try {
+ return getInstance().readValue(content, typeReference);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son byte 鏁扮粍鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param bytes json bytes
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T parse(byte[] bytes, Class<T> valueType) {
+ try {
+ return getInstance().readValue(bytes, valueType);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param bytes bytes
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
+ try {
+ return getInstance().readValue(bytes, typeReference);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param in InputStream
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T parse(InputStream in, Class<T> valueType) {
+ try {
+ return getInstance().readValue(in, valueType);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param in InputStream
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
+ try {
+ return getInstance().readValue(in, typeReference);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴怢ist瀵硅薄
+ *
+ * @param content content
+ * @param valueTypeRef class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return List<T>
+ */
+ public static <T> List<T> parseArray(String content, Class<T> valueTypeRef) {
+ try {
+
+ if (!StringUtil.startsWithIgnoreCase(content, StringPool.LEFT_SQ_BRACKET)) {
+ content = StringPool.LEFT_SQ_BRACKET + content + StringPool.RIGHT_SQ_BRACKET;
+ }
+
+ List<Map<String, Object>> list = getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
+ });
+
+ List<T> result = new ArrayList<>();
+ for (Map<String, Object> map : list) {
+ result.add(toPojo(map, valueTypeRef));
+ }
+ return result;
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param jsonString jsonString
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(String jsonString) {
+ Objects.requireNonNull(jsonString, "jsonString is null");
+ try {
+ return getInstance().readTree(jsonString);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param in InputStream
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(InputStream in) {
+ Objects.requireNonNull(in, "InputStream in is null");
+ try {
+ return getInstance().readTree(in);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param content content
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(byte[] content) {
+ Objects.requireNonNull(content, "byte[] content is null");
+ try {
+ return getInstance().readTree(content);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son瀛楃涓茶浆鎴� JsonNode
+ *
+ * @param jsonParser JsonParser
+ * @return jsonString json瀛楃涓�
+ */
+ public static JsonNode readTree(JsonParser jsonParser) {
+ Objects.requireNonNull(jsonParser, "jsonParser is null");
+ try {
+ return getInstance().readTree(jsonParser);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+
+ /**
+ * 灏唈son byte 鏁扮粍鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param content json bytes
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ @Nullable
+ public static <T> T readValue(@Nullable byte[] content, Class<T> valueType) {
+ if (ObjectUtil.isEmpty(content)) {
+ return null;
+ }
+ try {
+ return getInstance().readValue(content, valueType);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param jsonString jsonString
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ @Nullable
+ public static <T> T readValue(@Nullable String jsonString, Class<T> valueType) {
+ if (StringUtil.isBlank(jsonString)) {
+ return null;
+ }
+ try {
+ return getInstance().readValue(jsonString, valueType);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param in InputStream
+ * @param valueType class
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ @Nullable
+ public static <T> T readValue(@Nullable InputStream in, Class<T> valueType) {
+ if (in == null) {
+ return null;
+ }
+ try {
+ return getInstance().readValue(in, valueType);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param content bytes
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ @Nullable
+ public static <T> T readValue(@Nullable byte[] content, TypeReference<T> typeReference) {
+ if (ObjectUtil.isEmpty(content)) {
+ return null;
+ }
+ try {
+ return getInstance().readValue(content, typeReference);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param jsonString jsonString
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ @Nullable
+ public static <T> T readValue(@Nullable String jsonString, TypeReference<T> typeReference) {
+ if (StringUtil.isBlank(jsonString)) {
+ return null;
+ }
+ try {
+ return getInstance().readValue(jsonString, typeReference);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏唈son鍙嶅簭鍒楀寲鎴愬璞�
+ *
+ * @param in InputStream
+ * @param typeReference 娉涘瀷绫诲瀷
+ * @param <T> T 娉涘瀷鏍囪
+ * @return Bean
+ */
+ @Nullable
+ public static <T> T readValue(@Nullable InputStream in, TypeReference<T> typeReference) {
+ if (in == null) {
+ return null;
+ }
+ try {
+ return getInstance().readValue(in, typeReference);
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 灏佽 map type
+ *
+ * @param keyClass key 绫诲瀷
+ * @param valueClass value 绫诲瀷
+ * @return MapType
+ */
+ public static MapType getMapType(Class<?> keyClass, Class<?> valueClass) {
+ return getInstance().getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
+ }
+
+ /**
+ * 灏佽 map type
+ *
+ * @param elementClass 闆嗗悎鍊肩被鍨�
+ * @return CollectionLikeType
+ */
+ public static CollectionLikeType getListType(Class<?> elementClass) {
+ return getInstance().getTypeFactory().constructCollectionLikeType(List.class, elementClass);
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content bytes
+ * @param elementClass elementClass
+ * @param <T> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <T> List<T> readList(@Nullable byte[] content, Class<T> elementClass) {
+ if (ObjectUtil.isEmpty(content)) {
+ return Collections.emptyList();
+ }
+ try {
+ return getInstance().readValue(content, getListType(elementClass));
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content InputStream
+ * @param elementClass elementClass
+ * @param <T> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <T> List<T> readList(@Nullable InputStream content, Class<T> elementClass) {
+ if (content == null) {
+ return Collections.emptyList();
+ }
+ try {
+ return getInstance().readValue(content, getListType(elementClass));
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content bytes
+ * @param elementClass elementClass
+ * @param <T> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <T> List<T> readList(@Nullable String content, Class<T> elementClass) {
+ if (ObjectUtil.isEmpty(content)) {
+ return Collections.emptyList();
+ }
+ try {
+ return getInstance().readValue(content, getListType(elementClass));
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content bytes
+ * @param keyClass key绫诲瀷
+ * @param valueClass 鍊肩被鍨�
+ * @param <K> 娉涘瀷
+ * @param <V> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <K, V> Map<K, V> readMap(@Nullable byte[] content, Class<?> keyClass, Class<?> valueClass) {
+ if (ObjectUtil.isEmpty(content)) {
+ return Collections.emptyMap();
+ }
+ try {
+ return getInstance().readValue(content, getMapType(keyClass, valueClass));
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content InputStream
+ * @param keyClass key绫诲瀷
+ * @param valueClass 鍊肩被鍨�
+ * @param <K> 娉涘瀷
+ * @param <V> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <K, V> Map<K, V> readMap(@Nullable InputStream content, Class<?> keyClass, Class<?> valueClass) {
+ if (ObjectUtil.isEmpty(content)) {
+ return Collections.emptyMap();
+ }
+ try {
+ return getInstance().readValue(content, getMapType(keyClass, valueClass));
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content bytes
+ * @param keyClass key绫诲瀷
+ * @param valueClass 鍊肩被鍨�
+ * @param <K> 娉涘瀷
+ * @param <V> 娉涘瀷
+ * @return 闆嗗悎
+ */
+ public static <K, V> Map<K, V> readMap(@Nullable String content, Class<?> keyClass, Class<?> valueClass) {
+ if (ObjectUtil.isEmpty(content)) {
+ return Collections.emptyMap();
+ }
+ try {
+ return getInstance().readValue(content, getMapType(keyClass, valueClass));
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content bytes
+ * @return 闆嗗悎
+ */
+ public static Map<String, Object> readMap(@Nullable String content) {
+ return readMap(content, String.class, Object.class);
+ }
+
+ /**
+ * 璇诲彇闆嗗悎
+ *
+ * @param content bytes
+ * @return 闆嗗悎
+ */
+ public static List<Map<String, Object>> readListMap(@Nullable String content) {
+ if (ObjectUtil.isEmpty(content)) {
+ return Collections.emptyList();
+ }
+ try {
+ return getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
+ });
+ } catch (IOException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * jackson 鐨勭被鍨嬭浆鎹�
+ *
+ * @param fromValue 鏉ユ簮瀵硅薄
+ * @param toValueType 杞崲鐨勭被鍨�
+ * @param <T> 娉涘瀷鏍囪
+ * @return 杞崲缁撴灉
+ */
+ public static <T> T convertValue(Object fromValue, Class<T> toValueType) {
+ return getInstance().convertValue(fromValue, toValueType);
+ }
+
+ /**
+ * jackson 鐨勭被鍨嬭浆鎹�
+ *
+ * @param fromValue 鏉ユ簮瀵硅薄
+ * @param toValueType 杞崲鐨勭被鍨�
+ * @param <T> 娉涘瀷鏍囪
+ * @return 杞崲缁撴灉
+ */
+ public static <T> T convertValue(Object fromValue, JavaType toValueType) {
+ return getInstance().convertValue(fromValue, toValueType);
+ }
+
+ /**
+ * jackson 鐨勭被鍨嬭浆鎹�
+ *
+ * @param fromValue 鏉ユ簮瀵硅薄
+ * @param toValueTypeRef 娉涘瀷绫诲瀷
+ * @param <T> 娉涘瀷鏍囪
+ * @return 杞崲缁撴灉
+ */
+ public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) {
+ return getInstance().convertValue(fromValue, toValueTypeRef);
+ }
+
+ /**
+ * tree 杞璞�
+ *
+ * @param treeNode TreeNode
+ * @param valueType valueType
+ * @param <T> 娉涘瀷鏍囪
+ * @return 杞崲缁撴灉
+ */
+ public static <T> T treeToValue(TreeNode treeNode, Class<T> valueType) {
+ try {
+ return getInstance().treeToValue(treeNode, valueType);
+ } catch (JsonProcessingException e) {
+ throw Exceptions.unchecked(e);
+ }
+ }
+
+ /**
+ * 瀵硅薄杞负 json node
+ *
+ * @param value 瀵硅薄
+ * @return JsonNode
+ */
+ public static JsonNode valueToTree(@Nullable Object value) {
+ return getInstance().valueToTree(value);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁鍙互搴忓垪鍖�
+ *
+ * @param value 瀵硅薄
+ * @return 鏄惁鍙互搴忓垪鍖�
+ */
+ public static boolean canSerialize(@Nullable Object value) {
+ if (value == null) {
+ return true;
+ }
+ return getInstance().canSerialize(value.getClass());
+ }
+
+ public static Map<String, Object> toMap(String content) {
+ try {
+ return getInstance().readValue(content, Map.class);
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ public static <T> Map<String, T> toMap(String content, Class<T> valueTypeRef) {
+ try {
+ Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, Map<String, Object>>>() {
+ });
+ Map<String, T> result = new HashMap<>(16);
+ for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
+ result.put(entry.getKey(), toPojo(entry.getValue(), valueTypeRef));
+ }
+ return result;
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ public static <T> T toPojo(Map fromValue, Class<T> toValueType) {
+ return getInstance().convertValue(fromValue, toValueType);
+ }
+
+ public static ObjectMapper getInstance() {
+ return JacksonHolder.INSTANCE;
+ }
+
+ private static class JacksonHolder {
+ private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
+ }
+
+ private static class JacksonObjectMapper extends ObjectMapper {
+ private static final long serialVersionUID = 4288193147502386170L;
+
+ private static final Locale CHINA = Locale.CHINA;
+
+ public JacksonObjectMapper(ObjectMapper src) {
+ super(src);
+ }
+
+ public JacksonObjectMapper() {
+ super();
+ //璁剧疆鍦扮偣涓轰腑鍥�
+ super.setLocale(CHINA);
+ //鍘绘帀榛樿鐨勬椂闂存埑鏍煎紡
+ super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ //璁剧疆涓轰腑鍥戒笂娴锋椂鍖�
+ super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
+ //搴忓垪鍖栨椂锛屾棩鏈熺殑缁熶竴鏍煎紡
+ super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
+ // 鍗曞紩鍙�
+ super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
+ // 鍏佽JSON瀛楃涓插寘鍚潪寮曞彿鎺у埗瀛楃锛堝�煎皬浜�32鐨凙SCII瀛楃锛屽寘鍚埗琛ㄧ鍜屾崲琛岀锛�
+ super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
+ super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
+ super.findAndRegisterModules();
+ //澶辫触澶勭悊
+ super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+ super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ //鍗曞紩鍙峰鐞�
+ super.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
+ //鍙嶅簭鍒楀寲鏃讹紝灞炴�т笉瀛樺湪鐨勫吋瀹瑰鐞唖
+ super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+ //鏃ユ湡鏍煎紡鍖�
+ super.registerModule(new BladeJavaTimeModule());
+ super.findAndRegisterModules();
+ }
+
+ @Override
+ public ObjectMapper copy() {
+ return new JacksonObjectMapper(this);
+ }
+ }
+
+}
--
Gitblit v1.9.3