first commit
This commit is contained in:
70
fuint-utils/pom.xml
Normal file
70
fuint-utils/pom.xml
Normal file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>fuint</artifactId>
|
||||
<groupId>com.fuint</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>fuint-utils</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.58</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<!-- poi begin -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.14</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.14</version>
|
||||
</dependency>
|
||||
<!-- poi end -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,70 @@
|
||||
package com.fuint.exception;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* 关于异常的工具类.
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class Exceptions {
|
||||
|
||||
/**
|
||||
* 将CheckedException转换为UncheckedException.
|
||||
*/
|
||||
public static RuntimeException unchecked(Throwable ex) {
|
||||
if (ex instanceof RuntimeException) {
|
||||
return (RuntimeException) ex;
|
||||
} else {
|
||||
return new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将ErrorStack转化为String.
|
||||
*/
|
||||
public static String getStackTraceAsString(Throwable ex) {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
ex.printStackTrace(new PrintWriter(stringWriter));
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组合本异常信息与底层异常信息的异常描述, 适用于本异常为统一包装异常类,底层异常才是根本原因的情况。
|
||||
*/
|
||||
public static String getErrorMessageWithNestedException(Throwable ex) {
|
||||
Throwable nestedException = ex.getCause();
|
||||
return new StringBuilder().append(ex.getMessage()).append(" nested exception is ")
|
||||
.append(nestedException.getClass().getName()).append(":")
|
||||
.append(nestedException.getMessage()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取异常的Root Cause.
|
||||
*/
|
||||
public static Throwable getRootCause(Throwable ex) {
|
||||
Throwable cause;
|
||||
while ((cause = ex.getCause()) != null) {
|
||||
ex = cause;
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断异常是否由某些底层的异常引起.
|
||||
*/
|
||||
public static boolean isCausedBy(Exception ex, Class<? extends Exception>... causeExceptionClasses) {
|
||||
Throwable cause = ex;
|
||||
while (cause != null) {
|
||||
for (Class<? extends Exception> causeClass : causeExceptionClasses) {
|
||||
if (causeClass.isInstance(cause)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
cause = cause.getCause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
87
fuint-utils/src/main/java/com/fuint/text/CharsetKit.java
Normal file
87
fuint-utils/src/main/java/com/fuint/text/CharsetKit.java
Normal file
@ -0,0 +1,87 @@
|
||||
package com.fuint.text;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 字符集工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class CharsetKit {
|
||||
/** ISO-8859-1 */
|
||||
public static final String ISO_8859_1 = "ISO-8859-1";
|
||||
/** UTF-8 */
|
||||
public static final String UTF_8 = "UTF-8";
|
||||
/** GBK */
|
||||
public static final String GBK = "GBK";
|
||||
|
||||
/** ISO-8859-1 */
|
||||
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
|
||||
/** UTF-8 */
|
||||
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
|
||||
/** GBK */
|
||||
public static final Charset CHARSET_GBK = Charset.forName(GBK);
|
||||
|
||||
/**
|
||||
* 转换为Charset对象
|
||||
*
|
||||
* @param charset 字符集,为空则返回默认字符集
|
||||
* @return Charset
|
||||
*/
|
||||
public static Charset charset(String charset)
|
||||
{
|
||||
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, String srcCharset, String destCharset)
|
||||
{
|
||||
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, Charset srcCharset, Charset destCharset)
|
||||
{
|
||||
if (null == srcCharset)
|
||||
{
|
||||
srcCharset = StandardCharsets.ISO_8859_1;
|
||||
}
|
||||
|
||||
if (null == destCharset)
|
||||
{
|
||||
destCharset = StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
return new String(source.getBytes(srcCharset), destCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 系统字符集编码
|
||||
*/
|
||||
public static String systemCharset()
|
||||
{
|
||||
return Charset.defaultCharset().name();
|
||||
}
|
||||
}
|
||||
1007
fuint-utils/src/main/java/com/fuint/text/Convert.java
Normal file
1007
fuint-utils/src/main/java/com/fuint/text/Convert.java
Normal file
File diff suppressed because it is too large
Load Diff
93
fuint-utils/src/main/java/com/fuint/text/StrFormatter.java
Normal file
93
fuint-utils/src/main/java/com/fuint/text/StrFormatter.java
Normal file
@ -0,0 +1,93 @@
|
||||
package com.fuint.text;
|
||||
|
||||
import com.fuint.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* 字符串格式化
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class StrFormatter {
|
||||
|
||||
public static final String EMPTY_JSON = "{}";
|
||||
public static final char C_BACKSLASH = '\\';
|
||||
public static final char C_DELIM_START = '{';
|
||||
public static final char C_DELIM_END = '}';
|
||||
|
||||
/**
|
||||
* 格式化字符串<br>
|
||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||
*
|
||||
* @param strPattern 字符串模板
|
||||
* @param argArray 参数列表
|
||||
* @return 结果
|
||||
*/
|
||||
public static String format(final String strPattern, final Object... argArray)
|
||||
{
|
||||
if (StringUtil.isEmpty(strPattern) || argArray == null)
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
final int strPatternLength = strPattern.length();
|
||||
|
||||
// 初始化定义好的长度以获得更好的性能
|
||||
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
|
||||
|
||||
int handledPosition = 0;
|
||||
int delimIndex;// 占位符所在位置
|
||||
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
|
||||
{
|
||||
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
|
||||
if (delimIndex == -1)
|
||||
{
|
||||
if (handledPosition == 0)
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
else
|
||||
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
|
||||
sbuf.append(strPattern, handledPosition, strPatternLength);
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
|
||||
{
|
||||
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
|
||||
{
|
||||
// 转义符之前还有一个转义符,占位符依旧有效
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 占位符被转义
|
||||
argIndex--;
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(C_DELIM_START);
|
||||
handledPosition = delimIndex + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常占位符
|
||||
sbuf.append(strPattern, handledPosition, delimIndex);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 加入最后一个占位符后所有的字符
|
||||
sbuf.append(strPattern, handledPosition, strPattern.length());
|
||||
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
99
fuint-utils/src/main/java/com/fuint/utils/AES.java
Normal file
99
fuint-utils/src/main/java/com/fuint/utils/AES.java
Normal file
@ -0,0 +1,99 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 加密算法
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class AES {
|
||||
// 算法名称
|
||||
final String KEY_ALGORITHM = "AES";
|
||||
// 加解密算法/模式/填充方式
|
||||
final String algorithmStr = "AES/CBC/PKCS7Padding";
|
||||
private Key key;
|
||||
private Cipher cipher;
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
final byte[] iv = {0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38};
|
||||
|
||||
public void init(byte[] keyBytes) {
|
||||
|
||||
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
|
||||
int base = 16;
|
||||
if (keyBytes.length % base != 0) {
|
||||
int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
|
||||
byte[] temp = new byte[groups * base];
|
||||
Arrays.fill(temp, (byte) 0);
|
||||
System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
|
||||
keyBytes = temp;
|
||||
}
|
||||
// 初始化
|
||||
// 转化成JAVA的密钥格式
|
||||
key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
|
||||
try {
|
||||
// 初始化cipher
|
||||
cipher = Cipher.getInstance(algorithmStr, "BC");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchProviderException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
*
|
||||
* @param content 要加密的字符串
|
||||
* @param keyBytes 加密密钥
|
||||
* @return
|
||||
*/
|
||||
public byte[] encrypt(byte[] content, byte[] keyBytes) {
|
||||
byte[] encryptedText = null;
|
||||
init(keyBytes);
|
||||
System.out.println("IV:" + new String(iv));
|
||||
try {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
encryptedText = cipher.doFinal(content);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return encryptedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
*
|
||||
* @param encryptedData 要解密的字符串
|
||||
* @param keyBytes 解密密钥
|
||||
* @return
|
||||
*/
|
||||
public byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
|
||||
byte[] encryptedText = null;
|
||||
init(keyBytes);
|
||||
System.out.println("IV:" + new String(iv));
|
||||
try {
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
encryptedText = cipher.doFinal(encryptedData);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return encryptedText;
|
||||
}
|
||||
}
|
||||
5546
fuint-utils/src/main/java/com/fuint/utils/ArrayUtil.java
Normal file
5546
fuint-utils/src/main/java/com/fuint/utils/ArrayUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
175
fuint-utils/src/main/java/com/fuint/utils/Base64Util.java
Normal file
175
fuint-utils/src/main/java/com/fuint/utils/Base64Util.java
Normal file
@ -0,0 +1,175 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* 基于Java8的Base64工具类实现,不依赖第三方包
|
||||
* [Basic编码:适用于标准编码]
|
||||
* [URL编码:适用于URL地址编码,自动替换掉URL中不能出现的"/"等字符]
|
||||
* [MIME编码:适用于MIME编码,使用基本的字母数字产生BASE64输出,每一行输出不超过76个字符,而且每行以“\r\n”符结束]
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class Base64Util {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Base64Util.class);
|
||||
|
||||
private static final String CHARSET = "UTF-8";//默认字符集
|
||||
|
||||
/**
|
||||
* 基本Base64编码
|
||||
* @param bytes
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] baseEncode(byte[] bytes) {
|
||||
return java.util.Base64.getEncoder().encode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基本Base64编码
|
||||
*
|
||||
* @param s
|
||||
* @return String
|
||||
*/
|
||||
public static String baseEncode(String s) {
|
||||
try {
|
||||
byte[] bytes = s.getBytes(CHARSET);
|
||||
return java.util.Base64.getEncoder().encodeToString(bytes);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基本Base64解码
|
||||
*
|
||||
* @param bytes
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] baseDecode(byte[] bytes) {
|
||||
return java.util.Base64.getDecoder().decode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基本Base64解码
|
||||
*
|
||||
* @param s
|
||||
* @return String
|
||||
*/
|
||||
public static String baseDecode(String s) {
|
||||
try {
|
||||
byte[] result = java.util.Base64.getDecoder().decode(s);
|
||||
return new String(result, CHARSET);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL编码
|
||||
*
|
||||
* @param bytes
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] urlEncode(byte[] bytes) {
|
||||
return java.util.Base64.getUrlEncoder().encode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL编码
|
||||
*
|
||||
* @param s
|
||||
* @return String
|
||||
*/
|
||||
public static String urlEncode(String s) {
|
||||
try {
|
||||
byte[] bytes = s.getBytes(CHARSET);
|
||||
return java.util.Base64.getUrlEncoder().encodeToString(bytes);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL解码
|
||||
*
|
||||
* @param bytes
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] urlDecode(byte[] bytes) {
|
||||
return java.util.Base64.getUrlDecoder().decode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL解码
|
||||
*
|
||||
* @param s
|
||||
* @return String
|
||||
*/
|
||||
public static String urlDecode(String s) {
|
||||
byte[] result = java.util.Base64.getUrlDecoder().decode(s);
|
||||
try {
|
||||
return new String(result, CHARSET);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME编码
|
||||
*
|
||||
* @param bytes
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] mimeEncode(byte[] bytes) {
|
||||
return java.util.Base64.getMimeEncoder().encode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME编码
|
||||
*
|
||||
* @param s
|
||||
* @return String
|
||||
*/
|
||||
public static String mimeEncode(String s) {
|
||||
try {
|
||||
byte[] bytes = s.getBytes(CHARSET);
|
||||
return java.util.Base64.getMimeEncoder().encodeToString(bytes);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME解码
|
||||
*
|
||||
* @param bytes
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] mimeDecode(byte[] bytes) {
|
||||
return java.util.Base64.getMimeDecoder().decode(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* MIME解码
|
||||
*
|
||||
* @param s
|
||||
* @return String
|
||||
*/
|
||||
public static String mimeDecode(String s) {
|
||||
try {
|
||||
byte[] result = java.util.Base64.getMimeDecoder().decode(s);
|
||||
return new String(result, CHARSET);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
fuint-utils/src/main/java/com/fuint/utils/BeanToMapUtil.java
Normal file
83
fuint-utils/src/main/java/com/fuint/utils/BeanToMapUtil.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class BeanToMapUtil {
|
||||
/**
|
||||
* 将一个 Map 对象转化为一个 JavaBean
|
||||
*
|
||||
* @param type 要转化的类型
|
||||
* @param map 包含属性值的 map
|
||||
* @return 转化出来的 JavaBean 对象
|
||||
* @throws IntrospectionException 如果分析类属性失败
|
||||
* @throws IllegalAccessException 如果实例化 JavaBean 失败
|
||||
* @throws InstantiationException 如果实例化 JavaBean 失败
|
||||
* @throws InvocationTargetException 如果调用属性的 setter 方法失败
|
||||
*/
|
||||
public static Object convertMap(Class type, Map map)
|
||||
throws IntrospectionException, IllegalAccessException,
|
||||
InstantiationException, InvocationTargetException {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
|
||||
Object obj = type.newInstance(); // 创建 JavaBean 对象
|
||||
|
||||
// 给 JavaBean 对象的属性赋值
|
||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
||||
for (int i = 0; i < propertyDescriptors.length; i++) {
|
||||
PropertyDescriptor descriptor = propertyDescriptors[i];
|
||||
String propertyName = descriptor.getName();
|
||||
|
||||
if (map.containsKey(propertyName)) {
|
||||
// 下面一句可以 try 起来,这样当一个属性赋值失败的时候就不会影响其他属性赋值。
|
||||
Object value = map.get(propertyName);
|
||||
|
||||
Object[] args = new Object[1];
|
||||
args[0] = value;
|
||||
|
||||
descriptor.getWriteMethod().invoke(obj, args);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个 JavaBean 对象转化为一个 Map
|
||||
*
|
||||
* @param bean 要转化的JavaBean 对象
|
||||
* @return 转化出来的 Map 对象
|
||||
* @throws IntrospectionException 如果分析类属性失败
|
||||
* @throws IllegalAccessException 如果实例化 JavaBean 失败
|
||||
* @throws InvocationTargetException 如果调用属性的 setter 方法失败
|
||||
*/
|
||||
public static Map convertBean(Object bean) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
|
||||
Class type = bean.getClass();
|
||||
Map returnMap = new HashMap();
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(type);
|
||||
|
||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
||||
for (int i = 0; i < propertyDescriptors.length; i++) {
|
||||
PropertyDescriptor descriptor = propertyDescriptors[i];
|
||||
String propertyName = descriptor.getName();
|
||||
if (!propertyName.equals("class")) {
|
||||
Method readMethod = descriptor.getReadMethod();
|
||||
Object result = readMethod.invoke(bean, new Object[0]);
|
||||
if (result != null) {
|
||||
returnMap.put(propertyName, result);
|
||||
} else {
|
||||
returnMap.put(propertyName, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
}
|
||||
1250
fuint-utils/src/main/java/com/fuint/utils/ClassUtil.java
Normal file
1250
fuint-utils/src/main/java/com/fuint/utils/ClassUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
28
fuint-utils/src/main/java/com/fuint/utils/CommonUtil.java
Normal file
28
fuint-utils/src/main/java/com/fuint/utils/CommonUtil.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class CommonUtil {
|
||||
|
||||
/**
|
||||
* 格式化指定的日期
|
||||
*
|
||||
* @param date
|
||||
* @param formatStr
|
||||
* @return
|
||||
*/
|
||||
public static String formatDate(Date date, String formatStr) {
|
||||
if (date == null) date = new Date();
|
||||
if (StringUtils.isEmpty(formatStr)) formatStr = "yyyy-MM-dd";
|
||||
SimpleDateFormat dateFormater = new SimpleDateFormat(formatStr);
|
||||
return dateFormater.format(date);
|
||||
}
|
||||
}
|
||||
42
fuint-utils/src/main/java/com/fuint/utils/ContextUtils.java
Normal file
42
fuint-utils/src/main/java/com/fuint/utils/ContextUtils.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Context 工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
@Component
|
||||
public class ContextUtils implements ApplicationContextAware {
|
||||
public static ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
ContextUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public static Object getBean(String name) {
|
||||
return applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> requiredType) {
|
||||
return applicationContext.getBean(name, requiredType);
|
||||
}
|
||||
|
||||
public static boolean containsBean(String name) {
|
||||
return applicationContext.containsBean(name);
|
||||
}
|
||||
|
||||
public static boolean isSingleton(String name) {
|
||||
return applicationContext.isSingleton(name);
|
||||
}
|
||||
|
||||
public static Class<? extends Object> getType(String name) {
|
||||
return applicationContext.getType(name);
|
||||
}
|
||||
}
|
||||
110
fuint-utils/src/main/java/com/fuint/utils/Digests.java
Normal file
110
fuint-utils/src/main/java/com/fuint/utils/Digests.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import com.fuint.exception.Exceptions;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* 支持SHA-1/MD5消息摘要的工具类.
|
||||
*
|
||||
* 返回ByteSource,可进一步被编码为Hex, Base64或UrlSafeBase64
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class Digests {
|
||||
|
||||
private static final String SHA1 = "SHA-1";
|
||||
private static final String MD5 = "MD5";
|
||||
|
||||
private static SecureRandom random = new SecureRandom();
|
||||
|
||||
/**
|
||||
* 对输入字符串进行sha1散列.
|
||||
*/
|
||||
public static byte[] sha1(byte[] input) {
|
||||
return digest(input, SHA1, null, 1);
|
||||
}
|
||||
|
||||
public static byte[] sha1(byte[] input, byte[] salt) {
|
||||
return digest(input, SHA1, salt, 1);
|
||||
}
|
||||
|
||||
public static byte[] sha1(byte[] input, byte[] salt, int iterations) {
|
||||
return digest(input, SHA1, salt, iterations);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串进行散列, 支持md5与sha1算法.
|
||||
*/
|
||||
private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance(algorithm);
|
||||
|
||||
if (salt != null) {
|
||||
digest.update(salt);
|
||||
}
|
||||
|
||||
byte[] result = digest.digest(input);
|
||||
|
||||
for (int i = 1; i < iterations; i++) {
|
||||
digest.reset();
|
||||
result = digest.digest(result);
|
||||
}
|
||||
return result;
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机的Byte[]作为salt.
|
||||
*
|
||||
* @param numBytes byte数组的大小
|
||||
*/
|
||||
public static byte[] generateSalt(int numBytes) {
|
||||
Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)",
|
||||
numBytes);
|
||||
|
||||
byte[] bytes = new byte[numBytes];
|
||||
random.nextBytes(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对文件进行md5散列.
|
||||
*/
|
||||
public static byte[] md5(InputStream input) throws IOException {
|
||||
return digest(input, MD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对文件进行sha1散列.
|
||||
*/
|
||||
public static byte[] sha1(InputStream input) throws IOException {
|
||||
return digest(input, SHA1);
|
||||
}
|
||||
|
||||
private static byte[] digest(InputStream input, String algorithm) throws IOException {
|
||||
try {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
|
||||
int bufferLength = 8 * 1024;
|
||||
byte[] buffer = new byte[bufferLength];
|
||||
int read = input.read(buffer, 0, bufferLength);
|
||||
|
||||
while (read > -1) {
|
||||
messageDigest.update(buffer, 0, read);
|
||||
read = input.read(buffer, 0, bufferLength);
|
||||
}
|
||||
|
||||
return messageDigest.digest();
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
125
fuint-utils/src/main/java/com/fuint/utils/Encodes.java
Normal file
125
fuint-utils/src/main/java/com/fuint/utils/Encodes.java
Normal file
@ -0,0 +1,125 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import com.fuint.exception.Exceptions;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
|
||||
/**
|
||||
* 编码转换工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class Encodes {
|
||||
|
||||
private static final String DEFAULT_URL_ENCODING = "UTF-8";
|
||||
private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
.toCharArray();
|
||||
|
||||
/**
|
||||
* Hex编码.
|
||||
*/
|
||||
public static String encodeHex(byte[] input) {
|
||||
return Hex.encodeHexString(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hex解码.
|
||||
*/
|
||||
public static byte[] decodeHex(String input) {
|
||||
try {
|
||||
return Hex.decodeHex(input.toCharArray());
|
||||
} catch (DecoderException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64编码.
|
||||
*/
|
||||
public static String encodeBase64(byte[] input) {
|
||||
return Base64.encodeBase64String(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).
|
||||
*/
|
||||
public static String encodeUrlSafeBase64(byte[] input) {
|
||||
return Base64.encodeBase64URLSafeString(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64解码.
|
||||
*/
|
||||
public static byte[] decodeBase64(String input) {
|
||||
return Base64.decodeBase64(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base62编码。
|
||||
*/
|
||||
public static String encodeBase62(byte[] input) {
|
||||
char[] chars = new char[input.length];
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
chars[i] = BASE62[(input[i] & 0xFF) % BASE62.length];
|
||||
}
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Html 转码.
|
||||
*/
|
||||
public static String escapeHtml(String html) {
|
||||
return StringEscapeUtils.escapeHtml(html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Html 解码.
|
||||
*/
|
||||
public static String unescapeHtml(String htmlEscaped) {
|
||||
return StringEscapeUtils.unescapeHtml(htmlEscaped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Xml 转码.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static String escapeXml(String xml) {
|
||||
return StringEscapeUtils.escapeXml(xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Xml 解码.
|
||||
*/
|
||||
public static String unescapeXml(String xmlEscaped) {
|
||||
return StringEscapeUtils.unescapeXml(xmlEscaped);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL 编码, Encode默认为UTF-8.
|
||||
*/
|
||||
public static String urlEncode(String part) {
|
||||
try {
|
||||
return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw com.fuint.exception.Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL 解码, Encode默认为UTF-8.
|
||||
*/
|
||||
public static String urlDecode(String part) {
|
||||
|
||||
try {
|
||||
return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw com.fuint.exception.Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
363
fuint-utils/src/main/java/com/fuint/utils/ExportExcelUtil.java
Normal file
363
fuint-utils/src/main/java/com/fuint/utils/ExportExcelUtil.java
Normal file
@ -0,0 +1,363 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 利用开源组件POI3.0.2动态导出EXCEL文档 转载时请保留以下信息,注明出处!
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
* @param <T>
|
||||
* 应用泛型,代表任意一个符合javabean风格的类
|
||||
* 注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx()
|
||||
* byte[]表jpg格式的图片数据
|
||||
*/
|
||||
public class ExportExcelUtil<T> {
|
||||
|
||||
public void exportExcel(String title,Collection<T> dataset, OutputStream out) {
|
||||
exportExcel(title, null, dataset, out, "yyyy-MM-dd");
|
||||
}
|
||||
|
||||
|
||||
public void exportExcel(String title,
|
||||
String[] headers,
|
||||
Collection<T> dataset,
|
||||
OutputStream out,
|
||||
String pattern) {
|
||||
exportExcel(title, headers, dataset, out, pattern);
|
||||
}
|
||||
|
||||
|
||||
public void exportExcel(String title,
|
||||
String[] headers,
|
||||
String[] fields,
|
||||
Collection<T> dataset,
|
||||
OutputStream out) {
|
||||
|
||||
exportExcel(title,
|
||||
headers,
|
||||
fields,
|
||||
dataset,
|
||||
out,
|
||||
"yyyy-MM-dd");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
|
||||
*
|
||||
* @param title
|
||||
* 表格标题名
|
||||
* @param headers
|
||||
* 表格属性列名数组
|
||||
* @param dataset
|
||||
* 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
|
||||
* javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
|
||||
* @param out
|
||||
* 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
|
||||
* @param pattern
|
||||
* 如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void exportExcel(String title,
|
||||
String[] headers,
|
||||
String[] ofields,
|
||||
Collection<T> dataset,
|
||||
OutputStream out,
|
||||
String pattern) {
|
||||
// 声明一个工作薄
|
||||
HSSFWorkbook workbook = new HSSFWorkbook();
|
||||
// 生成一个表格
|
||||
HSSFSheet sheet = workbook.createSheet(title);
|
||||
// 设置表格默认列宽度为15个字节
|
||||
sheet.setDefaultColumnWidth((short) 15);
|
||||
// 生成一个样式
|
||||
|
||||
HSSFCellStyle hssfCellStyle = workbook.createCellStyle();
|
||||
HSSFFont font = workbook.createFont();
|
||||
font.setColor(HSSFColor.BLACK.index);
|
||||
hssfCellStyle.setFont(font);
|
||||
// 产生表格标题行
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
HSSFCell cell = row.createCell(i);
|
||||
// cell.setCellStyle(style);
|
||||
HSSFRichTextString text = new HSSFRichTextString(headers[i]);
|
||||
cell.setCellValue(text);
|
||||
cell.setCellStyle(hssfCellStyle);
|
||||
}
|
||||
|
||||
// 遍历集合数据,产生数据行
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
Iterator<T> it = dataset.iterator();
|
||||
int index = 0;
|
||||
while (it.hasNext()) {
|
||||
index++;
|
||||
row = sheet.createRow(index);
|
||||
T t = (T) it.next();
|
||||
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
|
||||
if (ofields != null) {
|
||||
for (int i = 0; i < ofields.length; i++) {
|
||||
HSSFCell cell = row.createCell(i);
|
||||
// cell.setCellStyle(style2);
|
||||
String fieldName = ofields[i];
|
||||
|
||||
String getMethodName = "get"
|
||||
+ fieldName.substring(0, 1)
|
||||
.toUpperCase()
|
||||
+ fieldName.substring(1);
|
||||
try {
|
||||
Class tCls = t.getClass();
|
||||
Object value = null;
|
||||
try {
|
||||
Method getMethod = tCls.getMethod(getMethodName,
|
||||
new Class[]{});
|
||||
value = getMethod.invoke(t, new Object[]{});
|
||||
}
|
||||
catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
// 判断值的类型后进行强制类型转换
|
||||
String textValue;
|
||||
if (value == null)
|
||||
continue;
|
||||
textValue = convertTextValue(pattern, df, value);
|
||||
// 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
|
||||
if (textValue != null) {
|
||||
Pattern p = Pattern.compile("^//d+(//.//d+)?$");
|
||||
Matcher matcher = p.matcher(textValue);
|
||||
if (matcher.matches()) {
|
||||
// 是数字当作double处理
|
||||
cell.setCellValue(Double.parseDouble(textValue));
|
||||
} else {
|
||||
HSSFRichTextString richString = new HSSFRichTextString(textValue);
|
||||
HSSFFont font3 = workbook.createFont();
|
||||
font3.setColor(HSSFColor.BLACK.index);
|
||||
richString.applyFont(font3);
|
||||
cell.setCellValue(richString);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
// 清理资源
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Field[] fields = t.getClass().getDeclaredFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
HSSFCell cell = row.createCell(i);
|
||||
// cell.setCellStyle(style2);
|
||||
Field field = fields[i];
|
||||
String fieldName = field.getName();
|
||||
|
||||
String getMethodName = "get"
|
||||
+ fieldName.substring(0, 1)
|
||||
.toUpperCase()
|
||||
+ fieldName.substring(1);
|
||||
try {
|
||||
Class tCls = t.getClass();
|
||||
Object value = null;
|
||||
try {
|
||||
Method getMethod = tCls.getMethod(getMethodName,
|
||||
new Class[]{});
|
||||
value = getMethod.invoke(t, new Object[]{});
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 判断值的类型后进行强制类型转换
|
||||
String textValue = null;
|
||||
|
||||
if (value == null)
|
||||
continue;
|
||||
textValue = convertTextValue(pattern, df, value);
|
||||
// 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
|
||||
if (textValue != null) {
|
||||
Pattern p = Pattern.compile("^//d+(//.//d+)?$");
|
||||
Matcher matcher = p.matcher(textValue);
|
||||
if (matcher.matches()) {
|
||||
// 是数字当作double处理
|
||||
cell.setCellValue(Double.parseDouble(textValue));
|
||||
} else {
|
||||
HSSFRichTextString richString = new HSSFRichTextString(textValue);
|
||||
// HSSFFont font3 = workbook.createFont();
|
||||
font.setColor(HSSFColor.BLACK.index);
|
||||
richString.applyFont(font);
|
||||
cell.setCellValue(richString);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
// 清理资源
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
workbook.write(out);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String convertTextValue(String pattern, DecimalFormat df, Object value) {
|
||||
String textValue;
|
||||
if (value instanceof Date) {
|
||||
Date date = (Date) value;
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
|
||||
textValue = sdf.format(date);
|
||||
} else if(value instanceof Timestamp){
|
||||
Timestamp timestamp = (Timestamp) value;
|
||||
Date date = new Date(timestamp.getTime());
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
|
||||
textValue = sdf.format(date);
|
||||
} else if (value instanceof Number) {
|
||||
if (((Number) value).intValue() != 0) {
|
||||
textValue = df.format((float) ((Number) value).intValue() / 100);
|
||||
} else {
|
||||
textValue = "0.00";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* else if (value instanceof byte[]) { //
|
||||
* 有图片时,设置行高为60px; row.setHeightInPoints(60); //
|
||||
* 设置图片所在列宽度为80px,注意这里单位的一个换算 sheet.setColumnWidth(i,
|
||||
* (short) (35.7 * 80)); // sheet.autoSizeColumn(i);
|
||||
* byte[] bsValue = (byte[]) value; HSSFClientAnchor
|
||||
* anchor = new HSSFClientAnchor(0, 0, 1023, 255,
|
||||
* (short) 6, index, (short) 6, index);
|
||||
* anchor.setAnchorType(2);
|
||||
* patriarch.createPicture(anchor, workbook.addPicture(
|
||||
* bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG)); }
|
||||
*/
|
||||
else {
|
||||
// 其它数据类型都当作字符串简单处理
|
||||
textValue = value.toString();
|
||||
}
|
||||
return textValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void exportExcel(String title,
|
||||
String[] headers,
|
||||
Collection<String[]> dataset,
|
||||
OutputStream out) {
|
||||
// 声明一个工作薄
|
||||
HSSFWorkbook workbook = new HSSFWorkbook();
|
||||
// 生成一个表格
|
||||
HSSFSheet sheet = workbook.createSheet(title);
|
||||
// 设置表格默认列宽度为15个字节
|
||||
sheet.setDefaultColumnWidth((short) 15);
|
||||
// 生成一个样式
|
||||
HSSFCellStyle style = workbook.createCellStyle();
|
||||
// 设置这些样式
|
||||
style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
|
||||
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
|
||||
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
|
||||
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
|
||||
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
|
||||
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
|
||||
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
|
||||
// 生成一个字体
|
||||
HSSFFont font = workbook.createFont();
|
||||
font.setColor(HSSFColor.VIOLET.index);
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
|
||||
// 把字体应用到当前的样式
|
||||
style.setFont(font);
|
||||
// 生成并设置另一个样式
|
||||
HSSFCellStyle style2 = workbook.createCellStyle();
|
||||
style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
|
||||
style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
|
||||
style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
|
||||
style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
|
||||
style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
|
||||
style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
|
||||
style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
|
||||
style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
|
||||
// 生成另一个字体
|
||||
HSSFFont font2 = workbook.createFont();
|
||||
font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
|
||||
// 把字体应用到当前的样式
|
||||
style2.setFont(font2);
|
||||
|
||||
// 声明一个画图的顶级管理器
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
// 定义注释的大小和位置,详见文档
|
||||
HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(short) 4,
|
||||
2,
|
||||
(short) 6,
|
||||
5));
|
||||
// 设置注释内容
|
||||
comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));
|
||||
// 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
|
||||
comment.setAuthor("leno");
|
||||
|
||||
// 产生表格标题行
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
HSSFCell cell = row.createCell(i);
|
||||
cell.setCellStyle(style);
|
||||
HSSFRichTextString text = new HSSFRichTextString(headers[i]);
|
||||
cell.setCellValue(text);
|
||||
}
|
||||
|
||||
// 遍历集合数据,产生数据行
|
||||
Iterator<String[]> it = dataset.iterator();
|
||||
int index = 0;
|
||||
while (it.hasNext()) {
|
||||
index++;
|
||||
row = sheet.createRow(index);// 行
|
||||
String[] t = (String[]) it.next();
|
||||
|
||||
for (int i = 0; i < t.length; i++) {
|
||||
HSSFCell cell = row.createCell(i);// 行的格
|
||||
cell.setCellStyle(style2);// 行的样式
|
||||
HSSFRichTextString richString = new HSSFRichTextString(t[i]);
|
||||
HSSFFont font3 = workbook.createFont();
|
||||
font3.setColor(HSSFColor.BLUE.index);
|
||||
richString.applyFont(font3);
|
||||
cell.setCellValue(richString);
|
||||
}
|
||||
}
|
||||
try {
|
||||
workbook.write(out);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
147
fuint-utils/src/main/java/com/fuint/utils/HttpUtil.java
Normal file
147
fuint-utils/src/main/java/com/fuint/utils/HttpUtil.java
Normal file
@ -0,0 +1,147 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* http请求工具
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class HttpUtil {
|
||||
|
||||
public static final int CONNECT_TIMEOUT = 30000;
|
||||
public static final int READ_TIMEOUT = 60000;
|
||||
public static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
public static byte[] toByteArray(Object obj) {
|
||||
byte[] bytes = null;
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
try {
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(obj);
|
||||
oos.flush();
|
||||
bytes = bos.toByteArray();
|
||||
oos.close();
|
||||
bos.close();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送http请求
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String sendRequest(String url) {
|
||||
URL myURL = null;
|
||||
URLConnection httpsConn;
|
||||
// 进行转码
|
||||
try {
|
||||
myURL = new URL(url);
|
||||
} catch (MalformedURLException e) {
|
||||
// empty
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
try {
|
||||
httpsConn = myURL.openConnection();
|
||||
if (httpsConn != null) {
|
||||
InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8");
|
||||
BufferedReader br = new BufferedReader(insr);
|
||||
String data = null;
|
||||
while ((data = br.readLine()) != null) {
|
||||
sb.append(data);
|
||||
}
|
||||
insr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String sendRequest(URL url, String data, Method method, Map<String, String> headers) throws IOException {
|
||||
HttpURLConnection client = (HttpURLConnection) url.openConnection();
|
||||
client.setConnectTimeout(CONNECT_TIMEOUT);
|
||||
client.setReadTimeout(READ_TIMEOUT);
|
||||
client.setRequestMethod(method.value);
|
||||
if (headers != null && headers.size() > 0) {
|
||||
Iterator iter = headers.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
String key = iter.next().toString();
|
||||
client.setRequestProperty(key, headers.get(key));
|
||||
}
|
||||
}
|
||||
if (Method.POST.equals(method)) {
|
||||
// 发送数据
|
||||
if (data != null) {
|
||||
client.setDoOutput(true);
|
||||
OutputStreamWriter osw = new OutputStreamWriter(client.getOutputStream(), "UTF-8");
|
||||
osw.write(data);
|
||||
osw.flush();
|
||||
osw.close();
|
||||
}
|
||||
}
|
||||
// 发送请求
|
||||
client.connect();
|
||||
if (client.getResponseCode() >= 300) {
|
||||
throw new ServerUnavailable(url, client.getResponseCode(), client.getResponseMessage());
|
||||
}
|
||||
|
||||
// 获取响应
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream(), UTF8));
|
||||
StringBuilder response = new StringBuilder();
|
||||
for (String line = in.readLine(); line != null; line = in.readLine()) {
|
||||
response.append(line);
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
public enum Method {
|
||||
GET("GET"),
|
||||
POST("POST"),
|
||||
DELETE("DELETE"),
|
||||
PUT("PUT");
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
private Method(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ServerUnavailable extends RuntimeException {
|
||||
/**
|
||||
* serialVersionUID
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServerUnavailable(URL url, int code, String msg) {
|
||||
super("url: " + url + ", code: " + code + ", msg: " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
416
fuint-utils/src/main/java/com/fuint/utils/IDCard.java
Normal file
416
fuint-utils/src/main/java/com/fuint/utils/IDCard.java
Normal file
@ -0,0 +1,416 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 身份证工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class IDCard {
|
||||
|
||||
/**
|
||||
* 省,直辖市代码表: { 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",
|
||||
* 21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",
|
||||
* 33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",
|
||||
* 42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",
|
||||
* 51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",
|
||||
* 63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"}
|
||||
*/
|
||||
protected String codeAndCity[][] = {{"11", "北京"}, {"12", "天津"},
|
||||
{"13", "河北"}, {"14", "山西"}, {"15", "内蒙古"}, {"21", "辽宁"},
|
||||
{"22", "吉林"}, {"23", "黑龙江"}, {"31", "上海"}, {"32", "江苏"},
|
||||
{"33", "浙江"}, {"34", "安徽"}, {"35", "福建"}, {"36", "江西"},
|
||||
{"37", "山东"}, {"41", "河南"}, {"42", "湖北"}, {"43", "湖南"},
|
||||
{"44", "广东"}, {"45", "广西"}, {"46", "海南"}, {"50", "重庆"},
|
||||
{"51", "四川"}, {"52", "贵州"}, {"53", "云南"}, {"54", "西藏"},
|
||||
{"61", "陕西"}, {"62", "甘肃"}, {"63", "青海"}, {"64", "宁夏"},
|
||||
{"65", "新疆"}, {"71", "台湾"}, {"81", "香港"}, {"82", "澳门"},
|
||||
{"91", "国外"}};
|
||||
|
||||
private final String cityCode[] = {"11", "12", "13", "14", "15", "21", "22",
|
||||
"23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43",
|
||||
"44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63",
|
||||
"64", "65", "71", "81", "82", "91"};
|
||||
|
||||
// 每位加权因子
|
||||
private int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
|
||||
|
||||
// 第18位校检码
|
||||
private final String verifyCode[] = {"1", "0", "X", "9", "8", "7", "6", "5",
|
||||
"4", "3", "2"};
|
||||
|
||||
/**
|
||||
* 验证所有的身份证的合法性
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidatedAllIdcard(String idcard) {
|
||||
if (idcard.length() == 15) {
|
||||
idcard = this.convertIdcarBy15bit(idcard);
|
||||
}
|
||||
return this.isValidate18Idcard(idcard);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 判断18位身份证的合法性
|
||||
* </p>
|
||||
* 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
|
||||
* 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
|
||||
* <p>
|
||||
* 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。
|
||||
* </p>
|
||||
* <p>
|
||||
* 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码;
|
||||
* 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码;
|
||||
* 6.第17位数字表示性别:奇数表示男性,偶数表示女性;
|
||||
* 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。
|
||||
* </p>
|
||||
* <p>
|
||||
* 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4
|
||||
* 2 1 6 3 7 9 10 5 8 4 2
|
||||
* </p>
|
||||
* <p>
|
||||
* 2.将这17位数字和系数相乘的结果相加。
|
||||
* </p>
|
||||
* <p>
|
||||
* 3.用加出来和除以11,看余数是多少?
|
||||
* </p>
|
||||
* 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3
|
||||
* 2。
|
||||
* <p>
|
||||
* 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。
|
||||
* </p>
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidate18Idcard(String idcard) {
|
||||
// 非18位为假
|
||||
if (idcard.length() != 18) {
|
||||
return false;
|
||||
}
|
||||
// 获取前17位
|
||||
String idcard17 = idcard.substring(0, 17);
|
||||
// 获取第18位
|
||||
String idcard18Code = idcard.substring(17, 18);
|
||||
char c[] = null;
|
||||
String checkCode = "";
|
||||
// 是否都为数字
|
||||
if (isDigital(idcard17)) {
|
||||
c = idcard17.toCharArray();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null != c) {
|
||||
int bit[] = new int[idcard17.length()];
|
||||
|
||||
bit = converCharToInt(c);
|
||||
|
||||
int sum17 = 0;
|
||||
|
||||
sum17 = getPowerSum(bit);
|
||||
|
||||
// 将和值与11取模得到余数进行校验码判断
|
||||
checkCode = getCheckCodeBySum(sum17);
|
||||
if (null == checkCode) {
|
||||
return false;
|
||||
}
|
||||
// 将身份证的第18位与算出来的校码进行匹配,不相等就为假
|
||||
if (!idcard18Code.equalsIgnoreCase(checkCode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证15位身份证的合法性,该方法验证不准确,最好是将15转为18位后再判断,该类中已提供。
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidate15Idcard(String idcard) {
|
||||
// 非15位为假
|
||||
if (idcard.length() != 15) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 是否全都为数字
|
||||
if (isDigital(idcard)) {
|
||||
String provinceid = idcard.substring(0, 2);
|
||||
String birthday = idcard.substring(6, 12);
|
||||
int year = Integer.parseInt(idcard.substring(6, 8));
|
||||
int month = Integer.parseInt(idcard.substring(8, 10));
|
||||
int day = Integer.parseInt(idcard.substring(10, 12));
|
||||
|
||||
// 判断是否为合法的省份
|
||||
boolean flag = false;
|
||||
for (String id : cityCode) {
|
||||
if (id.equals(provinceid)) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
// 该身份证生出日期在当前日期之后时为假
|
||||
Date birthdate = null;
|
||||
try {
|
||||
birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (birthdate == null || new Date().before(birthdate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 判断是否为合法的年份
|
||||
GregorianCalendar curDay = new GregorianCalendar();
|
||||
int curYear = curDay.get(Calendar.YEAR);
|
||||
int year2bit = Integer.parseInt(String.valueOf(curYear)
|
||||
.substring(2));
|
||||
|
||||
// 判断该年份的两位表示法,小于50的和大于当前年份的,为假
|
||||
if ((year < 50 && year > year2bit)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 判断是否为合法的月份
|
||||
if (month < 1 || month > 12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 判断是否为合法的日期
|
||||
boolean mflag = false;
|
||||
curDay.setTime(birthdate); // 将该身份证的出生日期赋于对象curDay
|
||||
switch (month) {
|
||||
case 1:
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
mflag = (day >= 1 && day <= 31);
|
||||
break;
|
||||
case 2: // 公历的2月非闰年有28天,闰年的2月是29天。
|
||||
if (curDay.isLeapYear(curDay.get(Calendar.YEAR))) {
|
||||
mflag = (day >= 1 && day <= 29);
|
||||
} else {
|
||||
mflag = (day >= 1 && day <= 28);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
case 9:
|
||||
case 11:
|
||||
mflag = (day >= 1 && day <= 30);
|
||||
break;
|
||||
}
|
||||
if (!mflag) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将15位的身份证转成18位身份证
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public String convertIdcarBy15bit(String idcard) {
|
||||
String idcard17 = null;
|
||||
// 非15位身份证
|
||||
if (idcard.length() != 15) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isDigital(idcard)) {
|
||||
// 获取出生年月日
|
||||
String birthday = idcard.substring(6, 12);
|
||||
Date birthdate = null;
|
||||
try {
|
||||
birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Calendar cday = Calendar.getInstance();
|
||||
cday.setTime(birthdate);
|
||||
String year = String.valueOf(cday.get(Calendar.YEAR));
|
||||
|
||||
idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);
|
||||
|
||||
char c[] = idcard17.toCharArray();
|
||||
String checkCode = "";
|
||||
|
||||
if (null != c) {
|
||||
int bit[] = new int[idcard17.length()];
|
||||
|
||||
// 将字符数组转为整型数组
|
||||
bit = converCharToInt(c);
|
||||
int sum17 = 0;
|
||||
sum17 = getPowerSum(bit);
|
||||
|
||||
// 获取和值与11取模得到余数进行校验码
|
||||
checkCode = getCheckCodeBySum(sum17);
|
||||
// 获取不到校验位
|
||||
if (null == checkCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 将前17位与第18位校验码拼接
|
||||
idcard17 += checkCode;
|
||||
}
|
||||
} else { // 身份证包含数字
|
||||
return null;
|
||||
}
|
||||
return idcard17;
|
||||
}
|
||||
|
||||
/**
|
||||
* 15位和18位身份证号码的基本数字和位数验校
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public boolean isIdcard(String idcard) {
|
||||
return idcard == null || "".equals(idcard) ? false : Pattern.matches(
|
||||
"(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)", idcard);
|
||||
}
|
||||
|
||||
/**
|
||||
* 15位身份证号码的基本数字和位数验校
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public boolean is15Idcard(String idcard) {
|
||||
return idcard == null || "".equals(idcard) ? false : Pattern.matches(
|
||||
"^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$",
|
||||
idcard);
|
||||
}
|
||||
|
||||
/**
|
||||
* 18位身份证号码的基本数字和位数验校
|
||||
*
|
||||
* @param idcard
|
||||
* @return
|
||||
*/
|
||||
public boolean is18Idcard(String idcard) {
|
||||
return Pattern
|
||||
.matches(
|
||||
"^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([\\d|x|X]{1})$",
|
||||
idcard);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字验证
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public boolean isDigital(String str) {
|
||||
return str == null || "".equals(str) ? false : str.matches("^[0-9]*$");
|
||||
}
|
||||
|
||||
/**
|
||||
* 将身份证的每位和对应位的加权因子相乘之后,再得到和值
|
||||
*
|
||||
* @param bit
|
||||
* @return
|
||||
*/
|
||||
public int getPowerSum(int[] bit) {
|
||||
|
||||
int sum = 0;
|
||||
|
||||
if (power.length != bit.length) {
|
||||
return sum;
|
||||
}
|
||||
|
||||
for (int i = 0; i < bit.length; i++) {
|
||||
for (int j = 0; j < power.length; j++) {
|
||||
if (i == j) {
|
||||
sum = sum + bit[i] * power[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将和值与11取模得到余数进行校验码判断
|
||||
*
|
||||
* @param sum17
|
||||
* @return 校验位
|
||||
*/
|
||||
public String getCheckCodeBySum(int sum17) {
|
||||
String checkCode = null;
|
||||
switch (sum17 % 11) {
|
||||
case 10:
|
||||
checkCode = "2";
|
||||
break;
|
||||
case 9:
|
||||
checkCode = "3";
|
||||
break;
|
||||
case 8:
|
||||
checkCode = "4";
|
||||
break;
|
||||
case 7:
|
||||
checkCode = "5";
|
||||
break;
|
||||
case 6:
|
||||
checkCode = "6";
|
||||
break;
|
||||
case 5:
|
||||
checkCode = "7";
|
||||
break;
|
||||
case 4:
|
||||
checkCode = "8";
|
||||
break;
|
||||
case 3:
|
||||
checkCode = "9";
|
||||
break;
|
||||
case 2:
|
||||
checkCode = "x";
|
||||
break;
|
||||
case 1:
|
||||
checkCode = "0";
|
||||
break;
|
||||
case 0:
|
||||
checkCode = "1";
|
||||
break;
|
||||
}
|
||||
return checkCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符数组转为整型数组
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public int[] converCharToInt(char[] c) throws NumberFormatException {
|
||||
int[] a = new int[c.length];
|
||||
int k = 0;
|
||||
for (char temp : c) {
|
||||
a[k++] = Integer.parseInt(String.valueOf(temp));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
72
fuint-utils/src/main/java/com/fuint/utils/IpUtil.java
Normal file
72
fuint-utils/src/main/java/com/fuint/utils/IpUtil.java
Normal file
@ -0,0 +1,72 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* IP地址工具类
|
||||
*
|
||||
* Created by: FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class IpUtil {
|
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(IpUtil.class);
|
||||
|
||||
/**
|
||||
* 校验IP是否在指定的段
|
||||
*
|
||||
* @param ipSection IP网段,如: 10.167.7.1-10.167.7.255
|
||||
* @param ip Ip地址,如:10.167.7.56
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean ipIsValid(String ipSection, String ip) {
|
||||
if (ipSection == null) {
|
||||
throw new NullPointerException("IP段不能为空!");
|
||||
}
|
||||
|
||||
if (ip == null) {
|
||||
throw new NullPointerException("IP不能为空!");
|
||||
}
|
||||
|
||||
ipSection = ipSection.trim();
|
||||
ip = ip.trim();
|
||||
final String REGX_IP = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
|
||||
final String REGX_IPB = REGX_IP + "\\-" + REGX_IP;
|
||||
if (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP))
|
||||
return false;
|
||||
int idx = ipSection.indexOf('-');
|
||||
String[] sips = ipSection.substring(0, idx).split("\\.");
|
||||
String[] sipe = ipSection.substring(idx + 1).split("\\.");
|
||||
String[] sipt = ip.split("\\.");
|
||||
long ips = 0L, ipe = 0L, ipt = 0L;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
ips = ips << 8 | Integer.parseInt(sips[i]);
|
||||
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
|
||||
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
|
||||
}
|
||||
if (ips > ipe) {
|
||||
long t = ips;
|
||||
ips = ipe;
|
||||
ipe = t;
|
||||
}
|
||||
return ips <= ipt && ipt <= ipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验IP是否在指定的段列表
|
||||
*
|
||||
* @param ip
|
||||
* @param ipSections
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean ipIsValid(String ip, String... ipSections) {
|
||||
for (String ipSection : ipSections) {
|
||||
if (ipIsValid(ipSection, ip)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
41
fuint-utils/src/main/java/com/fuint/utils/MD5Util.java
Normal file
41
fuint-utils/src/main/java/com/fuint/utils/MD5Util.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* MD5加密工具
|
||||
*
|
||||
* Created by: FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class MD5Util {
|
||||
private final static char[] hexDigits = {'0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int t;
|
||||
for (int i = 0; i < 16; i++) {// 16 == bytes.length;
|
||||
|
||||
t = bytes[i];
|
||||
if (t < 0)
|
||||
t += 256;
|
||||
sb.append(hexDigits[(t >>> 4)]);
|
||||
sb.append(hexDigits[(t % 16)]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String code(String input) {
|
||||
byte[] bytes = null;
|
||||
MessageDigest md = null;
|
||||
try {
|
||||
bytes = input.getBytes("utf-8");
|
||||
md = MessageDigest.getInstance(System.getProperty(
|
||||
"MD5.algorithm", "MD5"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bytesToHex(md.digest(bytes));
|
||||
}
|
||||
}
|
||||
376
fuint-utils/src/main/java/com/fuint/utils/ObjectUtil.java
Normal file
376
fuint-utils/src/main/java/com/fuint/utils/ObjectUtil.java
Normal file
@ -0,0 +1,376 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 有关<code>Object</code>处理的工具类。
|
||||
*
|
||||
* 这个类中的每个方法都可以“安全”地处理<code>null</code>,而不会抛出<code>NullPointerException</code>。
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class ObjectUtil {
|
||||
/* ============================================================================ */
|
||||
/* 常量和singleton。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 用于表示<code>null</code>的常量。
|
||||
*
|
||||
* <p>
|
||||
* 例如,<code>HashMap.get(Object)</code>方法返回<code>null</code>有两种可能:
|
||||
* 值不存在或值为<code>null</code>。而这个singleton可用来区别这两种情形。
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* 另一个例子是,<code>Hashtable</code>的值不能为<code>null</code>。
|
||||
* </p>
|
||||
*/
|
||||
public static final Object NULL = new Serializable() {
|
||||
private static final long serialVersionUID = 7092611880189329093L;
|
||||
|
||||
private Object readResolve() {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
/* ============================================================================ */
|
||||
/* 默认值函数。 */
|
||||
/* */
|
||||
/* 当对象为null时,将对象转换成指定的默认对象。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 如果对象为<code>null</code>,则返回指定默认对象,否则返回对象本身。
|
||||
* <pre>
|
||||
* ObjectUtil.defaultIfNull(null, null) = null
|
||||
* ObjectUtil.defaultIfNull(null, "") = ""
|
||||
* ObjectUtil.defaultIfNull(null, "zz") = "zz"
|
||||
* ObjectUtil.defaultIfNull("abc", *) = "abc"
|
||||
* ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
|
||||
* </pre>
|
||||
*
|
||||
* @param object 要测试的对象
|
||||
* @param defaultValue 默认值
|
||||
*
|
||||
* @return 对象本身或默认对象
|
||||
*/
|
||||
public static Object defaultIfNull(Object object, Object defaultValue) {
|
||||
return (object != null) ? object : defaultValue;
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
/* 比较函数。 */
|
||||
/* */
|
||||
/* 以下方法用来比较两个对象是否相同。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 比较两个对象是否完全相等。
|
||||
*
|
||||
* <p>
|
||||
* 此方法可以正确地比较多维数组。
|
||||
* <pre>
|
||||
* ObjectUtil.equals(null, null) = true
|
||||
* ObjectUtil.equals(null, "") = false
|
||||
* ObjectUtil.equals("", null) = false
|
||||
* ObjectUtil.equals("", "") = true
|
||||
* ObjectUtil.equals(Boolean.TRUE, null) = false
|
||||
* ObjectUtil.equals(Boolean.TRUE, "true") = false
|
||||
* ObjectUtil.equals(Boolean.TRUE, Boolean.TRUE) = true
|
||||
* ObjectUtil.equals(Boolean.TRUE, Boolean.FALSE) = false
|
||||
* </pre>
|
||||
* </p>
|
||||
*
|
||||
* @param object1 对象1
|
||||
* @param object2 对象2
|
||||
*
|
||||
* @return 如果相等, 则返回<code>true</code>
|
||||
*/
|
||||
public static boolean equals(Object object1, Object object2) {
|
||||
return ArrayUtil.equals(object1, object2);
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
/* Hashcode函数。 */
|
||||
/* */
|
||||
/* 以下方法用来取得对象的hash code。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 取得对象的hash值, 如果对象为<code>null</code>, 则返回<code>0</code>。
|
||||
*
|
||||
* <p>
|
||||
* 此方法可以正确地处理多维数组。
|
||||
* </p>
|
||||
*
|
||||
* @param object 对象
|
||||
*
|
||||
* @return hash值
|
||||
*/
|
||||
public static int hashCode(Object object) {
|
||||
return ArrayUtil.hashCode(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得对象的原始的hash值, 如果对象为<code>null</code>, 则返回<code>0</code>。
|
||||
*
|
||||
* <p>
|
||||
* 该方法使用<code>System.identityHashCode</code>来取得hash值,该值不受对象本身的<code>hashCode</code>方法的影响。
|
||||
* </p>
|
||||
*
|
||||
* @param object 对象
|
||||
*
|
||||
* @return hash值
|
||||
*/
|
||||
public static int identityHashCode(Object object) {
|
||||
return (object == null) ? 0 : System.identityHashCode(object);
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
/* 取得对象的identity。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 取得对象自身的identity,如同对象没有覆盖<code>toString()</code>方法时,<code>Object.toString()</code>的原始输出。
|
||||
* <pre>
|
||||
* ObjectUtil.identityToString(null) = null
|
||||
* ObjectUtil.identityToString("") = "java.lang.String@1e23"
|
||||
* ObjectUtil.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
|
||||
* ObjectUtil.identityToString(new int[0]) = "int[]@7fa"
|
||||
* ObjectUtil.identityToString(new Object[0]) = "java.lang.Object[]@7fa"
|
||||
* </pre>
|
||||
*
|
||||
* @param object 对象
|
||||
*
|
||||
* @return 对象的identity,如果对象是<code>null</code>,则返回<code>null</code>
|
||||
*/
|
||||
public static String identityToString(Object object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return appendIdentityToString(null, object).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得对象自身的identity,如同对象没有覆盖<code>toString()</code>方法时,<code>Object.toString()</code>的原始输出。
|
||||
* <pre>
|
||||
* ObjectUtil.identityToString(null, "NULL") = "NULL"
|
||||
* ObjectUtil.identityToString("", "NULL") = "java.lang.String@1e23"
|
||||
* ObjectUtil.identityToString(Boolean.TRUE, "NULL") = "java.lang.Boolean@7fa"
|
||||
* ObjectUtil.identityToString(new int[0], "NULL") = "int[]@7fa"
|
||||
* ObjectUtil.identityToString(new Object[0], "NULL") = "java.lang.Object[]@7fa"
|
||||
* </pre>
|
||||
*
|
||||
* @param object 对象
|
||||
* @param nullStr 如果对象为<code>null</code>,则返回该字符串
|
||||
*
|
||||
* @return 对象的identity,如果对象是<code>null</code>,则返回指定字符串
|
||||
*/
|
||||
public static String identityToString(Object object, String nullStr) {
|
||||
if (object == null) {
|
||||
return nullStr;
|
||||
}
|
||||
|
||||
return appendIdentityToString(null, object).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象自身的identity——如同对象没有覆盖<code>toString()</code>方法时,<code>Object.toString()</code>的原始输出——追加到<code>StringBuffer</code>中。
|
||||
* <pre>
|
||||
* ObjectUtil.appendIdentityToString(*, null) = null
|
||||
* ObjectUtil.appendIdentityToString(null, "") = "java.lang.String@1e23"
|
||||
* ObjectUtil.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa"
|
||||
* ObjectUtil.appendIdentityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa")
|
||||
* ObjectUtil.appendIdentityToString(buf, new int[0]) = buf.append("int[]@7fa")
|
||||
* ObjectUtil.appendIdentityToString(buf, new Object[0]) = buf.append("java.lang.Object[]@7fa")
|
||||
* </pre>
|
||||
*
|
||||
* @param buffer <code>StringBuffer</code>对象,如果是<code>null</code>,则创建新的
|
||||
* @param object 对象
|
||||
*
|
||||
* @return <code>StringBuffer</code>对象,如果对象为<code>null</code>,则返回<code>null</code>
|
||||
*/
|
||||
public static StringBuffer appendIdentityToString(StringBuffer buffer, Object object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuffer();
|
||||
}
|
||||
|
||||
buffer.append(ClassUtil.getClassNameForObject(object));
|
||||
|
||||
return buffer.append('@').append(Integer.toHexString(identityHashCode(object)));
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
/* Clone函数。 */
|
||||
/* */
|
||||
/* 以下方法调用Object.clone方法,默认是“浅复制”(shallow copy)。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 复制一个对象。如果对象为<code>null</code>,则返回<code>null</code>。
|
||||
*
|
||||
* <p>
|
||||
* 此方法调用<code>Object.clone</code>方法,默认只进行“浅复制”。 对于数组,调用<code>ArrayUtil.clone</code>方法更高效。
|
||||
* </p>
|
||||
*
|
||||
* @param array 要复制的数组
|
||||
*
|
||||
* @return 数组的复本,如果原始数组为<code>null</code>,则返回<code>null</code>
|
||||
*/
|
||||
public static Object clone(Object array) {
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 对数组特殊处理
|
||||
if (array instanceof Object[]) {
|
||||
return ArrayUtil.clone((Object[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof long[]) {
|
||||
return ArrayUtil.clone((long[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof int[]) {
|
||||
return ArrayUtil.clone((int[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof short[]) {
|
||||
return ArrayUtil.clone((short[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof byte[]) {
|
||||
return ArrayUtil.clone((byte[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof double[]) {
|
||||
return ArrayUtil.clone((double[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof float[]) {
|
||||
return ArrayUtil.clone((float[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof boolean[]) {
|
||||
return ArrayUtil.clone((boolean[]) array);
|
||||
}
|
||||
|
||||
if (array instanceof char[]) {
|
||||
return ArrayUtil.clone((char[]) array);
|
||||
}
|
||||
|
||||
// Not cloneable
|
||||
if (!(array instanceof Cloneable)) {
|
||||
throw new RuntimeException("Object of class " + array.getClass().getName()
|
||||
+ " is not Cloneable");
|
||||
}
|
||||
|
||||
// 用reflection调用clone方法
|
||||
Class clazz = array.getClass();
|
||||
|
||||
try {
|
||||
Method cloneMethod = clazz.getMethod("clone", ArrayUtil.EMPTY_CLASS_ARRAY);
|
||||
|
||||
return cloneMethod.invoke(array, ArrayUtil.EMPTY_OBJECT_ARRAY);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
/* 比较对象的类型。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 检查两个对象是否属于相同类型。<code>null</code>将被看作任意类型。
|
||||
*
|
||||
* @param object1 对象1
|
||||
* @param object2 对象2
|
||||
*
|
||||
* @return 如果两个对象有相同的类型,则返回<code>true</code>
|
||||
*/
|
||||
public static boolean isSameType(Object object1, Object object2) {
|
||||
if ((object1 == null) || (object2 == null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return object1.getClass().equals(object2.getClass());
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
/* toString方法。 */
|
||||
/* ============================================================================ */
|
||||
|
||||
/**
|
||||
* 取得对象的<code>toString()</code>的值,如果对象为<code>null</code>,则返回空字符串<code>""</code>。
|
||||
* <pre>
|
||||
* ObjectUtil.toString(null) = ""
|
||||
* ObjectUtil.toString("") = ""
|
||||
* ObjectUtil.toString("bat") = "bat"
|
||||
* ObjectUtil.toString(Boolean.TRUE) = "true"
|
||||
* ObjectUtil.toString([1, 2, 3]) = "[1, 2, 3]"
|
||||
* </pre>
|
||||
*
|
||||
* @param object 对象
|
||||
*
|
||||
* @return 对象的<code>toString()</code>的返回值,或空字符串<code>""</code>
|
||||
*/
|
||||
public static String toString(Object object) {
|
||||
return (object == null) ? StringUtil.EMPTY_STRING
|
||||
: (object.getClass().isArray() ? ArrayUtil.toString(object) : object.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得对象的<code>toString()</code>的值,如果对象为<code>null</code>,则返回指定字符串。
|
||||
* <pre>
|
||||
* ObjectUtil.toString(null, null) = null
|
||||
* ObjectUtil.toString(null, "null") = "null"
|
||||
* ObjectUtil.toString("", "null") = ""
|
||||
* ObjectUtil.toString("bat", "null") = "bat"
|
||||
* ObjectUtil.toString(Boolean.TRUE, "null") = "true"
|
||||
* ObjectUtil.toString([1, 2, 3], "null") = "[1, 2, 3]"
|
||||
* </pre>
|
||||
*
|
||||
* @param object 对象
|
||||
* @param nullStr 如果对象为<code>null</code>,则返回该字符串
|
||||
*
|
||||
* @return 对象的<code>toString()</code>的返回值,或指定字符串
|
||||
*/
|
||||
public static String toString(Object object, String nullStr) {
|
||||
return (object == null) ? nullStr : (object.getClass().isArray() ? ArrayUtil
|
||||
.toString(object) : object.toString());
|
||||
}
|
||||
/**
|
||||
* 数字格式化方法 为thyleaf服务
|
||||
*
|
||||
* @param num
|
||||
* @return
|
||||
*/
|
||||
public static String toNum(Double num){
|
||||
java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");
|
||||
try{
|
||||
if(num == null){
|
||||
return "";
|
||||
}else{
|
||||
return df.format(num);
|
||||
}
|
||||
}catch(Exception e){
|
||||
return "" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class PropertiesUtil {
|
||||
|
||||
public static final ResourceBundle messageResource = ResourceBundle.getBundle("international.message", Locale.getDefault());
|
||||
|
||||
/**
|
||||
* 获取请求返回Code对应的Message
|
||||
* @param code
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
public static String getResponseErrorMessageByCode(int code, String...params) {
|
||||
if (messageResource == null) {
|
||||
return "";
|
||||
}
|
||||
String pStr = messageResource.getString("response.error." + code);
|
||||
if (StringUtils.isEmpty(pStr) || pStr == null) {
|
||||
return "";
|
||||
}
|
||||
if (params == null || params.length == 0) {
|
||||
return pStr;
|
||||
}
|
||||
MessageFormat format = new MessageFormat(pStr, Locale.getDefault());
|
||||
return format.format(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Key值获取Value
|
||||
* @param key
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
public static String getValueByKey(String key, String...params) {
|
||||
String pStr = messageResource.getString(key);
|
||||
if (messageResource == null) {
|
||||
return "";
|
||||
}
|
||||
if (StringUtils.isEmpty(pStr)) {
|
||||
return "";
|
||||
}
|
||||
if (params == null || params.length == 0) {
|
||||
return pStr;
|
||||
}
|
||||
MessageFormat format = new MessageFormat(pStr, Locale.getDefault());
|
||||
return format.format(params);
|
||||
}
|
||||
}
|
||||
40
fuint-utils/src/main/java/com/fuint/utils/QRCodeUtil.java
Normal file
40
fuint-utils/src/main/java/com/fuint/utils/QRCodeUtil.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* 二维码生成工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class QRCodeUtil {
|
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(QRCodeUtil.class);
|
||||
|
||||
/**
|
||||
* 保存二维码
|
||||
*
|
||||
* @param bytes
|
||||
* @return
|
||||
* */
|
||||
public static void saveQrCodeToLocal(byte[] bytes, String path) {
|
||||
try {
|
||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
FileOutputStream out = new FileOutputStream(path);
|
||||
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
out.flush();
|
||||
inputStream.close();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
15
fuint-utils/src/main/java/com/fuint/utils/RSAKeys.java
Normal file
15
fuint-utils/src/main/java/com/fuint/utils/RSAKeys.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.fuint.utils;
|
||||
/**
|
||||
* RSA公钥&私钥.
|
||||
* */
|
||||
public interface RSAKeys {
|
||||
/**
|
||||
* 公钥
|
||||
* */
|
||||
public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxtLcYtsxohITlqO24KehQgJlq9k43XdpbIgjQXOht9eA9ypJKSlo1WbJUrJrKPGZ+2iELGe7dOQDL4Q+q1RGOXbBNRFQFqi8HZTHOz/krcQIuZYt7wjDu2P09zvgIvS+N6LaYrT7jddx+vN+Nk/ZZMcg/3ks/HAg7fBnCr2VcbQIDAQAB";
|
||||
|
||||
/**
|
||||
* 私钥
|
||||
* */
|
||||
public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALG0txi2zGiEhOWo7bgp6FCAmWr2Tjdd2lsiCNBc6G314D3KkkpKWjVZslSsmso8Zn7aIQsZ7t05AMvhD6rVEY5dsE1EVAWqLwdlMc7P+StxAi5li3vCMO7Y/T3O+Ai9L43otpitPuN13H68342T9lkxyD/eSz8cCDt8GcKvZVxtAgMBAAECgYA+pbbmv4rQTeeMD0G+6wc7Whq72pk4a53PAvCYhChsm4GyRvfLuOqUZEq6Dx+CrEh17/A2Oa47zxy4w18CmprVPpdiM+mSUgcqMxVMJJSJPh5uuN3uw/6B6+NvD81gfDiwHrh5Irh2gJMTah52jMcguCce6OaZa6DG+jSYDaSPAQJBAOsuTAjEPxnpzRrbTZWGgoC9ftfXsdsZCu6wmKfDd2lWHf/Kf6+sNjWN6Hf1gG1tJVYpRS1o9e2yxTfPqrqJnZMCQQDBb+m0sb7Pz41S2mnk/STU4Z5GpeA4JJbbs+GSUzwfzZl9ZGMmJ1Ej1c+9n/BORgoGyrDDQrQPMidAyvR5gV3/AkBRfeBg5UeMPiSRGs6eclaEL6VlO1totRvBq7Wp5CRbfri0asGl6MF7+ylDb/FJeZmHapOK8aTN8bU+6pmZO5g7AkBMjIww3LJFLL6hjhuf6em8cPigvp3nudsVYK8gp93APC3EqIhwHdkHVGKciQGhCCiJnYasDuaQqOlNw8NRnjdjAkEAwh3THsHJArsSKmZYIM98+qgYpgQZVm7KNNxbKGu5IZPh0IV3NsxQYspE0cRBmzr3P3mAWPwPzh1sFHfFRw3UKQ==";
|
||||
}
|
||||
122
fuint-utils/src/main/java/com/fuint/utils/SeqUtil.java
Normal file
122
fuint-utils/src/main/java/com/fuint/utils/SeqUtil.java
Normal file
@ -0,0 +1,122 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 序列工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class SeqUtil {
|
||||
|
||||
/**
|
||||
* 产生字符串序列(长度:32)
|
||||
*
|
||||
* @return String 32位字符串序列
|
||||
*/
|
||||
public static String getUUID() {
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
return uuid.replaceAll("\\-", "").toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生日期序列(长度:32)
|
||||
* [yyyyMMddHHmmssSSS+15位随机数]
|
||||
*
|
||||
* @return Long
|
||||
*/
|
||||
public static BigInteger getTimeSeq() {
|
||||
String date = CommonUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(date);
|
||||
int length = 32 - sb.length();
|
||||
String randNum = getRandomNumber(length);
|
||||
sb.append(randNum);
|
||||
return new BigInteger(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生日期序列(长度:大于17位)
|
||||
* [yyyyMMddHHmmssSSS+15位随机数]
|
||||
*
|
||||
* @return Long
|
||||
*/
|
||||
public static String getTimeSeq(int length) {
|
||||
String date = CommonUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(date);
|
||||
length = length - sb.length();
|
||||
if (length > 0) {
|
||||
String randNum = getRandomNumber(length);
|
||||
sb.append(randNum);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据客户自定义前缀获取序列(长度:32)
|
||||
* [前缀+yyyyMMddHHmmssSSS+随机数]
|
||||
*
|
||||
* @param prefix
|
||||
* @return String
|
||||
*/
|
||||
public static String getCustSeq(String prefix) {
|
||||
String date = CommonUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS");
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
sb.append(date);
|
||||
int length = 32 - sb.length();
|
||||
String randNum = getRandomNumber(length);
|
||||
sb.append(randNum);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生指定长度随机字母
|
||||
*
|
||||
* @param length
|
||||
* @return String
|
||||
*/
|
||||
public static String getRandomLetter(int length) {
|
||||
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
int rang = 26;
|
||||
ThreadLocalRandom rand = ThreadLocalRandom.current();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(base.charAt(rand.nextInt(rang)));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生指定长度随机数字
|
||||
*
|
||||
* @param length
|
||||
* @return String
|
||||
*/
|
||||
public static String getRandomNumber(int length) {
|
||||
String base = "0123456789";
|
||||
int rang = 10;
|
||||
ThreadLocalRandom rand = ThreadLocalRandom.current();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(base.charAt(rand.nextInt(rang)));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生指定区间的随机整数
|
||||
*
|
||||
* @param min
|
||||
* @param max
|
||||
* @return int
|
||||
*/
|
||||
public static int getRandomNumber(int min, int max) {
|
||||
ThreadLocalRandom rand = ThreadLocalRandom.current();
|
||||
return rand.nextInt(min, max);
|
||||
}
|
||||
}
|
||||
4210
fuint-utils/src/main/java/com/fuint/utils/StringUtil.java
Normal file
4210
fuint-utils/src/main/java/com/fuint/utils/StringUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
82
fuint-utils/src/main/java/com/fuint/utils/TimeUtils.java
Normal file
82
fuint-utils/src/main/java/com/fuint/utils/TimeUtils.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 时间相关的工具类
|
||||
*
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class TimeUtils {
|
||||
/**
|
||||
* 日期转换为时间戳,时间戳为秒
|
||||
*
|
||||
* @param day
|
||||
* @param format
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static int date2timeStamp(String day, String format) {
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return Integer.parseInt("" + sdf.parse(day).getTime() / 1000);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int date2timeStamp(Date date){
|
||||
return Integer.parseInt("" + date.getTime()/1000);
|
||||
}
|
||||
/**
|
||||
* 时间戳(秒)转换为字符日期
|
||||
*
|
||||
* @param seconds
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String timeStamp2Date(int seconds, String format) {
|
||||
if (seconds == 0) {
|
||||
return null;
|
||||
}
|
||||
if (format == null || format.isEmpty()) {
|
||||
format = "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return sdf.format(new Date(Long.valueOf(seconds + "000")));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前系统时间戳(秒)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int timeStamp() {
|
||||
return Integer.parseInt(System.currentTimeMillis() / 1000 + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定日期是否在起始日期区间内
|
||||
*
|
||||
* @param startDate
|
||||
* @param endDate
|
||||
* @param date
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isSection(Date startDate, Date endDate, Date date) {
|
||||
if (startDate.getTime() <= date.getTime() && endDate.getTime() >= date.getTime()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatDate(Date date, String format){
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return sdf.format(date);
|
||||
}
|
||||
}
|
||||
138
fuint-utils/src/main/java/com/fuint/utils/ValidationUtil.java
Normal file
138
fuint-utils/src/main/java/com/fuint/utils/ValidationUtil.java
Normal file
@ -0,0 +1,138 @@
|
||||
package com.fuint.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 校验工具类
|
||||
*
|
||||
* 统一返回值: true-校验成功(合法) false-校验失败(非法)
|
||||
* Created by FSQ
|
||||
* CopyRight https://www.fuint.cn
|
||||
*/
|
||||
public class ValidationUtil {
|
||||
|
||||
public static boolean isNumeric(String str){
|
||||
Pattern pattern = Pattern.compile("[0-9]*");
|
||||
Matcher isNum = pattern.matcher(str);
|
||||
if ( !isNum.matches() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 空校验
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateEmpty(String param) {
|
||||
return !StringUtils.isEmpty(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 长度校验
|
||||
*
|
||||
* @param param
|
||||
* @param minLen
|
||||
* @param maxLen
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateLength(String param, int minLen, int maxLen) {
|
||||
if (StringUtils.isEmpty(param)) param = "";
|
||||
return param.length() >= minLen && param.length() <= maxLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码格式校验
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static boolean validatePwdPattern(String param) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
String check = "^(?![^a-zA-Z]+$)(?!\\D+$).{6,20}$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(param);
|
||||
flag = matcher.matches();
|
||||
} catch (Exception e) {
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验手机号
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateMobile(String param) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
String check = "^[1][3,4,5,7,8][0-9]{9}$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(param);
|
||||
flag = matcher.matches();
|
||||
} catch (Exception e) {
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验邮箱
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateEmail(String param) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(param);
|
||||
flag = matcher.matches();
|
||||
} catch (Exception e) {
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验身份证号
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateIdCard(String param) {
|
||||
if (StringUtils.isEmpty(param)) return false;
|
||||
IDCard iv = new IDCard();
|
||||
return iv.isValidatedAllIdcard(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验Url
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateUrl(String param) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
String check = "^(http|https|ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&%\\$\\-]+)*@)?((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.[a-zA-Z]{2,4})(\\:[0-9]+)?(/[^/][a-zA-Z0-9\\.\\,\\?\\'\\\\/\\+&%\\$#\\=~_\\-@]*)*$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(param);
|
||||
flag = matcher.matches();
|
||||
} catch (Exception e) {
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static boolean isInteger(String str) {
|
||||
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
|
||||
return pattern.matcher(str).matches();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user