mirror of
https://gitee.com/jzsw-it/yexuejc-base.git
synced 2025-06-06 22:04:04 +08:00
Merge branch 'master' into develop
This commit is contained in:
commit
75f7aaeb77
@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: javax.validation:validation-api:1.1.0.Final">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
41
README.md
41
README.md
@ -1,21 +1,49 @@
|
||||
通用工具包
|
||||
yexuejc-base 基于jdk8常用工具包
|
||||
----------------------
|
||||
源码地址:<br>
|
||||
github:https://github.com/yexuejc/yexuejc-base
|
||||
gitee:https://gitee.com/jzsw-it/yexuejc-base
|
||||
|
||||
### 说明
|
||||
>1. 支持环境:java8
|
||||
>2. 该工具包基于springboot提取,按理说适用于所有java工程
|
||||
>3. 其中依赖jjwt、validation-api,但不传递依赖
|
||||
>3. 其中依赖jjwt、validation-api,排除请使用
|
||||
> ```
|
||||
> <exclusions>
|
||||
> <exclusion>
|
||||
> <artifactId>xxx</artifactId>
|
||||
> <groupId>xxxx</groupId>
|
||||
> </exclusion>
|
||||
> </exclusions>
|
||||
> ```
|
||||
>
|
||||
>4. `1.1.9` 升级JWT为单例类
|
||||
>5. `1.2.3` 修复RSA加密(签名)Base64Url 问题,如需使用RSA请使用1.2.3+
|
||||
>##### 6. 从`1.3.0`开始,版本维护转由`成都极致思维网络科技有限公司`向maven中央仓库发布版本,同时变更组织`groupId`为`top.yexuejc`。使用者请尽快升级到`1.3.0`以上(1.3.0代码向下兼容)
|
||||
|
||||
|
||||
### 使用
|
||||
>yexuejc.base.version=1.1.7
|
||||
>yexuejc.base.version=1.3.0
|
||||
|
||||
pom.xml
|
||||
```
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>${yexuejc.base.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
#### 附:1.3.0之前的使用方式
|
||||
pom.xml
|
||||
```
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.base</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>${yexuejc.base.version}</version>
|
||||
<version>1.3.0以下</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
@ -32,3 +60,8 @@ pom.xml
|
||||
|
||||
### 更新日志
|
||||
[更新记录](UPDATE.md)
|
||||
|
||||
#### 项目发展
|
||||
本工程项目由maxf基于日常使用,从[yexuejc-springboot](https://github.com/yexuejc/yexuejc-springboot.git)(_准备移交版本控制_)中抽离开源独立发展,后续增加许多常用工具包。
|
||||
使用者逐渐增多后考虑可靠性和稳定性原则,移交版本控制给`成都极致思维网络科技有限公司`管理,maven包直接发布到中央仓库。
|
||||
开源工程项目仍然保持继续维护和欢迎更多愿意贡献的小伙伴参与。
|
||||
|
144
UPDATE.md
144
UPDATE.md
@ -1,6 +1,150 @@
|
||||
yexuejc-base 更新记录
|
||||
------------------
|
||||
|
||||
#### version :1.3.4
|
||||
**time:2019-1-2 20:32:12** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. objUtil list类型修复
|
||||
#
|
||||
#### version :1.3.3
|
||||
**time:2019-1-2 14:06:47** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. MoneyUtil 扩展元转分
|
||||
#
|
||||
#### version :1.3.2
|
||||
**time:2019-1-2 14:06:47** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. objUtil 枚举类型修复
|
||||
#
|
||||
#### version :1.3.1
|
||||
**time:2019-1-2 14:06:47** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. objUtil 增加类字段(驼峰)转换成下划线
|
||||
#
|
||||
#### version :1.3.0
|
||||
**time:2018-12-30 16:47:50** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 移交发布到maven中央仓库
|
||||
>2. 移交后变更groupId 为`top.yexuejc`
|
||||
>3. 源码发布由`成都极致思维网络科技有限公司`维护,github开源地址不变,gitee从组织[ICC(InCloudCode)](https://gitee.com/incloudcode)转移到[成都极致思维网络科技有限公司/yexuejc-base](https://gitee.com/jzsw-it/yexuejc-base)
|
||||
|
||||
#
|
||||
#### version :1.2.9
|
||||
**time:2018-12-29 14:51:33** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 获取RSA密钥增加以输入流的形式获取密钥
|
||||
|
||||
#
|
||||
#### version :1.2.6
|
||||
**time:2018-12-21 14:58:49** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. RSA 验签增加初始化方法
|
||||
|
||||
#
|
||||
#### version :1.2.8
|
||||
**time:2018-12-28 20:10:14** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 新增[ObjUtil](src/main/java/com/yexuejc/base/util/ObjUtil.java) 对类(对象)进行处理,提供深度克隆
|
||||
|
||||
#
|
||||
#### version :1.2.6
|
||||
**time:2018-12-21 14:58:49** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. RSA 验签增加初始化方法
|
||||
|
||||
#
|
||||
#### version :1.2.7
|
||||
**time:2018-12-24 15:31:01** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. FileUtil增加base64转File `base64ToFile()`
|
||||
|
||||
#
|
||||
#### version :1.2.6
|
||||
**time:2018-12-21 14:58:49** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. RSA 验签增加初始化方法
|
||||
|
||||
#
|
||||
#### version :1.2.5
|
||||
**time:2018-12-20 13:13:23** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 丰富[JsonUtil](src/main/java/com/yexuejc/base/util/JsonUtil.java),支持直接对Map泛型转换
|
||||
|
||||
#
|
||||
#### version :1.2.4
|
||||
**time:2018-11-27 14:46:04** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 工具类的优化
|
||||
>2.规范代码
|
||||
|
||||
#
|
||||
#### version :1.2.3
|
||||
**time:2018-11-23 16:45:42** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 修复RSA加密(签名)时选择的Base64(encodeBase64URLSafeString、encodeBase64String)区分
|
||||
#
|
||||
#### version :1.2.1
|
||||
**time:2018-11-9 15:05:06** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 优化resps
|
||||
#
|
||||
#### version :1.2.2
|
||||
**time:2018-11-20 20:20:12** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 优化RSA 加解密
|
||||
>1. 增加RSA 签名
|
||||
#
|
||||
#### version :1.2.1
|
||||
**time:2018-11-9 15:05:06** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 优化resps
|
||||
#
|
||||
#### version :1.2.0
|
||||
**time:2018-10-19 11:38:20** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 增加异步线程处理工具
|
||||
```$java
|
||||
SysUtil.threadRun(() -> {
|
||||
//异步执行代码块
|
||||
}
|
||||
```
|
||||
#
|
||||
|
||||
#### version :1.1.9
|
||||
**time:2018-9-23 11:57:36** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 优化工具类包名:不向下兼容,升级请修改
|
||||
>2. 升级JWT工具类:更改为单例模式,可配置参数
|
||||
#
|
||||
|
||||
#### version :1.1.8
|
||||
**time:2018-9-3 19:29:56** <br/>
|
||||
**branch:** master <br/>
|
||||
**update:** <br/>
|
||||
>1. 增肌图片处理工具类
|
||||
>2. 增肌3des工具类
|
||||
>3. 增肌RSA工具类
|
||||
>4. 优化其他工具类
|
||||
#
|
||||
#### version :1.1.7
|
||||
**time:2018-8-17 11:22:50** <br/>
|
||||
**branch:** master <br/>
|
||||
|
7
WIKI.md
7
WIKI.md
@ -24,5 +24,12 @@ yexuejc-base 文档
|
||||
##### 17. RegexUtils 常用正则
|
||||
##### 18. StrUtil 字符串工具
|
||||
##### 19. SysUtils 常用java系统操作封装
|
||||
##### 20. ObjUtil 对象的操作(深度克隆)
|
||||
|
||||
> com.yexuejc.base.encrypt 加密相关
|
||||
##### 21. RSA 加密
|
||||
##### 22. RSA2 RSA加密获取文件密钥
|
||||
##### 23. RSACoder RSA工具
|
||||
##### 24. SignAlgorithm 签名算法类型
|
||||
|
||||
待完善......
|
138
pom.xml
138
pom.xml
@ -4,14 +4,42 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yexuejc.base</groupId>
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>1.1.7</version>
|
||||
<version>1.3.4</version>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<url>https://github.com/yexuejc/yexuejc-base</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>yexuejc</name>
|
||||
<email>yexuejc@gmail.com</email>
|
||||
<organization>Chengdu Ultimate Thinking Network Technology Co., Ltd.</organization>
|
||||
<timezone>+8</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<scm>
|
||||
<connection>
|
||||
scm:git:https://github.com/yexuejc/yexuejc-base.git
|
||||
</connection>
|
||||
<developerConnection>
|
||||
scm:git:https://github.com/yexuejc/yexuejc-base.git
|
||||
</developerConnection>
|
||||
<url>https://github.com/yexuejc/yexuejc-base</url>
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<repos.yexuejc.url>https://nexus.yexuejc.club/repository/</repos.yexuejc.url>
|
||||
<repos.mcworle.url>https://nexus.mcworle.com/repository/</repos.mcworle.url>
|
||||
<repos.aliyun.url>http://maven.aliyun.com/nexus/content/groups/public</repos.aliyun.url>
|
||||
<repos.jitpack.url>https://jitpack.io</repos.jitpack.url>
|
||||
<jjwt.version>0.7.0</jjwt.version>
|
||||
@ -20,6 +48,8 @@
|
||||
<validation-api.version>1.1.0.Final</validation-api.version>
|
||||
<commons-codec.version>1.10</commons-codec.version>
|
||||
<commons-io.version>2.6</commons-io.version>
|
||||
<bcprov-jdk15on.version>1.60</bcprov-jdk15on.version>
|
||||
<guava.version>20.0</guava.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -48,6 +78,18 @@
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<!--支持大量的密码术算法,并提供JCE 1.2.1的实现-->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>${bcprov-jdk15on.version}</version>
|
||||
</dependency>
|
||||
<!--com.yexuejc.base.util.SysUtil.threadRun 异步处理代码-->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@ -59,8 +101,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 打包源码 -->
|
||||
@ -93,6 +135,33 @@
|
||||
<executable>true</executable>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Javadoc -->
|
||||
<!--<plugin>-->
|
||||
<!--<groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!--<artifactId>maven-javadoc-plugin</artifactId>-->
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<phase>package</phase>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>jar</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<!--</plugin>-->
|
||||
<!-- GPG -->
|
||||
<!--<plugin> <!– 进行延签 –>-->
|
||||
<!--<groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!--<artifactId>maven-gpg-plugin</artifactId>-->
|
||||
<!--<version>1.6</version>-->
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<phase>verify</phase>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>sign</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<!--</plugin>-->
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
@ -111,8 +180,22 @@
|
||||
<url>${repos.jitpack.url}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<!-- 中间件jar包发布目标 -->
|
||||
<distributionManagement>
|
||||
<!--中央仓库发布-->
|
||||
<!--<snapshotRepository>-->
|
||||
<!--<id>sonatype-nexus-snapshots</id>-->
|
||||
<!--<name>Sonatype Nexus Snapshots</name>-->
|
||||
<!--<url>https://oss.sonatype.org/content/repositories/snapshots/</url>-->
|
||||
<!--</snapshotRepository>-->
|
||||
<!--<repository>-->
|
||||
<!--<id>sonatype-nexus-staging</id>-->
|
||||
<!--<name>Nexus Release Repository</name>-->
|
||||
<!--<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>-->
|
||||
<!--</repository>-->
|
||||
|
||||
<!-- 私服仓库发布
|
||||
<repository>
|
||||
<id>releases</id>
|
||||
<name>nexus-release</name>
|
||||
@ -123,5 +206,52 @@
|
||||
<name>nexus-snapshots</name>
|
||||
<url>${repos.yexuejc.url}maven-snapshots/</url>
|
||||
</snapshotRepository>
|
||||
-->
|
||||
|
||||
<repository>
|
||||
<id>releases</id>
|
||||
<name>nexus-release</name>
|
||||
<url>${repos.mcworle.url}maven-releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>snapshots</id>
|
||||
<name>nexus-snapshots</name>
|
||||
<url>${repos.mcworle.url}maven-snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>sonatype-oss-release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
@ -2,10 +2,13 @@ package com.yexuejc.base.encrypt;
|
||||
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
@ -15,6 +18,7 @@ import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* RSA加解密 配置模式
|
||||
*
|
||||
@ -27,7 +31,65 @@ public class RSA {
|
||||
|
||||
public static final String CHARSET = "UTF-8";
|
||||
public static final String RSA_ALGORITHM = "RSA";
|
||||
/**
|
||||
* 加密方式
|
||||
* <pre>
|
||||
* RSA 可选择isChangeSign 是否每次改变加密结果
|
||||
* RSA/None/NoPadding 不改变加密结果
|
||||
* RSA/ECB/PKCS1Padding 改变加密结果
|
||||
* </pre>
|
||||
*/
|
||||
public static String RSA_ALGORITHM_ECB = "RSA";
|
||||
/**
|
||||
* 是否每次改变加密结果
|
||||
* 只针对于RSA_ALGORITHM_ECB = "RSA"有效
|
||||
*/
|
||||
public static boolean isChangeSign = true;
|
||||
/**
|
||||
* 是否使用 Base64URL 方式加密 默认正常加密
|
||||
* <pre>
|
||||
* 关于 Base64URL 和正常加密的区别:Base64URL会把 '+', '/' 转换成 '-', '_' 来防止请求时url上的转义
|
||||
* private static final byte[] STANDARD_ENCODE_TABLE = {
|
||||
* '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',
|
||||
* '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
* };
|
||||
* private static final byte[] URL_SAFE_ENCODE_TABLE = {
|
||||
* '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',
|
||||
* '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
|
||||
* };
|
||||
* </pre>
|
||||
*/
|
||||
public static boolean encodeBase64URLSafe = false;
|
||||
/**
|
||||
* 签名算法
|
||||
*/
|
||||
public static SignAlgorithm signAlgorithm = SignAlgorithm.SHA1withRSA;
|
||||
|
||||
|
||||
/**
|
||||
* 生成密钥对
|
||||
*
|
||||
* @param keySize 生成长度
|
||||
* @param base64URLSafe 是否生成 base64URL 格式的密钥:默认false
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> initKeys(int keySize, boolean base64URLSafe) {
|
||||
encodeBase64URLSafe = base64URLSafe;
|
||||
return initKeys(keySize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成密钥对
|
||||
*
|
||||
* @param keySize 生成长度
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> initKeys(int keySize) {
|
||||
//为RSA算法创建一个KeyPairGenerator对象
|
||||
KeyPairGenerator kpg;
|
||||
@ -43,11 +105,18 @@ public class RSA {
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
//得到公钥
|
||||
Key publicKey = keyPair.getPublic();
|
||||
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
|
||||
//得到私钥
|
||||
Key privateKey = keyPair.getPrivate();
|
||||
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
|
||||
Map<String, String> keyPairMap = new HashMap<String, String>();
|
||||
String privateKeyStr = null;
|
||||
String publicKeyStr = null;
|
||||
if (encodeBase64URLSafe) {
|
||||
publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
|
||||
privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
|
||||
} else {
|
||||
publicKeyStr = Base64.encodeBase64String(publicKey.getEncoded());
|
||||
privateKeyStr = Base64.encodeBase64String(privateKey.getEncoded());
|
||||
}
|
||||
Map<String, String> keyPairMap = new HashMap<String, String>(2);
|
||||
keyPairMap.put("publicKey", publicKeyStr);
|
||||
keyPairMap.put("privateKey", privateKeyStr);
|
||||
|
||||
@ -86,15 +155,32 @@ public class RSA {
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param data
|
||||
* @param publicKey
|
||||
* @param data 加密原串数据
|
||||
* @param publicKey 公钥
|
||||
* @param base64URLSafe 是否生成 base64URL 格式的密钥:默认false
|
||||
* @return
|
||||
*/
|
||||
public static String publicEncrypt(String data, RSAPublicKey publicKey, boolean base64URLSafe) {
|
||||
encodeBase64URLSafe = base64URLSafe;
|
||||
return publicEncrypt(data, publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param data 加密原串数据
|
||||
* @param publicKey 公钥
|
||||
* @return
|
||||
*/
|
||||
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
if (encodeBase64URLSafe) {
|
||||
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
|
||||
} else {
|
||||
return Base64.encodeBase64String(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
|
||||
}
|
||||
@ -107,10 +193,9 @@ public class RSA {
|
||||
* @param privateKey
|
||||
* @return
|
||||
*/
|
||||
|
||||
public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
|
||||
} catch (Exception e) {
|
||||
@ -118,19 +203,36 @@ public class RSA {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param data
|
||||
* @param privateKey
|
||||
* @param data 加密原串数据
|
||||
* @param privateKey 公钥
|
||||
* @param base64URLSafe 是否生成 base64URL 格式的密钥:默认false
|
||||
* @return
|
||||
*/
|
||||
public static String privateEncrypt(String data, RSAPrivateKey privateKey, boolean base64URLSafe) {
|
||||
encodeBase64URLSafe = base64URLSafe;
|
||||
return privateEncrypt(data, privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param data 加密原串数据
|
||||
* @param privateKey 公钥
|
||||
* @return
|
||||
*/
|
||||
public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
if (encodeBase64URLSafe) {
|
||||
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
|
||||
} else {
|
||||
return Base64.encodeBase64String(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
|
||||
}
|
||||
@ -146,7 +248,7 @@ public class RSA {
|
||||
|
||||
public static String publicDecrypt(String data, RSAPublicKey publicKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
Cipher cipher = getCipher();
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
|
||||
} catch (Exception e) {
|
||||
@ -154,6 +256,25 @@ public class RSA {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Cipher
|
||||
*
|
||||
* @return
|
||||
* @throws NoSuchPaddingException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws NoSuchProviderException
|
||||
*/
|
||||
private static Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
|
||||
Cipher cipher;
|
||||
if ("RSA".equals(RSA_ALGORITHM_ECB) && isChangeSign) {
|
||||
cipher = Cipher.getInstance(RSA_ALGORITHM_ECB);
|
||||
} else {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
cipher = Cipher.getInstance(RSA_ALGORITHM_ECB, "BC");
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
|
||||
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
|
||||
int maxBlock = 0;
|
||||
if (opmode == Cipher.DECRYPT_MODE) {
|
||||
@ -180,8 +301,96 @@ public class RSA {
|
||||
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
|
||||
}
|
||||
byte[] resultDatas = out.toByteArray();
|
||||
IOUtils.closeQuietly(out);
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return resultDatas;
|
||||
}
|
||||
|
||||
private static Signature signature;
|
||||
|
||||
|
||||
/**
|
||||
* /**
|
||||
* 私钥签名:默认算法SHA1withRSA
|
||||
* <p>
|
||||
* 签名算法 {@link SignAlgorithm}
|
||||
* </p>
|
||||
*
|
||||
* @param plaintext 签名字符串
|
||||
* @param privateKey 签名私钥
|
||||
* @param base64URLSafe 是否生成 base64URL 格式的密钥:默认false
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static String sign(String plaintext, RSAPrivateKey privateKey, boolean base64URLSafe) throws NoSuchAlgorithmException {
|
||||
encodeBase64URLSafe = base64URLSafe;
|
||||
return sign(plaintext, privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥签名:默认算法SHA1withRSA
|
||||
* <p>
|
||||
* 签名算法 {@link SignAlgorithm}
|
||||
* </p>
|
||||
*
|
||||
* @param plaintext 签名字符串
|
||||
* @param privateKey 签名私钥
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static String sign(String plaintext, RSAPrivateKey privateKey) throws NoSuchAlgorithmException {
|
||||
signature = Signature.getInstance(signAlgorithm.getValue());
|
||||
String signBase64Str = "";
|
||||
|
||||
try {
|
||||
signature.initSign(privateKey);
|
||||
try {
|
||||
signature.update(plaintext.getBytes(CHARSET));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("签名字符串[" + plaintext + "]的数据时发生异常", e);
|
||||
}
|
||||
if (encodeBase64URLSafe) {
|
||||
signBase64Str = Base64.encodeBase64URLSafeString(signature.sign());
|
||||
} else {
|
||||
signBase64Str = Base64.encodeBase64String(signature.sign());
|
||||
}
|
||||
return signBase64Str;
|
||||
} catch (InvalidKeyException var6) {
|
||||
var6.printStackTrace();
|
||||
throw new RuntimeException("签名字符串[" + plaintext + "]的数据时发生异常", var6);
|
||||
} catch (SignatureException var7) {
|
||||
var7.printStackTrace();
|
||||
throw new RuntimeException("签名字符串[" + plaintext + "]的数据时发生异常", var7);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥校验签名
|
||||
*
|
||||
* @param plaintext 原串
|
||||
* @param signStr 签名串
|
||||
* @param publicKey 公钥
|
||||
* @return
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public static boolean verify(String plaintext, String signStr, RSAPublicKey publicKey) throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
||||
signature = Signature.getInstance(signAlgorithm.getValue());
|
||||
boolean isValid = false;
|
||||
try {
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(plaintext.getBytes(CHARSET));
|
||||
isValid = signature.verify(Base64.decodeBase64(signStr));
|
||||
} catch (InvalidKeyException var6) {
|
||||
var6.printStackTrace();
|
||||
throw new RuntimeException("校验签名字符串[" + plaintext + "]的数据时发生异常", var6);
|
||||
} catch (SignatureException var7) {
|
||||
var7.printStackTrace();
|
||||
throw new RuntimeException("校验签名字符串[" + plaintext + "]的数据时发生异常", var7);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
package com.yexuejc.base.encrypt;
|
||||
|
||||
import com.yexuejc.base.util.StrUtil;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -12,10 +15,12 @@ import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* RSA加解密 证书模式
|
||||
* 依赖 {@link RSA}
|
||||
*
|
||||
* @ClassName: RSA2
|
||||
* @Description:
|
||||
* @author: maxf
|
||||
@ -41,7 +46,22 @@ public class RSA2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到私钥
|
||||
* 得到公钥
|
||||
*
|
||||
* @param pubKeyIn 密钥文件流
|
||||
* @return
|
||||
* @throws CertificateException
|
||||
*/
|
||||
public static RSAPublicKey getPublicKey(InputStream pubKeyIn) throws CertificateException {
|
||||
//通过证书,获取公钥
|
||||
CertificateFactory cf = null;
|
||||
cf = CertificateFactory.getInstance("X.509");
|
||||
Certificate c = cf.generateCertificate(pubKeyIn);
|
||||
return (RSAPublicKey) c.getPublicKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取JKS格式的key(私钥)keystore格式
|
||||
*
|
||||
* @param filepath 私钥路径
|
||||
* @param alias 证书别名
|
||||
@ -54,8 +74,121 @@ public class RSA2 {
|
||||
* @throws UnrecoverableKeyException
|
||||
*/
|
||||
public static RSAPrivateKey getPrivateKey(String filepath, String alias, String password) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
ks.load(new FileInputStream(filepath), password.toCharArray());
|
||||
return getPrivateKey(filepath, alias, password, "JKS");
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取JKS格式的key(私钥)keystore格式
|
||||
*
|
||||
* @param priKeyIn 私钥文件流
|
||||
* @param alias 证书别名
|
||||
* @param password 证书密码
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws KeyStoreException
|
||||
* @throws IOException
|
||||
* @throws CertificateException
|
||||
* @throws UnrecoverableKeyException
|
||||
*/
|
||||
public static RSAPrivateKey getPrivateKey(InputStream priKeyIn, String alias, String password) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
|
||||
return getPrivateKey(priKeyIn, alias, password, "JKS");
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取PKCS12格式的key(私钥)pfx格式
|
||||
*
|
||||
* @param filepath 私钥路径
|
||||
* @param alias 证书别名 可空
|
||||
* @param password 证书密码
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws KeyStoreException
|
||||
* @throws IOException
|
||||
* @throws CertificateException
|
||||
* @throws UnrecoverableKeyException
|
||||
*/
|
||||
public static RSAPrivateKey getPrivateKeyFromPKCS12(String filepath, String alias, String password) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
|
||||
return getPrivateKey(filepath, alias, password, "PKCS12");
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取PKCS12格式的key(私钥)pfx格式
|
||||
*
|
||||
* @param priKeyIn 私钥文件流
|
||||
* @param alias 证书别名 可空
|
||||
* @param password 证书密码
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws KeyStoreException
|
||||
* @throws IOException
|
||||
* @throws CertificateException
|
||||
* @throws UnrecoverableKeyException
|
||||
*/
|
||||
public static RSAPrivateKey getPrivateKeyFromPKCS12(InputStream priKeyIn, String alias, String password) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
|
||||
return getPrivateKey(priKeyIn, alias, password, "PKCS12");
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取key(私钥)
|
||||
*
|
||||
* @param filepath 私钥路径
|
||||
* @param alias 证书别名 可空
|
||||
* @param password 证书密码
|
||||
* @param type 证书格式
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws KeyStoreException
|
||||
* @throws IOException
|
||||
* @throws CertificateException
|
||||
* @throws UnrecoverableKeyException
|
||||
*/
|
||||
public static RSAPrivateKey getPrivateKey(String filepath, String alias, String password, String type) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
|
||||
KeyStore ks = KeyStore.getInstance(type);
|
||||
FileInputStream fileInputStream = null;
|
||||
try {
|
||||
fileInputStream = new FileInputStream(filepath);
|
||||
ks.load(fileInputStream, password.toCharArray());
|
||||
if (StrUtil.isEmpty(alias)) {
|
||||
Enumeration<?> aliases = ks.aliases();
|
||||
if (aliases != null) {
|
||||
if (aliases.hasMoreElements()) {
|
||||
alias = (String) aliases.nextElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (fileInputStream != null) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
}
|
||||
return (RSAPrivateKey) ks.getKey(alias, password.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取key(私钥)
|
||||
*
|
||||
* @param priKeyIn 私钥文件流
|
||||
* @param alias 证书别名 可空
|
||||
* @param password 证书密码
|
||||
* @param type 证书格式
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws KeyStoreException
|
||||
* @throws IOException
|
||||
* @throws CertificateException
|
||||
* @throws UnrecoverableKeyException
|
||||
*/
|
||||
public static RSAPrivateKey getPrivateKey(InputStream priKeyIn, String alias, String password, String type) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
|
||||
KeyStore ks = KeyStore.getInstance(type);
|
||||
ks.load(priKeyIn, password.toCharArray());
|
||||
if (StrUtil.isEmpty(alias)) {
|
||||
Enumeration<?> aliases = ks.aliases();
|
||||
if (aliases != null) {
|
||||
if (aliases.hasMoreElements()) {
|
||||
alias = (String) aliases.nextElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
return (RSAPrivateKey) ks.getKey(alias, password.toCharArray());
|
||||
}
|
||||
|
||||
|
200
src/main/java/com/yexuejc/base/encrypt/RSACoder.java
Normal file
200
src/main/java/com/yexuejc/base/encrypt/RSACoder.java
Normal file
@ -0,0 +1,200 @@
|
||||
package com.yexuejc.base.encrypt;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* RSA 加解密 工具模式
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName RSACoder
|
||||
* @Description
|
||||
* @date 2018/9/3 16:13
|
||||
*/
|
||||
public class RSACoder {
|
||||
|
||||
public static final String KEY_ALGORITHM = "RSA";
|
||||
|
||||
/**
|
||||
* 解密<br>
|
||||
* 用公钥解密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPublic(String data, String key)
|
||||
throws Exception {
|
||||
return getDataByPublicKey(data, key, Cipher.DECRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密<br>
|
||||
* 用私钥解密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPrivateKey(String data, String key)
|
||||
throws Exception {
|
||||
return getDataByPrivateKey(data, key, Cipher.DECRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密<br>
|
||||
* 用公钥加密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPublicKey(String data, String key)
|
||||
throws Exception {
|
||||
return getDataByPublicKey(data, key, Cipher.ENCRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密<br>
|
||||
* 用私钥加密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPrivateKey(String data, String key)
|
||||
throws Exception {
|
||||
return getDataByPrivateKey(data, key, Cipher.ENCRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密<br>
|
||||
* 用公钥解密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPublic(byte[] data, String key)
|
||||
throws Exception {
|
||||
return getDataByPublicKey(data, key, Cipher.DECRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密<br>
|
||||
* 用私钥解密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPrivateKey(byte[] data, String key)
|
||||
throws Exception {
|
||||
return getDataByPrivateKey(data, key, Cipher.DECRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密<br>
|
||||
* 用公钥加密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPublicKey(byte[] data, String key)
|
||||
throws Exception {
|
||||
return getDataByPublicKey(data, key, Cipher.ENCRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密<br>
|
||||
* 用私钥加密
|
||||
*
|
||||
* @param data
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPrivateKey(byte[] data, String key)
|
||||
throws Exception {
|
||||
return getDataByPrivateKey(data, key, Cipher.ENCRYPT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过公钥获得加解密数据
|
||||
*
|
||||
* @param data String
|
||||
* @param key String
|
||||
* @param mode int
|
||||
* @return
|
||||
*/
|
||||
public static byte[] getDataByPublicKey(String data, String key, int mode)
|
||||
throws Exception {
|
||||
return getDataByPublicKey(data.getBytes(), key, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过私钥获得加解密数据
|
||||
*
|
||||
* @param data String
|
||||
* @param key String
|
||||
* @param mode 加密或解密
|
||||
* @return
|
||||
*/
|
||||
public static byte[] getDataByPrivateKey(String data, String key, int mode)
|
||||
throws Exception {
|
||||
return getDataByPrivateKey(data.getBytes(), key, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过公钥获得加解密数据
|
||||
*
|
||||
* @param data String
|
||||
* @param key String
|
||||
* @param mode int
|
||||
* @return
|
||||
*/
|
||||
public static byte[] getDataByPublicKey(byte[] data, String key, int mode)
|
||||
throws Exception {
|
||||
// 取得私钥
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(key.getBytes("UTF-8")));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key privateKey = keyFactory.generatePublic(x509KeySpec);
|
||||
// 对数据进行加密或解密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(mode, privateKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过私钥获得加解密数据
|
||||
*
|
||||
* @param data String
|
||||
* @param key String
|
||||
* @param mode 加密或解密
|
||||
* @return
|
||||
*/
|
||||
public static byte[] getDataByPrivateKey(byte[] data, String key, int mode)
|
||||
throws Exception {
|
||||
// 取得私钥
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(key.getBytes("UTF-8")));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
// 对数据解密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(mode, privateKey);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
}
|
57
src/main/java/com/yexuejc/base/encrypt/SignAlgorithm.java
Normal file
57
src/main/java/com/yexuejc/base/encrypt/SignAlgorithm.java
Normal file
@ -0,0 +1,57 @@
|
||||
package com.yexuejc.base.encrypt;
|
||||
|
||||
/**
|
||||
* 签名算法类型
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName SignAlgorithm
|
||||
* @Description 签名算法类型 参考Hutool https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Signature
|
||||
* @date 2018/11/26 10:25
|
||||
* @see 1.0
|
||||
*/
|
||||
public enum SignAlgorithm {
|
||||
// The RSA signature algorithm
|
||||
NONEwithRSA("NONEwithRSA"),
|
||||
|
||||
// The MD2/MD5 with RSA Encryption signature algorithm
|
||||
MD2withRSA("MD2withRSA"),
|
||||
MD5withRSA("MD5withRSA"),
|
||||
|
||||
// The signature algorithm with SHA-* and the RSA
|
||||
SHA1withRSA("SHA1withRSA"),
|
||||
SHA256withRSA("SHA256withRSA"),
|
||||
SHA384withRSA("SHA384withRSA"),
|
||||
SHA512withRSA("SHA512withRSA"),
|
||||
|
||||
// The Digital Signature Algorithm
|
||||
NONEwithDSA("NONEwithDSA"),
|
||||
// The DSA with SHA-1 signature algorithm
|
||||
SHA1withDSA("SHA1withDSA"),
|
||||
|
||||
// The ECDSA signature algorithms
|
||||
NONEwithECDSA("NONEwithECDSA"),
|
||||
SHA1withECDSA("SHA1withECDSA"),
|
||||
SHA256withECDSA("SHA256withECDSA"),
|
||||
SHA384withECDSA("SHA384withECDSA"),
|
||||
SHA512withECDSA("SHA512withECDSA");
|
||||
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param value 算法字符表示,区分大小写
|
||||
*/
|
||||
private SignAlgorithm(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取算法字符串表示,区分大小写
|
||||
*
|
||||
* @return 算法字符串表示
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
@ -59,18 +59,18 @@ public class Resps<T> implements Serializable {
|
||||
}
|
||||
|
||||
public Resps<T> setSucc(T t) {
|
||||
setSucc(t, RespsConsts.MSG_SUCCESS_OPERATE);
|
||||
this.data = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resps<T> setSucc(T t, String msg) {
|
||||
setSucc(t, new String[]{msg});
|
||||
this.setMsg(new String[]{msg});
|
||||
this.setData(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resps<T> setSucc(T t, String[] msg) {
|
||||
this.setData(t);
|
||||
this.setCode(RespsConsts.CODE_SUCCESS);
|
||||
this.setMsg(msg);
|
||||
return this;
|
||||
}
|
||||
@ -81,6 +81,14 @@ public class Resps<T> implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Resps success(String code, String msg) {
|
||||
return new Resps(code, msg);
|
||||
}
|
||||
|
||||
public static Resps success(String code, String[] msg) {
|
||||
return new Resps(code, msg);
|
||||
}
|
||||
|
||||
public static Resps success(String[] msg) {
|
||||
return new Resps(RespsConsts.CODE_SUCCESS, msg);
|
||||
}
|
||||
@ -93,6 +101,10 @@ public class Resps<T> implements Serializable {
|
||||
return new Resps(RespsConsts.CODE_SUCCESS, RespsConsts.MSG_SUCCESS_OPERATE);
|
||||
}
|
||||
|
||||
public static Resps error() {
|
||||
return new Resps(RespsConsts.CODE_ERROR, RespsConsts.MSG_ERROT_OPERATE);
|
||||
}
|
||||
|
||||
public static Resps error(String msg) {
|
||||
return new Resps(RespsConsts.CODE_ERROR, msg);
|
||||
}
|
||||
@ -109,6 +121,10 @@ public class Resps<T> implements Serializable {
|
||||
return new Resps(code, msg);
|
||||
}
|
||||
|
||||
public static Resps fail() {
|
||||
return new Resps(RespsConsts.CODE_FAIL, RespsConsts.MSG_FAIL_OPERATE);
|
||||
}
|
||||
|
||||
public static Resps fail(String msg) {
|
||||
return new Resps(RespsConsts.CODE_FAIL, msg);
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ package com.yexuejc.base.util;
|
||||
* @author: maxf
|
||||
* @date: 2017年11月23日 下午3:17:58
|
||||
*/
|
||||
public class AlgorithmUtils {
|
||||
public class AlgorithmUtil {
|
||||
private static final int LENGTH_1 = 1;
|
||||
private static final int LENGTH_2 = 2;
|
||||
private static final int LENGTH_3 = 3;
|
||||
private static final int LENGTH_36 = 36;
|
||||
|
||||
private AlgorithmUtils() {
|
||||
private AlgorithmUtil() {
|
||||
}
|
||||
|
||||
private static final String X36 = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
@ -77,7 +77,7 @@ public class AlgorithmUtils {
|
||||
* @throw
|
||||
*/
|
||||
public static int x36ConvertTo10(String pStr) {
|
||||
if (pStr == "") {
|
||||
if (StrUtil.isEmpty(pStr)) {
|
||||
return 0;
|
||||
}
|
||||
// 目标十进制数初始化为0
|
||||
@ -107,4 +107,47 @@ public class AlgorithmUtils {
|
||||
static class NextCodeException extends Exception {
|
||||
private static final long serialVersionUID = 8956943499144648985L;
|
||||
}
|
||||
|
||||
/**
|
||||
* 16进制转为2进制
|
||||
*
|
||||
* @param hexString 16进制字符串
|
||||
*/
|
||||
public static String x16ConvertTo2(String hexString) {
|
||||
if (hexString == null || hexString.length() % 2 != 0) {
|
||||
return null;
|
||||
}
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; i < hexString.length(); i++) {
|
||||
String tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
|
||||
buf.append(tmp.substring(tmp.length() - 4));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 16进制转为2进制byte[]
|
||||
*
|
||||
* @param hexString 16进制字符串
|
||||
* @return
|
||||
*/
|
||||
public static byte[] hexStringToBytes(String hexString) {
|
||||
if (hexString == null || "".equals(hexString)) {
|
||||
return null;
|
||||
}
|
||||
hexString = hexString.toUpperCase();
|
||||
int length = hexString.length() / 2;
|
||||
char[] hexChars = hexString.toCharArray();
|
||||
byte[] d = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int pos = i * 2;
|
||||
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private static byte charToByte(char c) {
|
||||
return (byte) "0123456789ABCDEF".indexOf(c);
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,9 @@ import java.util.Date;
|
||||
* @date: 2018/3/27 10:44
|
||||
*/
|
||||
public class DateTimeUtil {
|
||||
private DateTimeUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本年第一天
|
||||
*
|
||||
@ -106,8 +109,9 @@ public class DateTimeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static LocalDate getWeek4First(LocalDate date) {
|
||||
TemporalAdjuster FIRST_OF_WEEK = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()));
|
||||
return date.with(FIRST_OF_WEEK);
|
||||
TemporalAdjuster firstOfWeek = TemporalAdjusters.ofDateAdjuster(localDate ->
|
||||
localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()));
|
||||
return date.with(firstOfWeek);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,8 +130,9 @@ public class DateTimeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static LocalDate getWeek4Last(LocalDate date) {
|
||||
TemporalAdjuster LAST_OF_WEEK = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.plusDays(DayOfWeek.SUNDAY.getValue() - localDate.getDayOfWeek().getValue()));
|
||||
return date.with(LAST_OF_WEEK);
|
||||
TemporalAdjuster lastOfWeek = TemporalAdjusters.ofDateAdjuster(localDate ->
|
||||
localDate.plusDays(DayOfWeek.SUNDAY.getValue() - localDate.getDayOfWeek().getValue()));
|
||||
return date.with(lastOfWeek);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,22 +273,22 @@ public class DateTimeUtil {
|
||||
return df.format(dateTime);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
// System.out.println(df.format(zonedDateTime2Date(ZonedDateTime.now())));
|
||||
// System.out.println(df2.format(date2ZonedDateTime(new Date())));
|
||||
/** public static void main(String[] args) {
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
System.out.println(df.format(zonedDateTime2Date(ZonedDateTime.now())));
|
||||
System.out.println(df2.format(date2ZonedDateTime(new Date())));
|
||||
|
||||
// System.out.println(getWeek4First());
|
||||
System.out.println(getWeek4First());
|
||||
System.out.println(format(getWeek4First(LocalDate.parse("2018-02-10")).atTime(LocalTime.MIN)));
|
||||
System.out.println(format(getWeek4Last(LocalDate.parse("2018-02-10")).atTime(LocalTime.MAX)));
|
||||
|
||||
// System.out.println(format(getMonth4First().atTime(LocalTime.MIN)));
|
||||
// System.out.println(format(getMonth4Last().atTime(LocalTime.MAX)));
|
||||
System.out.println(format(getMonth4First().atTime(LocalTime.MIN)));
|
||||
System.out.println(format(getMonth4Last().atTime(LocalTime.MAX)));
|
||||
|
||||
// System.out.println(format(getYear4First().atTime(LocalTime.MIN)));
|
||||
// System.out.println(format(getYear4Last().atTime(LocalTime.MAX)));
|
||||
System.out.println(format(getYear4First().atTime(LocalTime.MIN)));
|
||||
System.out.println(format(getYear4Last().atTime(LocalTime.MAX)));
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,14 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* java.util.Date 时间工具类
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName DateUtil
|
||||
* @Description
|
||||
* @date 2018/9/3 15:27
|
||||
*/
|
||||
public class DateUtil {
|
||||
private DateUtil() {
|
||||
}
|
||||
@ -71,7 +79,7 @@ public class DateUtil {
|
||||
/**
|
||||
* 日期字符串转date
|
||||
*
|
||||
* @param date
|
||||
* @param dateStr
|
||||
* @return Date
|
||||
* @throws ParseException
|
||||
*/
|
||||
@ -81,7 +89,7 @@ public class DateUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期字符串转date
|
||||
* date转字符串
|
||||
*
|
||||
* @param date
|
||||
* @return Date
|
||||
@ -95,6 +103,34 @@ public class DateUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期字符串转dateTime
|
||||
*
|
||||
* @param dateStr
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Date str2dateTime(String dateStr) throws ParseException {
|
||||
Date date = DATE_TIME_FORMAT.parse(dateStr);
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* dateTime转字符串
|
||||
*
|
||||
* @param date
|
||||
* @return Date
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static String dateTime2str(Date date) throws ParseException {
|
||||
if (date != null) {
|
||||
return DATE_TIME_FORMAT.format(date);
|
||||
} else {
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取本周的日期
|
||||
*
|
||||
|
@ -8,8 +8,9 @@ package com.yexuejc.base.util;
|
||||
* @author: maxf
|
||||
* @date: 2017/12/27 16:42
|
||||
*/
|
||||
public class ExcelImportUtils {
|
||||
|
||||
public class ExcelImportUtil {
|
||||
private ExcelImportUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是2003的excel,返回true是2003
|
||||
@ -40,7 +41,8 @@ public class ExcelImportUtils {
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateExcel(String filePath) {
|
||||
if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
|
||||
boolean b = filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath));
|
||||
if (b) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
@ -1,38 +1,69 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
/**
|
||||
* 文件工具类
|
||||
*
|
||||
* @author maxf:yexue
|
||||
* @className FileUtil
|
||||
* @description 工具类
|
||||
* @time 2017年11月3日 下午3:12:49
|
||||
*/
|
||||
public class FileUtil {
|
||||
static Logger logger = Logger.getLogger(FileUtil.class.getName());
|
||||
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
private static final String TYPE_TAR_GZ = ".tar.gz";
|
||||
private static final String TAR_GZ = "tar.gz";
|
||||
|
||||
/**
|
||||
* 获取文件类型:不适合所有
|
||||
* <p>
|
||||
* 根据文件名称截取.后的文件格式
|
||||
* </p>
|
||||
*
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static String getFileType(String fileName) {
|
||||
try {
|
||||
if (fileName.lastIndexOf(TYPE_TAR_GZ) > 0) {
|
||||
return TAR_GZ;
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
} catch (Exception e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 判断文件是否存在
|
||||
/**
|
||||
* 判断文件是否存在
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public static void judeFileExists(File file) {
|
||||
|
||||
if (file.exists()) {
|
||||
System.out.println("file exists");
|
||||
logger.severe("file exists");
|
||||
} else {
|
||||
System.out.println("file not exists, create it ...");
|
||||
logger.info("file not exists, create it ...");
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
logger.severe("file create fail");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -49,20 +80,338 @@ public class FileUtil {
|
||||
* 4、File类的createTempFile方法创建临时文件,可以制定临时文件的文件名前缀、后缀及文件所在的目录,如果不指定目录,则存放在系统的临时文件夹下。
|
||||
* 5、除mkdirs方法外,以上方法在创建文件和目录时,必须保证目标文件不存在,而且父目录存在,否则会创建失败
|
||||
* </pre>
|
||||
*
|
||||
* @return 创建成功、失败
|
||||
*/
|
||||
public static void judeDirExists(File file) {
|
||||
|
||||
public static boolean judeDirExists(File file) {
|
||||
if (file.exists()) {
|
||||
if (file.isDirectory()) {
|
||||
System.out.println("dir exists");
|
||||
logger.severe("dir exists");
|
||||
} else {
|
||||
System.out.println("the same name file exists, can not create dir");
|
||||
logger.severe("the same name file exists, can not create dir");
|
||||
}
|
||||
} else {
|
||||
System.out.println("dir not exists, create it ...");
|
||||
file.mkdirs();
|
||||
logger.info("dir not exists, create it ...");
|
||||
return file.mkdirs();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件sha1
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static String sha1(File file) {
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||
byte[] buffer = new byte[1024 * 1024 * 10];
|
||||
|
||||
int len = 0;
|
||||
while ((len = in.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, len);
|
||||
}
|
||||
String sha1 = new BigInteger(1, digest.digest()).toString(16);
|
||||
int length = 40 - sha1.length();
|
||||
if (length > 0) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
sha1 = "0" + sha1;
|
||||
}
|
||||
}
|
||||
return sha1;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
logger.severe("system algorithm error.");
|
||||
e.printStackTrace();
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe("close FileInputStream IO exception.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 计算SHA1码
|
||||
*
|
||||
* @return String 适用于上G大的文件
|
||||
* @throws NoSuchAlgorithmException
|
||||
* */
|
||||
public static String sha1ByBigFile(File file) {
|
||||
MessageDigest messagedigest = null;
|
||||
try {
|
||||
messagedigest = MessageDigest.getInstance("SHA-1");
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
FileChannel ch = in.getChannel();
|
||||
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
|
||||
messagedigest.update(byteBuffer);
|
||||
return StrUtil.toHex(messagedigest.digest());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
logger.severe("system algorithm error.");
|
||||
e.printStackTrace();
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件md5
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static String md5(File file) {
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
byte[] buffer = new byte[1024 * 1024 * 10];
|
||||
|
||||
int len = 0;
|
||||
while ((len = in.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, len);
|
||||
}
|
||||
String md5 = new BigInteger(1, digest.digest()).toString(16);
|
||||
int length = 32 - md5.length();
|
||||
if (length > 0) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
md5 = "0" + md5;
|
||||
}
|
||||
}
|
||||
return md5;
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
logger.severe("system algorithm error.");
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe("close FileInputStream IO exception.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对一个文件获取md5值
|
||||
*
|
||||
* @return md5串
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static String md5ByBigFile(File file) {
|
||||
|
||||
MessageDigest messagedigest = null;
|
||||
try {
|
||||
messagedigest = MessageDigest.getInstance("MD5");
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
FileChannel ch = in.getChannel();
|
||||
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
|
||||
file.length());
|
||||
messagedigest.update(byteBuffer);
|
||||
return StrUtil.toHex(messagedigest.digest());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
logger.severe("system algorithm error.");
|
||||
e.printStackTrace();
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件CRC32码
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String crc32(File file) {
|
||||
CRC32 crc32 = new CRC32();
|
||||
// MessageDigest.get
|
||||
FileInputStream fileInputStream = null;
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
byte[] buffer = new byte[8192];
|
||||
int length;
|
||||
while ((length = fileInputStream.read(buffer)) != -1) {
|
||||
crc32.update(buffer, 0, length);
|
||||
}
|
||||
return crc32.getValue() + "";
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (fileInputStream != null) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe("close FileInputStream IO exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件base64
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static String base64(File file) {
|
||||
FileInputStream fileInputStream = null;
|
||||
byte[] data = null;
|
||||
// 读取图片字节数组
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
data = new byte[fileInputStream.available()];
|
||||
fileInputStream.read(data);
|
||||
fileInputStream.close();
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 对字节数组Base64编码
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
return encoder.encode(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* base64转文件
|
||||
* <p>
|
||||
* <i>
|
||||
* 文件转base64请使用 {@link FileUtil#base64(File)}
|
||||
* </i>
|
||||
*
|
||||
* @param decode baseByte
|
||||
* @param fileName 文件名称(包含路径)
|
||||
* @return 返回保存地址
|
||||
*/
|
||||
public static String base64ToFile(byte[] decode, String fileName) {
|
||||
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(fileName);
|
||||
out.write(decode);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件大小 :直接返回大小
|
||||
*
|
||||
* @param f
|
||||
* @return f.length()
|
||||
*/
|
||||
public static long size(File f) {
|
||||
if (f.exists() && f.isFile()) {
|
||||
return f.length();
|
||||
} else {
|
||||
logger.info("file doesn't exist or is not a file");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件大小 : 用流的方式获取
|
||||
*
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static long size4Stream(File f) {
|
||||
FileChannel fc = null;
|
||||
try {
|
||||
if (f.exists() && f.isFile()) {
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
fc = fis.getChannel();
|
||||
return fc.size();
|
||||
} else {
|
||||
logger.info("file doesn't exist or is not a file");
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.severe("file doesn't exist or is not a file");
|
||||
} catch (IOException e) {
|
||||
logger.severe("The operation file is an IO exception.");
|
||||
} finally {
|
||||
if (null != fc) {
|
||||
try {
|
||||
fc.close();
|
||||
} catch (IOException e) {
|
||||
logger.severe("close FileInputStream IO exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*public static void main(String[] args) {
|
||||
long size = FileUtil.size(new File("E:\\OS\\deepin-15.6-amd64\\DeepinCloudPrintServerInstaller_1.0.0.1.exe"));
|
||||
System.out.println(size);
|
||||
System.out.println(1024 * 1024 * 5);
|
||||
if (size > 1024 * 1024 * 5) {
|
||||
System.out.println("文件最大5M");
|
||||
return;
|
||||
}
|
||||
|
||||
long s1 = fileSize(new File("E:\\OS\\cn_windows_10_consumer_editions_version_1803_updated_march_2018_x64_dvd_12063766.iso"));
|
||||
System.out.println(s1);
|
||||
long s2 = fileSize4Stream(new File("E:\\OS\\cn_windows_10_consumer_editions_version_1803_updated_march_2018_x64_dvd_12063766.iso"));
|
||||
System.out.println(s2);
|
||||
|
||||
String s1 = base64(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
||||
System.out.println(s1);
|
||||
|
||||
String s = sha1(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
||||
String s2 = sha1ByBigFile(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
||||
System.out.println(s);
|
||||
System.out.println(s2);
|
||||
|
||||
|
||||
String md5 = md5(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
||||
String md52 = md5ByBigFile(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
||||
System.out.println(md5);
|
||||
System.out.println(md52);
|
||||
|
||||
|
||||
String crc32 = crc32(new File("C:\\Users\\Administrator\\Desktop\\a.html"));
|
||||
System.out.println(crc32);
|
||||
}*/
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class IdcardValidator {
|
||||
/**
|
||||
* 每位加权因子
|
||||
*/
|
||||
private static int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
|
||||
private static int[] power = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
|
||||
|
||||
/**
|
||||
* 验证所有的身份证的合法性
|
||||
@ -167,9 +167,9 @@ public class IdcardValidator {
|
||||
// 获取第18位
|
||||
String idcard18Code = idcard.substring(17, 18);
|
||||
|
||||
char c[] = idcard17.toCharArray();
|
||||
char[] c = idcard17.toCharArray();
|
||||
|
||||
int bit[] = converCharToInt(c);
|
||||
int[] bit = converCharToInt(c);
|
||||
|
||||
int sum17 = 0;
|
||||
|
||||
@ -290,11 +290,11 @@ public class IdcardValidator {
|
||||
|
||||
String idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);
|
||||
|
||||
char c[] = idcard17.toCharArray();
|
||||
char[] c = idcard17.toCharArray();
|
||||
String checkCode = "";
|
||||
|
||||
// 将字符数组转为整型数组
|
||||
int bit[] = converCharToInt(c);
|
||||
int[] bit = converCharToInt(c);
|
||||
|
||||
int sum17 = 0;
|
||||
sum17 = getPowerSum(bit);
|
||||
|
429
src/main/java/com/yexuejc/base/util/ImgUtil.java
Normal file
429
src/main/java/com/yexuejc/base/util/ImgUtil.java
Normal file
@ -0,0 +1,429 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import sun.misc.BASE64Decoder;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 图片处理工具类
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName ImageUtil
|
||||
* @Description
|
||||
* @date 2018/9/3 15:25
|
||||
*/
|
||||
public class ImgUtil {
|
||||
private ImgUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一张网络图片转化成Base64字符串
|
||||
*
|
||||
* @param imgURL 网络图片url
|
||||
* @return String Base64字符串
|
||||
*/
|
||||
public static String getImageStrFromUrl(String imgURL) {
|
||||
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||
try {
|
||||
byte[] by = new byte[1024];
|
||||
InputStream is = getImageInputStreamFromUrl(null, imgURL);
|
||||
// 将内容读取内存中
|
||||
int len = -1;
|
||||
while ((len = is.read(by)) != -1) {
|
||||
data.write(by, 0, len);
|
||||
}
|
||||
// 关闭流
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 对字节数组Base64编码
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
return encoder.encode(data.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取网络图片url为输入流
|
||||
* <p>本方法未关闭io流,请自行关闭io流</p>
|
||||
* <p>is.close();</p>
|
||||
*
|
||||
* @param imgURL 网络图片url
|
||||
* @return InputStream 输入流
|
||||
* @throws IOException
|
||||
*/
|
||||
public static InputStream getImageInputStreamFromUrl(Proxy proxy, String imgURL) throws IOException {
|
||||
// 创建URL
|
||||
URL url = new URL(imgURL);
|
||||
// 创建链接
|
||||
HttpURLConnection conn;
|
||||
if (null == proxy) {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
} else {
|
||||
// 如果有代理则通过代理下载
|
||||
conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
}
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(5000);
|
||||
InputStream is = conn.getInputStream();
|
||||
return is;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取网络图片url为输入流
|
||||
* <p>本方法未关闭io流,请自行关闭io流</p>
|
||||
* <p>is.close();</p>
|
||||
*
|
||||
* @param imgURL
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static InputStream getImageInputStreamFromUrl(String imgURL) throws IOException {
|
||||
return getImageInputStreamFromUrl(null, imgURL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将图片文件流转换成字节数组
|
||||
* <p>
|
||||
* 好处就是字节数组可以多次利用,而流一旦读取过一次之后就不能再使用了
|
||||
*
|
||||
* @param proxy
|
||||
* @param targetUrl
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] getByteArrayFromInputStream(Proxy proxy, String targetUrl)
|
||||
throws MalformedURLException, IOException {
|
||||
InputStream is = getImageInputStreamFromUrl(proxy, targetUrl);
|
||||
return getByteArray(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图片文件流转换成字节数组
|
||||
* <p>
|
||||
* 好处就是字节数组可以多次利用,而流一旦读取过一次之后就不能再使用了
|
||||
*
|
||||
* @param targetUrl
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] getByteArrayFromInputStream(String targetUrl)
|
||||
throws MalformedURLException, IOException {
|
||||
return getByteArrayFromInputStream(null, targetUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图片文件流转换成字节数组
|
||||
*
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] getByteArray(InputStream is)
|
||||
throws MalformedURLException, IOException {
|
||||
// 把文件写到字节数组保存起来
|
||||
ByteArrayOutputStream fos = getByteArrayFromInputStream(is);
|
||||
byte[] bytes = fos.toByteArray();
|
||||
fos.close();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* ByteArrayOutputStream转换成字节数组
|
||||
*
|
||||
* @param fos
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] getByteArray(ByteArrayOutputStream fos)
|
||||
throws MalformedURLException, IOException {
|
||||
// 把文件写到字节数组保存起来
|
||||
byte[] bytes = fos.toByteArray();
|
||||
fos.close();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图片文件流转换成ByteArrayOutputStream
|
||||
* <p>本方法未关闭io流,请自行关闭io流</p>
|
||||
* <p>is.close();</p>
|
||||
*
|
||||
* @param is
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static ByteArrayOutputStream getByteArrayFromInputStream(InputStream is) throws IOException {
|
||||
// 把文件写到字节数组保存起来
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
ByteArrayOutputStream fos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = bis.read(buffer)) != -1) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
bis.close();
|
||||
return fos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果你已经将图片文件流InputStream读取出来放到一个字节数组
|
||||
* <p>
|
||||
* 那么根据这个字节数组也是可以转换成对应的图片流,并再次获取图片基本信息
|
||||
*
|
||||
* @param imgBytes
|
||||
* @return
|
||||
*/
|
||||
public static ImageInfo getImageInfoFromInputStream(byte[] imgBytes) {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(imgBytes);
|
||||
ImageInfo image = getImageInfoFromInputStream(in);
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从图片文件流读取图片文件的基本信息
|
||||
*
|
||||
* @param inputStream
|
||||
* @return
|
||||
*/
|
||||
public static ImageInfo getImageInfoFromInputStream(InputStream inputStream) {
|
||||
ImageInputStream imgStream = null;
|
||||
try {
|
||||
// 创建Image流
|
||||
imgStream = ImageIO.createImageInputStream(inputStream);
|
||||
Iterator<ImageReader> iter = ImageIO.getImageReaders(imgStream);
|
||||
if (!iter.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
// 读取流中一帧就可以获取到高宽以及各式
|
||||
ImageReader reader = iter.next();
|
||||
reader.setInput(imgStream, true);
|
||||
int width = reader.getWidth(0);
|
||||
int height = reader.getHeight(0);
|
||||
String type = reader.getFormatName();
|
||||
ImageInfo bean = new ImageInfo();
|
||||
bean.setWidth(width);
|
||||
bean.setHeight(height);
|
||||
bean.setType(type);
|
||||
return bean;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
imgStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将byte数组以Base64方式编码为字符串
|
||||
*
|
||||
* @param bytes 待编码的byte数组
|
||||
* @return String 编码后的字符串
|
||||
*/
|
||||
public static String encode(byte[] bytes) {
|
||||
return new BASE64Encoder().encode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将以Base64方式编码的字符串解码为byte数组
|
||||
*
|
||||
* @param encodeStr 待解码的字符串
|
||||
* @return byte[] 解码后的byte数组
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] decode(String encodeStr) throws IOException {
|
||||
byte[] bt = null;
|
||||
BASE64Decoder decoder = new BASE64Decoder();
|
||||
bt = decoder.decodeBuffer(encodeStr);
|
||||
return bt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将两个byte数组连接起来后,返回连接后的Byte数组
|
||||
*
|
||||
* @param front 拼接后在前面的数组
|
||||
* @param after 拼接后在后面的数组
|
||||
* @return byte[] 拼接后的数组
|
||||
*/
|
||||
public static byte[] connectBytes(byte[] front, byte[] after) {
|
||||
byte[] result = new byte[front.length + after.length];
|
||||
System.arraycopy(front, 0, result, 0, after.length);
|
||||
System.arraycopy(after, 0, result, front.length, after.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将流保存至本机或者图片服务器
|
||||
*
|
||||
* @param in 图片流
|
||||
* @param saveUrl 目标地址
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void saveImgFromInputStream(InputStream in, String saveUrl) throws IOException {
|
||||
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveUrl));
|
||||
byte[] buffer = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = in.read(buffer)) != -1) {
|
||||
bos.write(buffer, 0, len);
|
||||
}
|
||||
bos.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将图片以Base64方式编码为字符串
|
||||
*
|
||||
* @param imgUrl 图片的绝对路径(例如:D:\\1.jpg)
|
||||
* @return String 编码后的字符串
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String encodeImage(String imgUrl) throws IOException {
|
||||
FileInputStream fis = new FileInputStream(imgUrl);
|
||||
byte[] rs = new byte[fis.available()];
|
||||
fis.read(rs);
|
||||
fis.close();
|
||||
return encode(rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片返回bate[]
|
||||
*
|
||||
* @param imgUrl 图片的绝对路径(例如:D:\\1.jpg)
|
||||
* @return byte[]
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] byteImage(String imgUrl) throws IOException {
|
||||
byte[] rs;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(imgUrl);
|
||||
rs = new byte[fis.available()];
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
public static class ImageInfo {
|
||||
/**
|
||||
* 图片大小
|
||||
*/
|
||||
private long size = 0;
|
||||
/**
|
||||
* 图片宽度
|
||||
*/
|
||||
private int width = 0;
|
||||
/**
|
||||
* 图片高度
|
||||
*/
|
||||
private int height = 0;
|
||||
/**
|
||||
* 图片类型
|
||||
*/
|
||||
private String type = "jpg";
|
||||
/**
|
||||
* 符号要求的图片类型
|
||||
*/
|
||||
private String[] validTypes;
|
||||
|
||||
/**
|
||||
* 定义一个简单方法描述该图片是否符合要求
|
||||
*
|
||||
* @param validImg
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidImg(ImageInfo validImg) {
|
||||
if (null == validImg) {
|
||||
return true;
|
||||
}
|
||||
return (this.getSize() <= validImg.getSize()) && (this.getWidth() <= validImg.getWidth())
|
||||
&& (this.getHeight() <= validImg.getHeight()) && isValidType(validImg);
|
||||
|
||||
}
|
||||
|
||||
private boolean isValidType(ImageInfo validImg) {
|
||||
if (null == validImg.getValidTypes()) {
|
||||
return true;
|
||||
}
|
||||
boolean isValid = false;
|
||||
for (String validType : validImg.getValidTypes()) {
|
||||
if (type.equalsIgnoreCase(validType)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private String validTypeToString() {
|
||||
if (null == validTypes) {
|
||||
return "";
|
||||
}
|
||||
StringBuffer sb = new StringBuffer("[");
|
||||
for (String type : validTypes) {
|
||||
sb.append(type).append(" ");
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String[] getValidTypes() {
|
||||
return validTypes;
|
||||
}
|
||||
|
||||
public void setValidTypes(String[] validTypes) {
|
||||
this.validTypes = validTypes;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,11 +5,24 @@ import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.type.MapType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* json工具类,基于jackson
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName JsonUtil
|
||||
* @Description
|
||||
* @date 2018/9/3 15:28
|
||||
*/
|
||||
public class JsonUtil {
|
||||
private static Logger log = Logger.getLogger(JsonUtil.class.getName());
|
||||
|
||||
private JsonUtil() {
|
||||
}
|
||||
|
||||
@ -60,8 +73,11 @@ public class JsonUtil {
|
||||
try {
|
||||
pojo = objectMapper.readValue(json, cls);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + e.getMessage());
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + e.getMessage());
|
||||
}
|
||||
|
||||
return pojo;
|
||||
@ -80,19 +96,23 @@ public class JsonUtil {
|
||||
try {
|
||||
pojo = objectMapper.readValue(json, cls);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + e.getMessage());
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + e.getMessage());
|
||||
}
|
||||
|
||||
return pojo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Json字符串转换为Java对象
|
||||
*
|
||||
* @param json
|
||||
* @param parametrized
|
||||
* @param parameterClasses
|
||||
* @param json 字符串
|
||||
* @param parametrized 容器类
|
||||
* @param parameterClasses 实际类
|
||||
* @return
|
||||
*/
|
||||
public static <T> T json2Obj(String json, Class<T> parametrized, Class<?>... parameterClasses) {
|
||||
@ -102,8 +122,61 @@ public class JsonUtil {
|
||||
try {
|
||||
pojo = objectMapper.readValue(json, javaType);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + e.getMessage());
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + e.getMessage());
|
||||
}
|
||||
return pojo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Json字符串转换为Java-Map对象
|
||||
*
|
||||
* @param json 字符串
|
||||
* @param mapClass Map 继承类
|
||||
* @param keyClass Key 类
|
||||
* @param valueClass Value 类
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T json2Obj(String json, Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass) {
|
||||
T pojo = null;
|
||||
MapType mapType = objectMapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass);
|
||||
try {
|
||||
pojo = objectMapper.readValue(json, mapType);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + e.getMessage());
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + e.getMessage());
|
||||
}
|
||||
return pojo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Json字符串转换为Java-Map对象
|
||||
*
|
||||
* @param json 字符串
|
||||
* @param mapClass Map 继承类
|
||||
* @param keyType Key 类
|
||||
* @param valueType Value 类
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T json2Obj(String json, Class<? extends Map> mapClass, JavaType keyType, JavaType valueType) {
|
||||
T pojo = null;
|
||||
MapType mapType = objectMapper.getTypeFactory().constructMapType(mapClass, keyType, valueType);
|
||||
try {
|
||||
pojo = objectMapper.readValue(json, mapType);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + e.getMessage());
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + e.getMessage());
|
||||
}
|
||||
return pojo;
|
||||
}
|
||||
@ -111,9 +184,9 @@ public class JsonUtil {
|
||||
/**
|
||||
* Json字符串转换为Java对象
|
||||
*
|
||||
* @param json
|
||||
* @param parametrized
|
||||
* @param parameterClasses
|
||||
* @param json 字符串
|
||||
* @param parametrized 容器类
|
||||
* @param parameterClasses 实际类
|
||||
* @return
|
||||
*/
|
||||
public static <T> T json2Obj(InputStream json, Class<T> parametrized, Class<?>... parameterClasses) {
|
||||
@ -123,8 +196,11 @@ public class JsonUtil {
|
||||
try {
|
||||
pojo = objectMapper.readValue(json, javaType);
|
||||
} catch (JsonParseException e) {
|
||||
log.warning("json to Object JsonParseException.\n" + e.getMessage());
|
||||
} catch (JsonMappingException e) {
|
||||
log.warning("json to Object JsonMappingException.\n" + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warning("json to Object IOException.\n" + e.getMessage());
|
||||
}
|
||||
return pojo;
|
||||
}
|
||||
@ -140,6 +216,7 @@ public class JsonUtil {
|
||||
try {
|
||||
json = objectMapper.writeValueAsString(pojo);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warning("json to Object JsonProcessingException.\n" + e.getMessage());
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
@ -6,13 +6,61 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* jwt工具类
|
||||
* <p>
|
||||
* 升级2.0
|
||||
* <br/>
|
||||
* 由静态类分装成单例类,可配置参数config()
|
||||
* </p>
|
||||
*
|
||||
* @author maxf
|
||||
* @version 2.0
|
||||
* @ClassName JwtUtil
|
||||
* @Description
|
||||
* @date 2018/9/3 15:28
|
||||
*/
|
||||
public class JwtUtil {
|
||||
/** 加密用KEY */
|
||||
private static String JWT_SIGNATURE_KEY = "h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a";
|
||||
/** token类型 */
|
||||
private static String JWT_HEADER_TYP = "JWT";
|
||||
/** token发行商 */
|
||||
private static String JWT_CLAIMS_ISS = "yexuejc.com";
|
||||
|
||||
private JwtUtil() {
|
||||
}
|
||||
|
||||
public static JwtUtil instace() {
|
||||
return Instace.jwtUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数配置:设置一次即可,多次设置会覆盖之前的
|
||||
*
|
||||
* @param key 加密key 默认:h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a
|
||||
* @param type 加密类型:默认JWT
|
||||
* @param iss token发行商: 默认yexuejc.com
|
||||
* @return
|
||||
*/
|
||||
public static JwtUtil config(String key, String type, String iss) {
|
||||
JwtUtil jwtUtil = instace();
|
||||
jwtUtil.JWT_SIGNATURE_KEY = key;
|
||||
jwtUtil.JWT_HEADER_TYP = type;
|
||||
jwtUtil.JWT_CLAIMS_ISS = iss;
|
||||
return jwtUtil;
|
||||
}
|
||||
|
||||
public static class Instace {
|
||||
private static JwtUtil jwtUtil = new JwtUtil();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密用KEY
|
||||
*/
|
||||
private String JWT_SIGNATURE_KEY = "h%OG8Y3WgA5AN7&6Ke7I#C1XvneW0N8a";
|
||||
/**
|
||||
* token类型
|
||||
*/
|
||||
private String JWT_HEADER_TYP = "JWT";
|
||||
/**
|
||||
* token发行商
|
||||
*/
|
||||
private String JWT_CLAIMS_ISS = "yexuejc.com";
|
||||
|
||||
/**
|
||||
* 加密内容生成token
|
||||
@ -20,7 +68,7 @@ public class JwtUtil {
|
||||
* @param subjectObj
|
||||
* @return
|
||||
*/
|
||||
public static String compact(Object subjectObj) {
|
||||
public String compact(Object subjectObj) {
|
||||
String subject = null;
|
||||
if (subjectObj instanceof String) {
|
||||
subject = (String) subjectObj;
|
||||
@ -52,7 +100,7 @@ public class JwtUtil {
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
public static Map<?, ?> parse(String token) {
|
||||
public Map<?, ?> parse(String token) {
|
||||
return parse(token, Map.class);
|
||||
}
|
||||
|
||||
@ -63,7 +111,7 @@ public class JwtUtil {
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
public static <T> T parse(String token, Class<T> cls) {
|
||||
public <T> T parse(String token, Class<T> cls) {
|
||||
String subject = null;
|
||||
try {
|
||||
subject = Jwts.parser().setSigningKey(JWT_SIGNATURE_KEY).parseClaimsJws(token).getBody().getSubject();
|
||||
|
@ -3,8 +3,15 @@ package com.yexuejc.base.util;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* map相关工具
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName MapRemoveNullUtil
|
||||
* @Description
|
||||
* @date 2018/9/3 15:32
|
||||
*/
|
||||
public class MapRemoveNullUtil {
|
||||
private MapRemoveNullUtil() {
|
||||
}
|
||||
@ -28,10 +35,11 @@ public class MapRemoveNullUtil {
|
||||
* @return
|
||||
*/
|
||||
public static Map removeNullKey(Map map) {
|
||||
Set set = map.keySet();
|
||||
for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
|
||||
Object obj = (Object) iterator.next();
|
||||
remove(obj, iterator);
|
||||
for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
|
||||
Map.Entry item = (Map.Entry) it.next();
|
||||
if (StrUtil.isEmpty(item.getKey())) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@ -43,11 +51,11 @@ public class MapRemoveNullUtil {
|
||||
* @return
|
||||
*/
|
||||
public static Map removeNullValue(Map map) {
|
||||
Set set = map.keySet();
|
||||
for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
|
||||
Object obj = (Object) iterator.next();
|
||||
Object value = (Object) map.get(obj);
|
||||
remove(value, iterator);
|
||||
for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
|
||||
Map.Entry item = (Map.Entry) it.next();
|
||||
if (StrUtil.isEmpty(item.getValue())) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -4,15 +4,15 @@ import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* q钱相关工具类
|
||||
* 钱相关工具类
|
||||
*
|
||||
* @ClassName: MoneyUtils
|
||||
* @Description:
|
||||
* @author: maxf
|
||||
* @date: 2017年12月1日 下午5:33:57
|
||||
*/
|
||||
public class MoneyUtils {
|
||||
private MoneyUtils() {
|
||||
public class MoneyUtil {
|
||||
private MoneyUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -34,6 +34,25 @@ public class MoneyUtils {
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分转元
|
||||
*
|
||||
* @param num
|
||||
* @return String
|
||||
* @Title: formatPrice
|
||||
* @Description:分转元
|
||||
* @throw
|
||||
*/
|
||||
public static String toYuan(Long num) {
|
||||
if (num == null) {
|
||||
return "0.00";
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
BigDecimal bigDecimal = new BigDecimal(num).divide(new BigDecimal(100));
|
||||
String str = df.format(bigDecimal);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 元转分
|
||||
*
|
||||
@ -52,4 +71,23 @@ public class MoneyUtils {
|
||||
String str = df.format(bigDecimal);
|
||||
return Integer.parseInt(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 元转分
|
||||
*
|
||||
* @param num
|
||||
* @return int
|
||||
* @Title: formatPrice
|
||||
* @Description: 元转分
|
||||
* @throw
|
||||
*/
|
||||
public static Long toFen4Long(String num) {
|
||||
if (num == null) {
|
||||
return 0L;
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat("#0");
|
||||
BigDecimal bigDecimal = new BigDecimal(num).multiply(new BigDecimal(100));
|
||||
String str = df.format(bigDecimal);
|
||||
return Long.parseLong(str);
|
||||
}
|
||||
}
|
296
src/main/java/com/yexuejc/base/util/ObjUtil.java
Normal file
296
src/main/java/com/yexuejc/base/util/ObjUtil.java
Normal file
@ -0,0 +1,296 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 对象工具:对类的操作
|
||||
*
|
||||
* @author maxf
|
||||
* @version 1.0
|
||||
* @ClassName ObjUtil
|
||||
* @Description
|
||||
* @date 2018/12/28 15:54
|
||||
*/
|
||||
public class ObjUtil {
|
||||
private ObjUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>把对象按照{@link ToUeProperty}注解转换</p>
|
||||
* <i>字段值为空不输出</i>
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @return 转换后的值以Map返回
|
||||
*/
|
||||
public static Map<String, Object> getToUeMap(Object obj) {
|
||||
return getUnderlineMap(obj, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>把对象按照注解转换</p>
|
||||
* <i>字段值为空不输出</i>
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @return 转换后的值toJson以String返回
|
||||
*/
|
||||
public static String getToUeStr(Object obj) {
|
||||
return JsonUtil.obj2Json(getUnderlineMap(obj, true, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>把对象驼峰字段转换成下划线输出,支持继承和字段类型为对象</p>
|
||||
* <i>字段值为空不输出</i>
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @return 转换后的值以Map返回
|
||||
*/
|
||||
public static Map<String, Object> getUnderlineMap(Object obj) {
|
||||
return getUnderlineMap(obj, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>把对象驼峰字段转换成下划线输出,支持继承和字段类型为对象</p>
|
||||
* <i>字段值为空不输出</i>
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @return 转换后的值toJson以String返回
|
||||
*/
|
||||
public static String getUnderlineStr(Object obj) {
|
||||
return JsonUtil.obj2Json(getUnderlineMap(obj, true, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* 把对象字段按{@link ToUeProperty}注解规则转换输出,支持继承和字段类型为对象
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @param isAnnotationAll 是否全部依赖注解转换。全部依赖注解转换:true 只有字段上有注解的才转换,没有注解的默认不转换;false 有注解的依照注解转换,没有的全传下划线
|
||||
* @param putNull 是否映射null
|
||||
* @return 转换后的值toJson以String返回
|
||||
*/
|
||||
public static String getUnderlineStr(Object obj, boolean isAnnotationAll, boolean putNull) {
|
||||
return JsonUtil.obj2Json(getUnderlineMap(obj, isAnnotationAll, putNull));
|
||||
}
|
||||
|
||||
/**
|
||||
* 把对象字段按{@link ToUeProperty}注解规则转换成输出,支持继承和字段类型为对象
|
||||
* <p>主要功能:解决输出时驼峰-下划线的转换</p>
|
||||
*
|
||||
* @param obj 要转换的对象
|
||||
* @param isAnnotationAll 是否全部依赖注解转换。全部依赖注解转换:true 只有字段上有注解的才转换,没有注解的默认不转换;false 有注解的依照注解转换,没有的全传下划线
|
||||
* @param putNull 是否映射null
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> getUnderlineMap(Object obj, boolean isAnnotationAll, boolean putNull) {
|
||||
Class<?> bindClass = obj.getClass();
|
||||
Map<String, Object> objMap = new HashMap<>(0);
|
||||
/*
|
||||
* 得到类中的所有属性集合
|
||||
*/
|
||||
try {
|
||||
List<Field> fieldList = new ArrayList<>();
|
||||
//当父类为null的时候说明到达了最上层的父类(Object类).
|
||||
while (bindClass != null) {
|
||||
fieldList.addAll(Arrays.asList(bindClass.getDeclaredFields()));
|
||||
//得到父类,然后赋给自己
|
||||
bindClass = bindClass.getSuperclass();
|
||||
}
|
||||
for (Field f : fieldList) {
|
||||
//排除序列化
|
||||
if ("serialVersionUID".equals(f.getName())) {
|
||||
continue;
|
||||
}
|
||||
//设置些属性是可以访问的
|
||||
f.setAccessible(true);
|
||||
String fName = f.getName();
|
||||
if (!isAnnotationAll) {
|
||||
fName = StrUtil.camelToUnderline(f.getName());
|
||||
}
|
||||
boolean annotationPresent = f.isAnnotationPresent(ToUeProperty.class);
|
||||
if (annotationPresent) {
|
||||
ToUeProperty annotation = f.getAnnotation(ToUeProperty.class);
|
||||
String value = annotation.value();
|
||||
if (StrUtil.isNotEmpty(value)) {
|
||||
fName = value;
|
||||
}
|
||||
}
|
||||
Object o = f.get(obj);
|
||||
if (null == o || o.getClass().isPrimitive() || o instanceof String || o instanceof Enum) {
|
||||
if (null == o && !putNull) {
|
||||
continue;
|
||||
}
|
||||
objMap.put(fName, f.get(obj));
|
||||
} else if (o instanceof List) {
|
||||
List list = (List) o;
|
||||
List bodyList = new ArrayList();
|
||||
list.forEach(it -> {
|
||||
if (null != it) {
|
||||
Map<String, Object> underlineMap = getUnderlineMap(it, isAnnotationAll, putNull);
|
||||
bodyList.add(underlineMap);
|
||||
}
|
||||
});
|
||||
if (bodyList.size() > 0) {
|
||||
objMap.put(fName, bodyList);
|
||||
}
|
||||
} else {
|
||||
Map<String, Object> underlineMap = getUnderlineMap(o, isAnnotationAll, putNull);
|
||||
objMap.put(fName, underlineMap);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return objMap;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
B a = new B();
|
||||
a.nameFirst = "张三";
|
||||
a.ageInt = "5165458";
|
||||
a.testAss = "asdasdsad";
|
||||
a.setaM1("method1");
|
||||
a.setbM1("b1Mthod1");
|
||||
a.protectedStr = "protectedStr";
|
||||
C c = new C();
|
||||
c.ageInt = "test";
|
||||
a.c = c;
|
||||
a.list = new ArrayList<>();
|
||||
a.list.add(c);
|
||||
Map<String, Object> underlineMap = getUnderlineMap(a, false, false);
|
||||
System.out.println(JsonUtil.obj2Json(underlineMap));
|
||||
}
|
||||
|
||||
static class A implements Serializable {
|
||||
private static final long serialVersionUID = -8462118058721865488L;
|
||||
public String nameFirst;
|
||||
public String ageInt;
|
||||
private String aM1;
|
||||
@ToUeProperty("p_str")
|
||||
protected String protectedStr;
|
||||
|
||||
public String getaM1() {
|
||||
return aM1;
|
||||
}
|
||||
|
||||
public A setaM1(String aM1) {
|
||||
this.aM1 = aM1;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
static class B extends A {
|
||||
private static final long serialVersionUID = -8462118058721865488L;
|
||||
public String testAss;
|
||||
private String bM1;
|
||||
private C c;
|
||||
List<C> list;
|
||||
|
||||
public String getbM1() {
|
||||
return bM1;
|
||||
}
|
||||
|
||||
public B setbM1(String bM1) {
|
||||
this.bM1 = bM1;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
static class C extends A {
|
||||
private static final long serialVersionUID = -8462118058721865488L;
|
||||
public String testAss;
|
||||
private String bM1;
|
||||
|
||||
public String getbM1() {
|
||||
return bM1;
|
||||
}
|
||||
|
||||
public C setbM1(String bM1) {
|
||||
this.bM1 = bM1;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <h2>深度克隆对象</h2>
|
||||
* <p>
|
||||
* 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
|
||||
* </p>
|
||||
* <i>注:克隆对象必须序列化</i>
|
||||
*
|
||||
* @param t
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T depthClone(T t) {
|
||||
T outer = null;
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(t);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
outer = (T) ois.readObject();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return outer;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//// test1();
|
||||
//// test2();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private static void test2() {
|
||||
// B t = new B();
|
||||
// t.sex = "男";
|
||||
// t.age = 18;
|
||||
// A test = new A();
|
||||
// test.name = "张三";
|
||||
// t.test = test;
|
||||
// B b = depthClone(t);
|
||||
// System.out.println(JsonUtil.obj2Json(b));
|
||||
// }
|
||||
//
|
||||
// static class A implements Serializable {
|
||||
// private static final long serialVersionUID = -8462118058721865488L;
|
||||
// public String name;
|
||||
// }
|
||||
//
|
||||
// static class B implements Serializable {
|
||||
// private static final long serialVersionUID = 3297717505428005316L;
|
||||
// public int age;
|
||||
// public String sex;
|
||||
// public A test;
|
||||
// }
|
||||
//
|
||||
// static class C implements Serializable {
|
||||
// private static final long serialVersionUID = 3297717505428005316L;
|
||||
// public int age;
|
||||
// public String sex;
|
||||
// public A test;
|
||||
// }
|
||||
//
|
||||
// private static void test1() {
|
||||
// ApiVO apiVO = new ApiVO(ApiVO.STATUS.S);
|
||||
// apiVO.setMsg("asdsadsad");
|
||||
// apiVO.setObject1("sadsadsad");
|
||||
//
|
||||
// Resps<String> obj = new Resps<>();
|
||||
// obj.setSucc("安达圣斗士", "ok");
|
||||
// System.out.println(obj);
|
||||
// apiVO.setObject2(obj);
|
||||
// ApiVO apiVO1 = depthClone(apiVO);
|
||||
// System.out.println(apiVO == apiVO1);
|
||||
// System.out.println(JsonUtil.obj2Json(apiVO1));
|
||||
// System.out.println(JsonUtil.obj2Json(apiVO1.getObject1(String.class)));
|
||||
// System.out.println(JsonUtil.obj2Json(apiVO1.getObject2(Resps.class)));
|
||||
// System.out.println(apiVO1.getObject2(Resps.class) == obj);
|
||||
// }
|
||||
}
|
@ -10,8 +10,8 @@ import java.util.regex.Pattern;
|
||||
* @expl
|
||||
* @time 2017年11月9日 上午11:01:24
|
||||
*/
|
||||
public class RegexUtils {
|
||||
private RegexUtils() {
|
||||
public class RegexUtil {
|
||||
private RegexUtil() {
|
||||
}
|
||||
|
||||
/**
|
@ -16,6 +16,9 @@ import java.util.regex.Pattern;
|
||||
* @date: 2018/5/12 19:13
|
||||
*/
|
||||
public final class StrUtil {
|
||||
private StrUtil() {
|
||||
}
|
||||
|
||||
public static char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
/**
|
||||
@ -123,7 +126,7 @@ public final class StrUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
Map<String, String> map = new HashMap<String, String>(16);
|
||||
String[] kv = null;
|
||||
for (String entry : entrys) {
|
||||
if (isEmpty(entry)) {
|
||||
@ -148,7 +151,7 @@ public final class StrUtil {
|
||||
* @param buf 初始字节数组
|
||||
* @return 转换后字符串
|
||||
*/
|
||||
public static String toHex(byte buf[]) {
|
||||
public static String toHex(byte[] buf) {
|
||||
StringBuffer strbuf = new StringBuffer(buf.length * 2);
|
||||
int i;
|
||||
for (i = 0; i < buf.length; i++) {
|
||||
@ -178,7 +181,7 @@ public final class StrUtil {
|
||||
return null;
|
||||
}
|
||||
md.update(str.getBytes());
|
||||
byte tmp[] = md.digest();
|
||||
byte[] tmp = md.digest();
|
||||
return toHex(tmp);
|
||||
}
|
||||
|
||||
@ -212,7 +215,7 @@ public final class StrUtil {
|
||||
return null;
|
||||
}
|
||||
messageDigest.update(str.getBytes());
|
||||
byte tmp[] = messageDigest.digest();
|
||||
byte[] tmp = messageDigest.digest();
|
||||
return toHex(tmp);
|
||||
}
|
||||
|
||||
@ -238,8 +241,9 @@ public final class StrUtil {
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
private static Pattern pattern = Pattern.compile("[0-9]*");
|
||||
|
||||
public static boolean isNumeric(String str) {
|
||||
Pattern pattern = Pattern.compile("[0-9]*");
|
||||
Matcher isNum = pattern.matcher(str);
|
||||
if (!isNum.matches()) {
|
||||
return false;
|
||||
@ -259,16 +263,17 @@ public final class StrUtil {
|
||||
}
|
||||
|
||||
StringBuilder coded = new StringBuilder();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 13; i++) {
|
||||
coded.append(HEX_CHAR[(int) (Math.random() * 15L) + 1]);
|
||||
coded.append(HEX_CHAR[random.nextInt(16)]);
|
||||
}
|
||||
coded.append(id.substring(0, 11));
|
||||
for (int i = 0; i < 7; i++) {
|
||||
coded.append(HEX_CHAR[(int) (Math.random() * 15L) + 1]);
|
||||
coded.append(HEX_CHAR[random.nextInt(16)]);
|
||||
}
|
||||
coded.append(id.substring(11));
|
||||
for (int i = 0; i < 12; i++) {
|
||||
coded.append(HEX_CHAR[(int) (Math.random() * 15L) + 1]);
|
||||
coded.append(HEX_CHAR[random.nextInt(16)]);
|
||||
}
|
||||
|
||||
return coded.toString();
|
||||
@ -335,7 +340,7 @@ public final class StrUtil {
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> mapSort(Map<String, ?> sortedParams) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
List<String> keys = new ArrayList<>(sortedParams.keySet());
|
||||
Collections.sort(keys);
|
||||
int index = 0;
|
||||
@ -361,4 +366,57 @@ public final class StrUtil {
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下划线字符
|
||||
*/
|
||||
public static final char UNDERLINE = '_';
|
||||
|
||||
/**
|
||||
* 字符串下划线转驼峰格式
|
||||
*
|
||||
* @param param 需要转换的字符串
|
||||
* @return 转换好的字符串
|
||||
*/
|
||||
public static String underlineToCamel(String param) {
|
||||
if (isEmpty(param)) {
|
||||
return "";
|
||||
}
|
||||
String temp = param.toLowerCase();
|
||||
int len = temp.length();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = temp.charAt(i);
|
||||
if (c == UNDERLINE) {
|
||||
if (++i < len) {
|
||||
sb.append(Character.toUpperCase(temp.charAt(i)));
|
||||
}
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串驼峰转下划线格式
|
||||
*
|
||||
* @param param 需要转换的字符串
|
||||
* @return 转换好的字符串
|
||||
*/
|
||||
public static String camelToUnderline(String param) {
|
||||
if (isEmpty(param)) {
|
||||
return "";
|
||||
}
|
||||
int len = param.length();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = param.charAt(i);
|
||||
if (Character.isUpperCase(c) && i > 0) {
|
||||
sb.append(UNDERLINE);
|
||||
}
|
||||
sb.append(Character.toLowerCase(c));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
82
src/main/java/com/yexuejc/base/util/SysUtil.java
Normal file
82
src/main/java/com/yexuejc/base/util/SysUtil.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 系统工具类
|
||||
*
|
||||
* @PackageName: com.yexuejc.util.base
|
||||
* @Description:
|
||||
* @author: maxf
|
||||
* @date: 2017/12/28 16:12
|
||||
*/
|
||||
public class SysUtil {
|
||||
private static final String PROJECT_ROOT_PATH = "java.io.tmpdir";
|
||||
|
||||
private SysUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取临时缓存路径
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getCachePath() {
|
||||
return System.getProperty(PROJECT_ROOT_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从根路径获取文件URL
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static URL getRootPath(Class clazz, String filePath) {
|
||||
return clazz.getClass().getResource(StrUtil.setStr(filePath, "/"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启线程执行<p>
|
||||
* 异步处理代码
|
||||
*
|
||||
* @param threadRun
|
||||
*/
|
||||
public static void threadRun(ThreadRun threadRun) {
|
||||
threadRun(null, threadRun);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步处理代码
|
||||
*
|
||||
* @param poolName 开启线程名称
|
||||
* @param threadRun
|
||||
*/
|
||||
public static void threadRun(String poolName, ThreadRun threadRun) {
|
||||
if (StrUtil.isEmpty(poolName)) {
|
||||
poolName = "java-pool-%d";
|
||||
}
|
||||
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
|
||||
.setNameFormat(poolName).build();
|
||||
ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
|
||||
0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
|
||||
|
||||
singleThreadPool.execute(() -> {
|
||||
threadRun.execute();
|
||||
});
|
||||
singleThreadPool.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行接口
|
||||
*/
|
||||
public interface ThreadRun {
|
||||
/**
|
||||
* 执行代码块
|
||||
*/
|
||||
void execute();
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* 系统工具类
|
||||
*
|
||||
* @PackageName: com.yexuejc.util.base
|
||||
* @Description:
|
||||
* @author: maxf
|
||||
* @date: 2017/12/28 16:12
|
||||
*/
|
||||
public class SysUtils {
|
||||
private static final String PROJECT_ROOT_PATH = "java.io.tmpdir";
|
||||
|
||||
private SysUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取临时缓存路径
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getCachePath() {
|
||||
return System.getProperty(PROJECT_ROOT_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从根路径获取文件URL
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static URL getRootPath(Class clazz, String filePath) {
|
||||
return clazz.getClass().getResource(StrUtil.setStr(filePath, "/"));
|
||||
}
|
||||
|
||||
}
|
103
src/main/java/com/yexuejc/base/util/ThreeDES.java
Normal file
103
src/main/java/com/yexuejc/base/util/ThreeDES.java
Normal file
@ -0,0 +1,103 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESedeKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
|
||||
|
||||
/**
|
||||
* 3DES加解密
|
||||
*
|
||||
* @author maxf
|
||||
* @ClassName ThreeDES
|
||||
* @Description
|
||||
* @date 2018/9/3 17:09
|
||||
*/
|
||||
public class ThreeDES {
|
||||
private ThreeDES() {
|
||||
}
|
||||
|
||||
public static String IV = "1234567-";
|
||||
public static String ENCODING = "utf-8";
|
||||
|
||||
/**
|
||||
* DESCBC加密
|
||||
*
|
||||
* @param src 数据源
|
||||
* @param key 密钥
|
||||
* @return 返回加密后的数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encryptDESCBC(final String src, final String key) throws Exception {
|
||||
if (key.length() < 24) {
|
||||
throw new InvalidKeyException("key的length不得小于24");
|
||||
}
|
||||
Key deskey = null;
|
||||
DESedeKeySpec spec = new DESedeKeySpec(key.getBytes());
|
||||
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
|
||||
deskey = keyfactory.generateSecret(spec);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
|
||||
IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
|
||||
byte[] encryptData = cipher.doFinal(src.getBytes(ENCODING));
|
||||
return Base64.encodeBase64URLSafeString(encryptData);
|
||||
}
|
||||
|
||||
/**
|
||||
* DESCBC解密
|
||||
*
|
||||
* @param src 数据源
|
||||
* @param key 密钥
|
||||
* @return 返回解密后的原始数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String decryptDESCBC(final String src, final String key) throws Exception {
|
||||
if (key.length() < 24) {
|
||||
throw new InvalidKeyException("key的length不得小于24");
|
||||
}
|
||||
Key deskey = null;
|
||||
DESedeKeySpec spec = new DESedeKeySpec(key.getBytes());
|
||||
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
|
||||
deskey = keyfactory.generateSecret(spec);
|
||||
Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
|
||||
IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
|
||||
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
|
||||
|
||||
byte[] decryptData = cipher.doFinal(Base64.decodeBase64(src));
|
||||
|
||||
return new String(decryptData, ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充,不是8的倍数会填充成8的倍数
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String padding(String str) {
|
||||
byte[] oldByteArray;
|
||||
try {
|
||||
oldByteArray = str.getBytes("UTF8");
|
||||
int numberToPad = 8 - oldByteArray.length % 8;
|
||||
byte[] newByteArray = new byte[oldByteArray.length + numberToPad];
|
||||
System.arraycopy(oldByteArray, 0, newByteArray, 0,
|
||||
oldByteArray.length);
|
||||
for (int i = oldByteArray.length; i < newByteArray.length; ++i) {
|
||||
newByteArray[i] = 0;
|
||||
}
|
||||
return new String(newByteArray, "UTF8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
System.out.println("Crypter.padding UnsupportedEncodingException");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
14
src/main/java/com/yexuejc/base/util/ToUeProperty.java
Normal file
14
src/main/java/com/yexuejc/base/util/ToUeProperty.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.yexuejc.base.util;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ToUeProperty {
|
||||
/**
|
||||
* 字段名,默认该字段转下划线
|
||||
* @return
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user