# JWosUtility
**Repository Path**: WosElement/JWosUtility
## Basic Information
- **Project Name**: JWosUtility
- **Description**: jwos.utility是包含开发中高频使用的工具类,涉及基础工具、网络、安全、文件、jar加载等。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-04-23
- **Last Updated**: 2026-08-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# jwos.utility
[TOC]
## 简介
jwos.utility是包含开发中高频使用的工具类,涉及基础工具、网络、安全、文件、jar加载等,适配JDK1.8,兼容JDK9及更高版本,建议使用LTS版本:JDK11、JDK17、JDK21、JDK25。
## 依赖
#### 依赖说明
本工具包设计为尽可能减少依赖任何第三方库。
#### 依赖
- javax.servlet-api 3.1.0 由运行容器决定
- org.slf4j 1.7.36 兼容性较好
- logback-core/access 1.2.12 日志实现
- fastjson2 2.0.51 JSON处理
- dom4j 2.1.4及jaxen 1.2.0 XML处理
## 使用说明
### 快速开始
1. 添加依赖包
```xml
cn.5wos
JWosUtility
${JWosUtility.version}
```
2. 添加工具类配置文件(如果不配置则使用默认配置)到项目resources/wos.xml
```xml
smtp.qiye.aliyun.com
465
true
发件人用户名
发件人密码
发件人邮件
200
20
- http:localhost:8080:5
- https:localhost:8443:6
```
3. 添加多语言配置文件(可选),项目resources/i18n/resultcode.properties(resultcode_en.properties)
```properties
result.success=成功。
result.system_error=系统繁忙,请稍后再试。
```
4. 添加日志配置文件(可选),项目resources/logback.xml
```xml
${log.pattern}
UTF-8
${LOG_HOME}/${APP_NAME}.log
${LOG_HOME}/${APP_NAME}-%d{yyyy-MM-dd}.log
${log.maxHistory}
${log.pattern}
UTF-8
${LOG_HOME}/${APP_NAME}-full.log
${LOG_HOME}/${APP_NAME}-full-%d{yyyy-MM-dd}.%i.log
${log.maxHistory}
${log.maxSize}
${log.pattern}
UTF-8
```
5. 按照以下说明使用各项能力
### 缓存(开发中)
### 配置
#### 配置工具ConfigUtil
- getFileStream 获取文件输入流,优先读取嵌入资源文件,
如果找不到则从外部config文件夹中读取,使用getPath方法获取的路径
- getPath 如果项目编译时将src/main/resources的文件编译到config文件夹下则可使用该方法获取配置文件绝对路径
- loadConfig 加载配置文件(支持xml、json文件,其他类型配置文件不支持转换到对象)
- `loadConfig(Class clazz)` 加载默认配置到指定的对象,默认配置文件为wos.xml
- `loadConfig(String configFile)` 加载配置文件并缓存,返回配置文件字符串
- `loadConfig(String configFile, Class clazz)` 加载配置文件到实体类
- 配置文件xml、json转换为配置对象,且支持将配置文件中某个节点转换为对象,
须在配置类中添加注解`@ConfigPrefix("节点名.")`。
如果是xml需要添加注解`@XmlRootElement(name = "节点名")`,如邮件配置示例:
```java
@ConfigPrefix("mail.")
@XmlRootElement(name = "mail")
public class MailConfig {
...
}
```
### 数据库
#### 基础实体类BaseEntity
使用前项目中需包含以下依赖包MyBatis-Plus或MyBatis-Flex,也可以使用包含相关依赖的其他包。
```xml
org.mybatis
mybatis
3.5.19
com.baomidou
mybatis-plus-core
3.5.12
com.baomidou
mybatis-plus-annotation
3.5.12
com.mybatis-flex
mybatis-flex-core
1.10.9
com.mybatis-flex
mybatis-flex-codegen
1.10.9
```
BaseEntity类继承了Serializable接口,并定义了如下属性:
- deleted 逻辑删除字段,默认为0表示正常,1表示已删除
- author 创建人字段
- created 创建时间字段
- editor 更新人字段
- modified 更新时间字段
### 异常
#### 跟踪过滤器类TagFilter
用于生成请求生命周期的跟踪标识ID,用于日志记录等场景;使用时候,请将此过滤器添加到SpringMVC、SpringBoot的过滤器链中。如果需要跟踪线程等其他情况,可在对应的线程等生命周期开始和结束合适的位置调用生成方法`TagFilter.preHandle(null)` 和销毁方法`TagFilter.afterCompletion()`;在SpringBoot中注册:
```java
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean tagFilterRegistration() {
FilterRegistrationBean beanTag = new FilterRegistrationBean<>();
beanTag.setFilter(new TagFilter()); // 直接实例化
beanTag.addUrlPatterns("/*"); // 指定过滤器要拦截的URL模式
beanTag.setName("tagFilter"); // 设置过滤器的名称
beanTag.setOrder(1); // 设置过滤器的执行顺序,建议为1
return beanTag;
}
}
```
日志记录中使用该跟踪标识ID(X-Tag-ID),logback示例:
完整最佳实践配置及带有该跟踪标识ID的日志配置说明,请[参考](#logconfigfile)
```xml
...其他配置...
```
### 文件(开发中)
#### 文件工具 FileUtility
- checkRealFileType 检查文件真实类型
- getFileMd5 获取文件的MD5值
- getFileETag 获取文件的ETag值
#### 文件传输工具 FileTransferUtility
- 工具环境初始化(仅需初始化一次,推荐在程序启动时初始化),参考文件存储服务的配置初始化
- getTemporarySignedUrl 获取临时签名URL
-
- download 下载文件(支持仅下载和浏览器打开),支持根据请求信息自动断点续传
#### 文件存储服务 FileStorageService
- 配置初始化
1. 添加依赖,根据使用的存储服务添加对应的依赖,如华为OBS对象存储服务
```xml
com.huaweicloud
esdk-obs-java
3.22.12
```
2. 实现存储服务配置接口`FileStorageConfigProvider`,实现getConfig方法,返回存储服务配置对象
- 基于非Spring容器管理初始化时,无需加任何注解
- 基于Spring容器管理初始化时,实现类需添加 @Component 注解
3. 调用`FileStorageService.setConfigProvider(new FileStorageConfigProviderImpl())`传入配置提供者
- 基于实现类自己注册(Spring Boot 推荐)
```java
@Component
public class FileStorageConfigProviderImpl implements FileStorageConfigProvider {
@Autowired
private FileStorageConfigService fileStorageConfigService; // 文件存储服务配置服务,表名为 file_storage_config
@PostConstruct
public void init() {
// 将当前类注册到 FileStorageService
FileStorageService.setConfigProvider(this);
}
@Override
public BaseConfig getConfig(String cid) {
// 如果需要支持多种类型,可根据 cid 前缀判断返回不同的配置对象
FileStorageConfig fileStorageConfig = fileStorageConfigService.getOne(cid);
// 初始化并返回对应存储服务的配置对象,以下为示例,具体根据实际存储服务配置对象进行初始化
if (fileStorageConfig != null) {
return new HuaweiObsConfig(cid,
fileStorageConfig.getAppKey(), fileStorageConfig.getSecretId(), fileStorageConfig.getEndPoint(),
fileStorageConfig.getBucketName());
}
return null;
}
}
```
- 基于 CommandLineRunner 注册(推荐)
```java
@Component
public class FileStorageInitRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
FileStorageService.setConfigProvider(new FileStorageConfigProviderImpl());
}
}
```
- 基于 @Configuration 注册(该方式与实现类自己注册的方式相似)
```java
@Configuration
public class FileStorageAutoConfig {
@Autowired
private FileStorageConfigProviderImpl configProvider;
@PostConstruct
public void init() {
FileStorageService.setConfigProvider(configProvider);
}
}
```
- 获取存储服务实例并直接调用,例如:
获取存储里的文件信息:`FileStorageService.getFileInfo(FileTransferInfo)`
- 获取存储服务的实例并间接调用对应存储的方法(不常用),例如:
获取OBS存储的客户端对象实例:`ObsClient obsClient = ((HuaweiObsFileStorage) FileStorageService.getInstance("huaweiObs")).getClient()`
### 网络
#### Http客户端工具 IntHubUtility
依赖
```xml
org.apache.httpcomponents.client5
httpclient5
5.1.3
org.apache.httpcomponents.client5
httpclient5-fluent
5.1.3
```
- getSharedHttpClient,getSharedIgnoreCertHttpClient 获取HttpClient实例,该实例是单例,可重复使用,线程安全
- getTrustStore 获取TrustStore实例,该实例是单例,可重复使用,线程安全,
注意该实例建议只保存信任证书,涉及高安全的加解密,签名等私钥证书建议是使用单独的密钥库存储
- 构建POST表单html字符串:buildPostForm(<提交的url>,<表单键值对Map>,<传null默认utf-8>)
- 发送GET请求、发送POST请求
- 配置说明
发送GET、POST请求可设置连接池连接数,可通过wos.xml配置文件中配置,
也可以通过`setIntHubConfig(IntHubConfig intHubConfig)`设置,该设置优先级高于配置文件配置
- 自定义证书配置,存放位置:src/main/resources/ca/truststore.jks
使用keytool工具创建信任库
```bash
keytool -import -alias "别名" -keystore "ca/truststore.jks的绝对路径" -file "证书绝对路径" -storepass changeit
# 别名,建议使用证书的Subject或Friendly Name
# 查询:openssl x509 -in "证书绝对路径" -text -noout
# 密码,默认changeit,保持与Java默认信任库一致,当需要自定义密码时需保证自定义jks文件和java运行环境默认的cacerts文件密码一致
# 修改jks密码:keytool -storepasswd -keystore "ca/truststore.jks的绝对路径" -storepass changeit -new "新密码"
```
如果证书密码与默认不一致,则在启动参数中-Djavax.net.ssl.trustStorePassword(推荐)或配置文件server.ssl.trust-store-password(不推荐,影响范围比较大)设置证书密码
#### Http工具 HttpUtility
- buildQueryString 构建已编码的查询串
- getCookie 获取Cookie值
- parseHttpDate 解析HTTP头中的时间戳
- toHttpDate 时间戳转HTTP头时间戳
- getClientIP 获取客户端IP
- isPublicIP 判断IP是否为公网IP
- isInternalIP 判断IP是否为内网IP
- isLocalhostIP 判断IP是否为本地回环IP
- isValidIp 判断IP是否合法
- isIPv4 判断IP是否为IPv4
- isIPv6 判断IP是否为IPv6
#### 邮件工具 MailUtility
```xml
com.sun.mail
jakarta.mail
2.0.1
```
### 安全
```xml
org.bouncycastle
bcprov-jdk18on
1.79
org.bouncycastle
bcpkix-jdk18on
1.79
```
- 加密
- 非对称加密RSA、SM2(开发中)
- 对称加密SM4、AES、3DES、DES,支持字节数组和字符串,推荐使用字符串
- 哈希(以下算法直接调用,其他使用HashUtility)
- BCrypt 验证当前密码并生成新密码哈希值validateAndReplacePassword
- BCrypt 哈希方法hashPassword、enhancedHashPassword
- BCrypt 验证方法verify、enhancedVerify(enhancedEntropy为true)
- BCrypt 专用盐生成方法generateSalt
- SCrypt 验证当前密码并生成新密码哈希值validateAndReplacePassword
- SCrypt 哈希方法hashPassword
- SCrypt 验证方法verify
- SCrypt 专用盐生成方法generateSalt
- 密文对象CipherText【字节密文与十六进制字符或Base64字符互转】
- 基于原始密文byte[]创建密文对象,Hex默认无分隔符,也可以指定分隔符
- 基于密文字符串(Hex不带分隔符、Hex带分隔符或Base64)创建密文对象
- getHexSeparator 获取密文对象中十六进制字符串的分隔符
- setHexSeparator 设置密文对象中十六进制字符串的分隔符
- getOriginal 获取密文对象原始密文byte[]
- setOriginal 设置密文对象原始密文byte[],用于改变原始密文,一般不用
- getBase64String 获取密文的Base64字符串
- getHexString 获取密文的十六进制字符串,需要分隔符时需先调用分割符设置方法
- Hash工具HashUtility,支持多种算法SM3、SHA、MD5等,参考枚举HashAlgorithmType
- HMAC签名工具HmacUtility,支持多种算法SM3、SHA、MD5等,参考枚举HashAlgorithmType,注意注释带有(Hmac)的
- 随机数工具RandomUtility,(支持伪随机数和安全随机数)
- 获取随机密码:getPassword
- 获取随机字符串:getString
- 获取随机数:getRandom
- 填充安全随机数:fill(ByteBuffer.wrap(目标数组, 起始位置, 长度))
### 其他工具
- 二进制操作工具 BitUtility【32比特循环移位】
- 常用常量定义 Constants
- 统一返回类 Result,主要对前端的返回统一样式,便于处理,JSON格式为
```json
{
"code":"200",
"data":"字符串或json对象",
"message":"正常或异常文本消息",
"timestamp":"yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式的日期"
}
```
- Result.success 创建成功返回
- Result.fail 创建失败返回
- codeType参数需要定义错误枚举,建议名称ResultCode或以此为前缀,
该枚举需实现接口(implements ResultCodeEnum),且至少定义两个枚举
```java
public enum ResultCodeIhs implements ResultCodeEnum {
/** 系统未知错误 */
SYSTEM_ERROR("B-00-0001"),
/** 成功 */
SUCCESS("200");
private String code;
ResultCodeIhs(String code) {
this.code = code;
}
@Override
public String getCode() {
return code;
}
}
```
- ResultCode枚举的国际化支持,须在src/main/resources/i18n/resultcode.properties中定义错误信息描述,用于message,定义的key用枚举名的小写,按上面的枚举示例如下:
```properties
result.success=成功。
result.system_error=系统繁忙,请稍后再试。
```
- 字符串工具 StringUtility
- 是否null和空
- 是否空白字符串
- 对比忽略大小写
- HTML转换为纯文本,保留换行
- HTML转换为单行纯文本
- 获取body内容,并清理无用标签
- 将驼峰式命名的字符串转换为下划线式(蛇形)命名的字符串
### 配置文件最佳实践
#### 默认配置文件(wos.xml)
- 配置文件位置:src/main/resources/wos.xml
- 该配置主要配置工具的基本属性,邮件工具的发件信息、Http客户端工具的连接池配置等
#### 日志配置文件(logback)
- 日志配置文件位置:src/main/resources/logback.xml
- sprspringboot项目,将logback.xml改名为logback-spring.xml,并添加到resources目录下,项目启动时会自动加载,且优先级高于logback.xml,通过\标签读取springboot配置文件里的属性,如spring.application.name
## 编译及工具说明
maven 工具使用3.6.3版本,java版本最低使用1.8,maven插件版本3.15.0版本
- SNAPSHOT版本发布到私有SNAPSHOT仓库,可调整distributionManagement的配置,maven工具直接执行deploy或命令:mvn clean deploy
- 正式版版本发布到中央仓库,使用maven命令:mvn clean deploy -P release
## 版本内容更新
[更新日志](CHANGELOG.md)