# 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)