Commit 3647b776 by stylefeng

抽象出工具类和异常

parent 461f2460
......@@ -15,6 +15,30 @@
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
package com.stylefeng;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
package com.stylefeng.guns.core.exception;
/**
* @Description 业务异常的封装
* @author fengshuonan
* @date 2016年11月12日 下午5:05:10
*/
@SuppressWarnings("serial")
public class GunsException extends RuntimeException{
//友好提示的code码
private int friendlyCode;
//友好提示
private String friendlyMsg;
//业务异常跳转的页面
private String urlPath;
public GunsException(GunsExceptionEnum bizExceptionEnum){
this.friendlyCode = bizExceptionEnum.getCode();
this.friendlyMsg = bizExceptionEnum.getMessage();
this.urlPath = bizExceptionEnum.getUrlPath();
}
public int getCode() {
return friendlyCode;
}
public void setCode(int code) {
this.friendlyCode = code;
}
public String getMessage() {
return friendlyMsg;
}
public void setMessage(String message) {
this.friendlyMsg = message;
}
public String getUrlPath() {
return urlPath;
}
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
}
package com.stylefeng.guns.core.exception;
/**
* @Description 所有业务异常的枚举
* @author fengshuonan
* @date 2016年11月12日 下午5:04:51
*/
public enum GunsExceptionEnum {
/**
* 文件上传
*/
FILE_READING_ERROR(400,"FILE_READING_ERROR!"),
FILE_NOT_FOUND(400,"FILE_NOT_FOUND!"),
/**
* 错误的请求
*/
REQUEST_NULL(400, "请求有错误"),
SERVER_ERROR(500, "服务器异常");
GunsExceptionEnum(int code, String message) {
this.friendlyCode = code;
this.friendlyMsg = message;
}
GunsExceptionEnum(int code, String message, String urlPath) {
this.friendlyCode = code;
this.friendlyMsg = message;
this.urlPath = urlPath;
}
private int friendlyCode;
private String friendlyMsg;
private String urlPath;
public int getCode() {
return friendlyCode;
}
public void setCode(int code) {
this.friendlyCode = code;
}
public String getMessage() {
return friendlyMsg;
}
public void setMessage(String message) {
this.friendlyMsg = message;
}
public String getUrlPath() {
return urlPath;
}
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
}
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.core.util.support.*;
import com.stylefeng.guns.core.util.support.exception.ToolBoxException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Set;
/**
* 类型转换器
*
* @author xiaoleilu
*
*/
public class Convert {
private Convert() {
// 静态类不可实例化
}
/**
* 强制转换类型
*
* @param clazz 被转换成的类型
* @param value 需要转换的对象
* @return 转换后的对象
*/
public static Object parse(Class<?> clazz, Object value) {
try {
if (clazz.isAssignableFrom(String.class)) {
// ----2016-12-19---zhuangqian----防止beetlsql对空字符串不检测导致无法入库的问题----
if (StrKit.isBlank(String.valueOf(value)))
return " ";
else
return String.valueOf(value);
}
return clazz.cast(value);
} catch (ClassCastException e) {
String valueStr = String.valueOf(value);
Object result = parseBasic(clazz, valueStr);
if (result != null) {
return result;
}
if (Date.class.isAssignableFrom(clazz)) {
// 判断标准日期
// ----2016-11-24---zhuangqian----需要加toDate(),不然beetlsql转换date类型的时候会报错----
return DateTimeKit.parse(valueStr).toDate();
} else if (clazz == BigInteger.class) {
// 数学计算数字
return new BigInteger(valueStr);
} else if (clazz == BigDecimal.class) {
// 数学计算数字
return new BigDecimal(valueStr);
} else if (clazz == byte[].class) {
// 流,由于有字符编码问题,在此使用系统默认
return valueStr.getBytes();
}
// 未找到可转换的类型,返回原值
return (StrKit.isBlank(valueStr)) ? null : value;
}
}
/**
* 转换基本类型<br>
* 将字符串转换为原始类型或包装类型
*
* @param clazz 转换到的类,可以是原始类型类,也可以是包装类型类
* @param valueStr 被转换的字符串
* @return 转换后的对象,如果非基本类型,返回null
*/
public static Object parseBasic(Class<?> clazz, String valueStr) {
if (null == clazz || null == valueStr) {
return null;
}
if (StrKit.isBlank(valueStr)) return null;
BasicType basicType = null;
try {
basicType = BasicType.valueOf(clazz.getSimpleName().toUpperCase());
} catch (Exception e) {
// 非基本类型数据
return null;
}
switch (basicType) {
case BYTE:
if (clazz == byte.class) {
return Byte.parseByte(valueStr);
}
return Byte.valueOf(valueStr);
case SHORT:
if (clazz == short.class) {
return Short.parseShort(valueStr);
}
return Short.valueOf(valueStr);
case INT:
return Integer.parseInt(valueStr);
case INTEGER:
return Integer.valueOf(valueStr);
case LONG:
if (clazz == long.class) {
return new BigDecimal(valueStr).longValue();
}
return Long.valueOf(valueStr);
case DOUBLE:
if (clazz == double.class) {
return new BigDecimal(valueStr).doubleValue();
}
case FLOAT:
if (clazz == float.class) {
return Float.parseFloat(valueStr);
}
return Float.valueOf(valueStr);
case BOOLEAN:
if (clazz == boolean.class) {
return Boolean.parseBoolean(valueStr);
}
return Boolean.valueOf(valueStr);
case CHAR:
return valueStr.charAt(0);
case CHARACTER:
return Character.valueOf(valueStr.charAt(0));
default:
return null;
}
}
/**
* 转换为字符串<br>
* 如果给定的值为null,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static String toStr(Object value, String defaultValue) {
if (null == value) {
return defaultValue;
}
if (value instanceof String) {
return (String) value;
} else if (CollectionKit.isArray(value)) {
return CollectionKit.toString(value);
}
return value.toString();
}
/**
* 转换为字符串<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static String toStr(Object value) {
return toStr(value, null);
}
/**
* 转换为字符<br>
* 如果给定的值为null,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Character toChar(Object value, Character defaultValue) {
if (null == value) {
return defaultValue;
}
if (value instanceof Character) {
return (Character) value;
}
final String valueStr = toStr(value, null);
return StrKit.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
}
/**
* 转换为字符<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Character toChar(Object value) {
return toChar(value, null);
}
/**
* 转换为byte<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Byte toByte(Object value, Byte defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Byte) {
return (Byte) value;
}
if (value instanceof Number) {
return ((Number) value).byteValue();
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return Byte.parseByte(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为byte<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Byte toByte(Object value) {
return toByte(value, null);
}
/**
* 转换为Short<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Short toShort(Object value, Short defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Short) {
return (Short) value;
}
if (value instanceof Number) {
return ((Number) value).shortValue();
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return Short.parseShort(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为Short<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Short toShort(Object value) {
return toShort(value, null);
}
/**
* 转换为Number<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Number toNumber(Object value, Number defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Number) {
return (Number) value;
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return NumberFormat.getInstance().parse(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为Number<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Number toNumber(Object value) {
return toNumber(value, null);
}
/**
* 转换为int<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Integer toInt(Object value, Integer defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Integer) {
return (Integer) value;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return Integer.parseInt(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为int<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Integer toInt(Object value) {
return toInt(value, null);
}
/**
* 转换为Integer数组<br>
*
* @param isIgnoreConvertError 是否忽略转换错误,忽略则给值null
* @param values 被转换的值
* @return 结果
*/
public static Integer[] toIntArray(boolean isIgnoreConvertError, Object... values) {
if (CollectionKit.isEmpty(values)) {
return new Integer[] {};
}
final Integer[] ints = new Integer[values.length];
for (int i = 0; i < values.length; i++) {
final Integer v = toInt(values[i], null);
if (null == v && isIgnoreConvertError == false) {
throw new ToolBoxException(StrKit.format("Convert [{}] to Integer error!", values[i]));
}
ints[i] = v;
}
return ints;
}
/**
* 转换为Integer数组<br>
*
* @param split 被转换的值
* @return 结果
*/
public static Integer[] toIntArray(String str) {
return toIntArray(",", str);
}
/**
* 转换为Integer数组<br>
*
* @param split 分隔符
* @param split 被转换的值
* @return 结果
*/
public static Integer[] toIntArray(String split, String str) {
if (StrKit.isEmpty(str)) {
return new Integer[] {};
}
String[] arr = str.split(split);
final Integer[] ints = new Integer[arr.length];
for (int i = 0; i < arr.length; i++) {
final Integer v = toInt(arr[i], 0);
ints[i] = v;
}
return ints;
}
/**
* 转换为String数组<br>
*
* @param split 被转换的值
* @return 结果
*/
public static String[] toStrArray(String str) {
return toStrArray("", str);
}
/**
* 转换为String数组<br>
*
* @param split 分隔符
* @param split 被转换的值
* @return 结果
*/
public static String[] toStrArray(String split, String str) {
return str.split(split);
}
/**
* 转换为long<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Long toLong(Object value, Long defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Long) {
return (Long) value;
}
if (value instanceof Number) {
return ((Number) value).longValue();
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
// 支持科学计数法
return new BigDecimal(valueStr.trim()).longValue();
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为long<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Long toLong(Object value) {
return toLong(value, null);
}
/**
* 转换为Long数组<br>
*
* @param isIgnoreConvertError 是否忽略转换错误,忽略则给值null
* @param values 被转换的值
* @return 结果
*/
public static Long[] toLongArray(boolean isIgnoreConvertError, Object... values) {
if (CollectionKit.isEmpty(values)) {
return new Long[] {};
}
final Long[] longs = new Long[values.length];
for (int i = 0; i < values.length; i++) {
final Long v = toLong(values[i], null);
if (null == v && isIgnoreConvertError == false) {
throw new ToolBoxException(StrKit.format("Convert [{}] to Long error!", values[i]));
}
longs[i] = v;
}
return longs;
}
/**
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Double toDouble(Object value, Double defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Double) {
return (Double) value;
}
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
// 支持科学计数法
return new BigDecimal(valueStr.trim()).doubleValue();
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Double toDouble(Object value) {
return toDouble(value, null);
}
/**
* 转换为Double数组<br>
*
* @param isIgnoreConvertError 是否忽略转换错误,忽略则给值null
* @param values 被转换的值
* @return 结果
*/
public static Double[] toDoubleArray(boolean isIgnoreConvertError, Object... values) {
if (CollectionKit.isEmpty(values)) {
return new Double[] {};
}
final Double[] doubles = new Double[values.length];
for (int i = 0; i < values.length; i++) {
final Double v = toDouble(values[i], null);
if (null == v && isIgnoreConvertError == false) {
throw new ToolBoxException(StrKit.format("Convert [{}] to Double error!", values[i]));
}
doubles[i] = v;
}
return doubles;
}
/**
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Float toFloat(Object value, Float defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Float) {
return (Float) value;
}
if (value instanceof Number) {
return ((Number) value).floatValue();
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return Float.parseFloat(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Float toFloat(Object value) {
return toFloat(value, null);
}
/**
* 转换为Float数组<br>
*
* @param isIgnoreConvertError 是否忽略转换错误,忽略则给值null
* @param values 被转换的值
* @return 结果
*/
public static <T> Float[] toFloatArray(boolean isIgnoreConvertError, Object... values) {
if (CollectionKit.isEmpty(values)) {
return new Float[] {};
}
final Float[] floats = new Float[values.length];
for (int i = 0; i < values.length; i++) {
final Float v = toFloat(values[i], null);
if (null == v && isIgnoreConvertError == false) {
throw new ToolBoxException(StrKit.format("Convert [{}] to Float error!", values[i]));
}
floats[i] = v;
}
return floats;
}
/**
* 转换为boolean<br>
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Boolean toBool(Object value, Boolean defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Boolean) {
return (Boolean) value;
}
String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
valueStr = valueStr.trim().toLowerCase();
switch (valueStr) {
case "true":
return true;
case "false":
return false;
case "yes":
return true;
case "ok":
return true;
case "no":
return false;
case "1":
return true;
case "0":
return false;
default:
return defaultValue;
}
}
/**
* 转换为boolean<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Boolean toBool(Object value) {
return toBool(value, null);
}
/**
* 转换为Boolean数组<br>
*
* @param isIgnoreConvertError 是否忽略转换错误,忽略则给值null
* @param values 被转换的值
* @return 结果
*/
public static Boolean[] toBooleanArray(boolean isIgnoreConvertError, Object... values) {
if (CollectionKit.isEmpty(values)) {
return new Boolean[] {};
}
final Boolean[] bools = new Boolean[values.length];
for (int i = 0; i < values.length; i++) {
final Boolean v = toBool(values[i], null);
if (null == v && isIgnoreConvertError == false) {
throw new ToolBoxException(StrKit.format("Convert [{}] to Boolean error!", values[i]));
}
bools[i] = v;
}
return bools;
}
/**
* 转换为Enum对象<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
*
* @param clazz Enum的Class
* @param value 值
* @param defaultValue 默认值
* @return Enum
*/
public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) {
if (value == null) {
return defaultValue;
}
if (clazz.isAssignableFrom(value.getClass())) {
@SuppressWarnings("unchecked")
E myE = (E) value;
return myE;
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return Enum.valueOf(clazz, valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为Enum对象<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
*
* @param clazz Enum的Class
* @param value 值
* @return Enum
*/
public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) {
return toEnum(clazz, value, null);
}
/**
* 转换为BigInteger<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static BigInteger toBigInteger(Object value, BigInteger defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof BigInteger) {
return (BigInteger) value;
}
if (value instanceof Long) {
return BigInteger.valueOf((Long) value);
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return new BigInteger(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为BigInteger<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static BigInteger toBigInteger(Object value) {
return toBigInteger(value, null);
}
/**
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof BigDecimal) {
return (BigDecimal) value;
}
if (value instanceof Long) {
return new BigDecimal((Long) value);
}
if (value instanceof Double) {
return new BigDecimal((Double) value);
}
if (value instanceof Integer) {
return new BigDecimal((Integer) value);
}
final String valueStr = toStr(value, null);
if (StrKit.isBlank(valueStr)) {
return defaultValue;
}
try {
return new BigDecimal(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static BigDecimal toBigDecimal(Object value) {
return toBigDecimal(value, null);
}
// ----------------------------------------------------------------------- 全角半角转换
/**
* 半角转全角
*
* @param input String.
* @return 全角字符串.
*/
public static String toSBC(String input) {
return toSBC(input, null);
}
/**
* 半角转全角
*
* @param input String
* @param notConvertSet 不替换的字符集合
* @return 全角字符串.
*/
public static String toSBC(String input, Set<Character> notConvertSet) {
char c[] = input.toCharArray();
for (int i = 0; i < c.length; i++) {
if (null != notConvertSet && notConvertSet.contains(c[i])) {
// 跳过不替换的字符
continue;
}
if (c[i] == ' ') {
c[i] = '\u3000';
} else if (c[i] < '\177') {
c[i] = (char) (c[i] + 65248);
}
}
return new String(c);
}
/**
* 全角转半角
*
* @param input String.
* @return 半角字符串
*/
public static String toDBC(String input) {
return toDBC(input, null);
}
/**
* 替换全角为半角
*
* @param text 文本
* @param notConvertSet 不替换的字符集合
* @return 替换后的字符
*/
public static String toDBC(String text, Set<Character> notConvertSet) {
char c[] = text.toCharArray();
for (int i = 0; i < c.length; i++) {
if (null != notConvertSet && notConvertSet.contains(c[i])) {
// 跳过不替换的字符
continue;
}
if (c[i] == '\u3000') {
c[i] = ' ';
} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
c[i] = (char) (c[i] - 65248);
}
}
String returnString = new String(c);
return returnString;
}
// --------------------------------------------------------------------- hex
/**
* 字符串转换成十六进制字符串
*
* @param str 待转换的ASCII字符串
* @return 16进制字符串
*/
public static String toHex(String str) {
return HexKit.encodeHexStr(str.getBytes());
}
/**
* byte数组转16进制串
*
* @param bytes 被转换的byte数组
* @return 转换后的值
*/
public static String toHex(byte[] bytes) {
return HexKit.encodeHexStr(bytes);
}
/**
* Hex字符串转换为Byte值
*
* @param src Byte字符串,每个Byte之间没有分隔符
* @return byte[]
*/
public static byte[] hexToBytes(String src) {
return HexKit.decodeHex(src.toCharArray());
}
/**
* 十六进制转换字符串
*
* @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
* @param charset 编码 {@link Charset}
* @return 对应的字符串
*/
public static String hexStrToStr(String hexStr, Charset charset) {
return HexKit.decodeHexStr(hexStr, charset);
}
/**
* String的字符串转换成unicode的String
*
* @param strText 全角字符串
* @return String 每个unicode之间无分隔符
* @throws Exception
*/
public static String strToUnicode(String strText) throws Exception {
char c;
StringBuilder str = new StringBuilder();
int intAsc;
String strHex;
for (int i = 0; i < strText.length(); i++) {
c = strText.charAt(i);
intAsc = (int) c;
strHex = Integer.toHexString(intAsc);
if (intAsc > 128)
str.append("\\u" + strHex);
else // 低位在前面补00
str.append("\\u00" + strHex);
}
return str.toString();
}
/**
* unicode的String转换成String的字符串
*
* @param hex 16进制值字符串 (一个unicode为2byte)
* @return String 全角字符串
*/
public static String unicodeToStr(String hex) {
int t = hex.length() / 6;
StringBuilder str = new StringBuilder();
for (int i = 0; i < t; i++) {
String s = hex.substring(i * 6, (i + 1) * 6);
// 高位需要补上00再转
String s1 = s.substring(2, 4) + "00";
// 低位直接转
String s2 = s.substring(4);
// 将16进制的string转为int
int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
// 将int转换为字符
char[] chars = Character.toChars(n);
str.append(new String(chars));
}
return str.toString();
}
/**
* 给定字符串转换字符编码<br/>
* 如果参数为空,则返回原字符串,不报错。
*
* @param str 被转码的字符串
* @param sourceCharset 原字符集
* @param destCharset 目标字符集
* @return 转换后的字符串
*/
public static String convertCharset(String str, String sourceCharset, String destCharset) {
if (StrKit.hasBlank(str, sourceCharset, destCharset)) {
return str;
}
try {
return new String(str.getBytes(sourceCharset), destCharset);
} catch (UnsupportedEncodingException e) {
return str;
}
}
/**
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
*
* @param n 数字
* @return 中文大写数字
*/
public static String digitUppercase(double n) {
String fraction[] = { "角", "分" };
String digit[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
String unit[][] = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };
String head = n < 0 ? "负" : "";
n = Math.abs(n);
String s = "";
for (int i = 0; i < fraction.length; i++) {
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
}
if (s.length() < 1) {
s = "整";
}
int integerPart = (int) Math.floor(n);
for (int i = 0; i < unit[0].length && integerPart > 0; i++) {
String p = "";
for (int j = 0; j < unit[1].length && n > 0; j++) {
p = digit[integerPart % 10] + unit[1][j] + p;
integerPart = integerPart / 10;
}
s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
}
return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
}
}
/**
* Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
/**
* 获取YYYY格式
*
* @return
*/
public static String getYear() {
return formatDate(new Date(), "yyyy");
}
/**
* 获取YYYY格式
*
* @return
*/
public static String getYear(Date date) {
return formatDate(date, "yyyy");
}
/**
* 获取YYYY-MM-DD格式
*
* @return
*/
public static String getDay() {
return formatDate(new Date(), "yyyy-MM-dd");
}
/**
* 获取YYYY-MM-DD格式
*
* @return
*/
public static String getDay(Date date) {
return formatDate(date, "yyyy-MM-dd");
}
/**
* 获取YYYYMMDD格式
*
* @return
*/
public static String getDays() {
return formatDate(new Date(), "yyyyMMdd");
}
/**
* 获取YYYYMMDD格式
*
* @return
*/
public static String getDays(Date date) {
return formatDate(date, "yyyyMMdd");
}
/**
* 获取YYYY-MM-DD HH:mm:ss格式
*
* @return
*/
public static String getTime() {
return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
}
/**
* 获取YYYY-MM-DD HH:mm:ss.SSS格式
*
* @return
*/
public static String getMsTime() {
return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
}
/**
* 获取YYYYMMDDHHmmss格式
*
* @return
*/
public static String getAllTime() {
return formatDate(new Date(), "yyyyMMddHHmmss");
}
/**
* 获取YYYY-MM-DD HH:mm:ss格式
*
* @return
*/
public static String getTime(Date date) {
return formatDate(date, "yyyy-MM-dd HH:mm:ss");
}
public static String formatDate(Date date, String pattern) {
String formatDate = null;
if (StringUtils.isNotBlank(pattern)) {
formatDate = DateFormatUtils.format(date, pattern);
} else {
formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
}
return formatDate;
}
/**
* @Title: compareDate
* @Description:(日期比较,如果s>=e 返回true 否则返回false)
* @param s
* @param e
* @return boolean
* @throws
* @author luguosui
*/
public static boolean compareDate(String s, String e) {
if (parseDate(s) == null || parseDate(e) == null) {
return false;
}
return parseDate(s).getTime() >= parseDate(e).getTime();
}
/**
* 格式化日期
*
* @return
*/
public static Date parseDate(String date) {
return parse(date,"yyyy-MM-dd");
}
/**
* 格式化日期
*
* @return
*/
public static Date parseTime(String date) {
return parse(date,"yyyy-MM-dd HH:mm:ss");
}
/**
* 格式化日期
*
* @return
*/
public static Date parse(String date, String pattern) {
try {
return DateUtils.parseDate(date,pattern);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* 格式化日期
*
* @return
*/
public static String format(Date date, String pattern) {
return DateFormatUtils.format(date, pattern);
}
/**
* 把日期转换为Timestamp
*
* @param date
* @return
*/
public static Timestamp format(Date date) {
return new Timestamp(date.getTime());
}
/**
* 校验日期是否合法
*
* @return
*/
public static boolean isValidDate(String s) {
return parse(s, "yyyy-MM-dd HH:mm:ss") != null;
}
/**
* 校验日期是否合法
*
* @return
*/
public static boolean isValidDate(String s, String pattern) {
return parse(s, pattern) != null;
}
public static int getDiffYear(String startTime, String endTime) {
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
try {
int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(
startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
return years;
} catch (Exception e) {
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
return 0;
}
}
/**
* <li>功能描述:时间相减得到天数
*
* @param beginDateStr
* @param endDateStr
* @return long
* @author Administrator
*/
public static long getDaySub(String beginDateStr, String endDateStr) {
long day = 0;
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd");
Date beginDate = null;
Date endDate = null;
try {
beginDate = format.parse(beginDateStr);
endDate = format.parse(endDateStr);
} catch (ParseException e) {
e.printStackTrace();
}
day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
// System.out.println("相隔的天数="+day);
return day;
}
/**
* 得到n天之后的日期
*
* @param days
* @return
*/
public static String getAfterDayDate(String days) {
int daysInt = Integer.parseInt(days);
Calendar canlendar = Calendar.getInstance(); // java.util包
canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
Date date = canlendar.getTime();
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdfd.format(date);
return dateStr;
}
/**
* 得到n天之后是周几
*
* @param days
* @return
*/
public static String getAfterDayWeek(String days) {
int daysInt = Integer.parseInt(days);
Calendar canlendar = Calendar.getInstance(); // java.util包
canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
Date date = canlendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("E");
String dateStr = sdf.format(date);
return dateStr;
}
/**
* 格式化Oracle Date
* @param value
* @return
*/
// public static String buildDateValue(Object value){
// if(Func.isOracle()){
// return "to_date('"+ value +"','yyyy-mm-dd HH24:MI:SS')";
// }else{
// return Func.toStr(value);
// }
// }
public static void main(String[] args) {
System.out.println(getTime(new Date()));
System.out.println(getAfterDayWeek("3"));
}
}
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.core.exception.GunsExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FileUtil {
private static Logger log = LoggerFactory.getLogger(FileUtil.class);
/**
* NIO way
*/
public static byte[] toByteArray(String filename) {
File f = new File(filename);
if (!f.exists()) {
log.error("文件未找到!" + filename);
throw new GunsException(GunsExceptionEnum.FILE_NOT_FOUND);
}
FileChannel channel = null;
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
channel = fs.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
while ((channel.read(byteBuffer)) > 0) {
// do nothing
// System.out.println("reading");
}
return byteBuffer.array();
} catch (IOException e) {
throw new GunsException(GunsExceptionEnum.FILE_READING_ERROR);
} finally {
try {
channel.close();
} catch (IOException e) {
throw new GunsException(GunsExceptionEnum.FILE_READING_ERROR);
}
try {
fs.close();
} catch (IOException e) {
throw new GunsException(GunsExceptionEnum.FILE_READING_ERROR);
}
}
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util;
import javax.servlet.http.HttpSession;
/**
* 非Controller中获取当前session的工具类
*
* @author fengshuonan
* @date 2016年11月28日 上午10:24:31
*/
public class HttpSessionHolder {
private static ThreadLocal<HttpSession> tl = new ThreadLocal<HttpSession>();
public static void put(HttpSession s) {
tl.set(s);
}
public static HttpSession get() {
return tl.get();
}
public static void remove() {
tl.remove();
}
}
package com.stylefeng.guns.core.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* MD5加密类(封装jdk自带的md5加密方法)
*
* @author fengshuonan
* @date 2016年12月2日 下午4:14:22
*/
public class MD5Util {
public static String encrypt(String source) {
return encodeMd5(source.getBytes());
}
private static String encodeMd5(byte[] source) {
try {
return encodeHex(MessageDigest.getInstance("MD5").digest(source));
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
private static String encodeHex(byte[] bytes) {
StringBuffer buffer = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
if (((int) bytes[i] & 0xff) < 0x10)
buffer.append("0");
buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buffer.toString();
}
public static void main(String[] args) {
System.out.println(encrypt("123456"));
}
}
package com.stylefeng.guns.core.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/**
* 数字格式化的类
*
* @author fengshuonan
* @date 2016年11月30日 下午5:58:40
*/
public class NumUtil {
/**
* @Description 保留指定位数的小数(少的位数不补零)
* @author fengshuonan
*/
public static String keepRandomPoint(Double value, int n) {
if (value == null) {
value = 0.00;
return new BigDecimal(value).setScale(n, RoundingMode.HALF_UP).toString();
} else {
return new BigDecimal(value).setScale(n, RoundingMode.HALF_UP).toString();
}
}
/**
* @Description 浮点保留两位小数(少的位数不补零)
* @author fengshuonan
*/
public static String keep2Point(double value) {
return keepRandomPoint(value, 2);
}
/**
* @Description 浮点保留1位小数(少的位数不补零)
* @author fengshuonan
*/
public static String keep1Point(double value) {
return keepRandomPoint(value, 1);
}
/**
* @Description 浮点保留任意位小数(少位补零)
* @author fengshuonan
*/
public static String keepRandomPointZero(double value, int n) {
DecimalFormat df = new DecimalFormat("#0.00");
return df.format(Double.valueOf(keepRandomPoint(value, n)));
}
/**
* @Description 浮点保留两位小数(少位补零)
* @author fengshuonan
*/
public static String keep2PointZero(double value) {
return keepRandomPointZero(value, 2);
}
/**
* @Description 获取任意小数点位的百分比表示
* @author fengshuonan
*/
public static String percentRandomPoint(double value, int n) {
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setGroupingUsed(false);
percent.setMaximumFractionDigits(n);
return percent.format(value);
}
/**
* @Description 百分比保留两位小数
* @author fengshuonan
*/
public static String percent2Point(double value) {
return percentRandomPoint(value, 2);
}
/**
* @Description 获取格式化经纬度后的小数(保留3位)
* @author fengshuonan
*/
public static String latLngPoint(double value) {
return keepRandomPoint(value, 3);
}
}
package com.stylefeng.guns.core.util;
import java.util.Random;
/***
*
* 得到中文首字母
*
* @author lxm_09
*
*/
public class PingYinUtil {
public static void main(String[] args) {
String str = "这是一个测试";
System.out.println("中文首字母:" + getPYIndexStr(str, true));
}
/**
* 返回首字母
*/
public static String getPYIndexStr(String strChinese, boolean bUpCase) {
try {
StringBuffer buffer = new StringBuffer();
byte b[] = strChinese.getBytes("GBK");// 把中文转化成byte数组
for (int i = 0; i < b.length; i++) {
if ((b[i] & 255) > 128) {
int char1 = b[i++] & 255;
char1 <<= 8;// 左移运算符用“<<”表示,是将运算符左边的对象,向左移动运算符右边指定的位数,并且在低位补零。其实,向左移n位,就相当于乘上2的n次方
int chart = char1 + (b[i] & 255);
buffer.append(getPYIndexChar((char) chart, bUpCase));
continue;
}
char c = (char) b[i];
if (!Character.isJavaIdentifierPart(c))// 确定指定字符是否可以是 Java
// 标识符中首字符以外的部分。
c = 'A';
buffer.append(c);
}
return buffer.toString();
} catch (Exception e) {
System.out.println((new StringBuilder()).append("\u53D6\u4E2D\u6587\u62FC\u97F3\u6709\u9519")
.append(e.getMessage()).toString());
}
return null;
}
/**
* 得到首字母
*/
private static char getPYIndexChar(char strChinese, boolean bUpCase) {
int charGBK = strChinese;
char result;
if (charGBK >= 45217 && charGBK <= 45252)
result = 'A';
else
if (charGBK >= 45253 && charGBK <= 45760)
result = 'B';
else
if (charGBK >= 45761 && charGBK <= 46317)
result = 'C';
else
if (charGBK >= 46318 && charGBK <= 46825)
result = 'D';
else
if (charGBK >= 46826 && charGBK <= 47009)
result = 'E';
else
if (charGBK >= 47010 && charGBK <= 47296)
result = 'F';
else
if (charGBK >= 47297 && charGBK <= 47613)
result = 'G';
else
if (charGBK >= 47614 && charGBK <= 48118)
result = 'H';
else
if (charGBK >= 48119 && charGBK <= 49061)
result = 'J';
else
if (charGBK >= 49062 && charGBK <= 49323)
result = 'K';
else
if (charGBK >= 49324 && charGBK <= 49895)
result = 'L';
else
if (charGBK >= 49896 && charGBK <= 50370)
result = 'M';
else
if (charGBK >= 50371 && charGBK <= 50613)
result = 'N';
else
if (charGBK >= 50614 && charGBK <= 50621)
result = 'O';
else
if (charGBK >= 50622 && charGBK <= 50905)
result = 'P';
else
if (charGBK >= 50906 && charGBK <= 51386)
result = 'Q';
else
if (charGBK >= 51387 && charGBK <= 51445)
result = 'R';
else
if (charGBK >= 51446 && charGBK <= 52217)
result = 'S';
else
if (charGBK >= 52218 && charGBK <= 52697)
result = 'T';
else
if (charGBK >= 52698 && charGBK <= 52979)
result = 'W';
else
if (charGBK >= 52980 && charGBK <= 53688)
result = 'X';
else
if (charGBK >= 53689 && charGBK <= 54480)
result = 'Y';
else
if (charGBK >= 54481 && charGBK <= 55289)
result = 'Z';
else
result = (char) (65 + (new Random()).nextInt(25));
if (!bUpCase)
result = Character.toLowerCase(result);
return result;
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException;
/**
* 资源文件相关的操作类
*
* @author fengshuonan
* @date 2016年11月17日 下午10:09:23
*/
public class ResKit {
/**
* @Description 批量获取ClassPath下的资源文件
* @author fengshuonan
*/
public static Resource[] getClassPathResources(String pattern) {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
return resolver.getResources(pattern);
} catch (IOException e) {
throw new RuntimeException("加载resource文件时,找不到文件,所找文件为:" + pattern);
}
}
/**
* @Description 批量获取ClassPath下的资源文件
* @author fengshuonan
*/
public static String getClassPathFile(String file) {
//return ResKit.class.getClassLoader().getResource(file).getPath();
return Thread.currentThread().getContextClassLoader().getResource(file).getPath();
}
}
package com.stylefeng.guns.core.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean
*
* @author fengshuonan
* @date 2016年11月27日 下午3:32:11
*/
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
assertApplicationContext();
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
assertApplicationContext();
return (T) applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> requiredType) {
assertApplicationContext();
return applicationContext.getBean(requiredType);
}
private static void assertApplicationContext() {
if (SpringContextHolder.applicationContext == null) {
throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!");
}
}
}
package com.stylefeng.guns.core.util;
import java.util.ArrayList;
import java.util.List;
/**
* sql语句工具类
*
* @author fengshuonan
* @date 2016年12月6日 下午1:01:54
*/
public class SqlUtil {
/**
* @Description 根据集合的大小,输出相应个数"?"
* @author fengshuonan
*/
public static String parse(List<?> list) {
String str = "";
if (list != null && list.size() > 0) {
str = str + "?";
for (int i = 1; i < list.size(); i++) {
str = str + ",?";
}
}
return str;
}
public static void main(String[] args) {
ArrayList<Object> arrayList = new ArrayList<>();
arrayList.add(2);
arrayList.add(2);
System.out.println(parse(arrayList));
}
}
/**
* Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.core.util.support.StrKit;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;
/**
* 高频方法集合类
*/
public class ToolUtil {
/**
* 判断一个对象是否是时间类型
*
* @author stylefeng
* @Date 2017/4/18 12:55
*/
public static String dateType(Object o){
if(o instanceof Date){
return DateUtil.getDay((Date) o);
}else{
return o.toString();
}
}
/**
* 获取异常的具体信息
*
* @author fengshuonan
* @Date 2017/3/30 9:21
* @version 2.0
*/
public static String getExceptionMsg(Exception e) {
StringWriter sw = new StringWriter();
try{
e.printStackTrace(new PrintWriter(sw));
}finally {
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return sw.getBuffer().toString().replaceAll("\\$","T");
}
/**
* @Description 主键id
* @author fengshuonan
*/
public static String getUid() {
return getRandomNum();
}
/**
* @Description 随机数字
* @author fengshuonan
*/
public static String getRandomNum() {
return Calendar.getInstance().getTimeInMillis() + generateCellPhoneValNum();
}
/**
* @Description 获取电话号码
* @author fengshuonan
*/
public static String generateCellPhoneValNum() {
String[] beforeShuffle = new String[]{"1", "2", "3", "4", "5", "6",
"7", "8", "9", "0"};
List<String> list = Arrays.asList(beforeShuffle);
Collections.shuffle(list);
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
buffer.append(list.get(i));
}
String afterShuffle = buffer.toString();
String result = afterShuffle.substring(3, 9);
return result;
}
/**
* 比较两个对象是否相等。<br>
* 相同的条件有两个,满足其一即可:<br>
* 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
*
* @param obj1 对象1
* @param obj2 对象2
* @return 是否相等
*/
public static boolean equals(Object obj1, Object obj2) {
return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
}
/**
* 计算对象长度,如果是字符串调用其length函数,集合类调用其size函数,数组调用其length属性,其他可遍历对象遍历计算长度
*
* @param obj 被计算长度的对象
* @return 长度
*/
public static int length(Object obj) {
if (obj == null) {
return 0;
}
if (obj instanceof CharSequence) {
return ((CharSequence) obj).length();
}
if (obj instanceof Collection) {
return ((Collection<?>) obj).size();
}
if (obj instanceof Map) {
return ((Map<?, ?>) obj).size();
}
int count;
if (obj instanceof Iterator) {
Iterator<?> iter = (Iterator<?>) obj;
count = 0;
while (iter.hasNext()) {
count++;
iter.next();
}
return count;
}
if (obj instanceof Enumeration) {
Enumeration<?> enumeration = (Enumeration<?>) obj;
count = 0;
while (enumeration.hasMoreElements()) {
count++;
enumeration.nextElement();
}
return count;
}
if (obj.getClass().isArray() == true) {
return Array.getLength(obj);
}
return -1;
}
/**
* 对象中是否包含元素
*
* @param obj 对象
* @param element 元素
* @return 是否包含
*/
public static boolean contains(Object obj, Object element) {
if (obj == null) {
return false;
}
if (obj instanceof String) {
if (element == null) {
return false;
}
return ((String) obj).contains(element.toString());
}
if (obj instanceof Collection) {
return ((Collection<?>) obj).contains(element);
}
if (obj instanceof Map) {
return ((Map<?, ?>) obj).values().contains(element);
}
if (obj instanceof Iterator) {
Iterator<?> iter = (Iterator<?>) obj;
while (iter.hasNext()) {
Object o = iter.next();
if (equals(o, element)) {
return true;
}
}
return false;
}
if (obj instanceof Enumeration) {
Enumeration<?> enumeration = (Enumeration<?>) obj;
while (enumeration.hasMoreElements()) {
Object o = enumeration.nextElement();
if (equals(o, element)) {
return true;
}
}
return false;
}
if (obj.getClass().isArray() == true) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
Object o = Array.get(obj, i);
if (equals(o, element)) {
return true;
}
}
}
return false;
}
/**
* 对象是否不为空(新增)
*
* @param obj String,List,Map,Object[],int[],long[]
* @return
*/
public static boolean isNotEmpty(Object o) {
return !isEmpty(o);
}
/**
* 对象是否为空
*
* @param obj String,List,Map,Object[],int[],long[]
* @return
*/
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Object o) {
if (o == null) {
return true;
}
if (o instanceof String) {
if (o.toString().trim().equals("")) {
return true;
}
} else if (o instanceof List) {
if (((List) o).size() == 0) {
return true;
}
} else if (o instanceof Map) {
if (((Map) o).size() == 0) {
return true;
}
} else if (o instanceof Set) {
if (((Set) o).size() == 0) {
return true;
}
} else if (o instanceof Object[]) {
if (((Object[]) o).length == 0) {
return true;
}
} else if (o instanceof int[]) {
if (((int[]) o).length == 0) {
return true;
}
} else if (o instanceof long[]) {
if (((long[]) o).length == 0) {
return true;
}
}
return false;
}
/**
* 对象组中是否存在 Empty Object
*
* @param os 对象组
* @return
*/
public static boolean isOneEmpty(Object... os) {
for (Object o : os) {
if (isEmpty(o)) {
return true;
}
}
return false;
}
/**
* 对象组中是否全是 Empty Object
*
* @param os
* @return
*/
public static boolean isAllEmpty(Object... os) {
for (Object o : os) {
if (!isEmpty(o)) {
return false;
}
}
return true;
}
/**
* 是否为数字
*
* @param obj
* @return
*/
public static boolean isNum(Object obj) {
try {
Integer.parseInt(obj.toString());
} catch (Exception e) {
return false;
}
return true;
}
/**
* 如果为空, 则调用默认值
*
* @param str
* @return
*/
public static Object getValue(Object str, Object defaultValue) {
if (isEmpty(str)) {
return defaultValue;
}
return str;
}
/**
* 格式化文本
*
* @param template 文本模板,被替换的部分用 {} 表示
* @param values 参数值
* @return 格式化后的文本
*/
public static String format(String template, Object... values) {
return StrKit.format(template, values);
}
/**
* 格式化文本
*
* @param template 文本模板,被替换的部分用 {key} 表示
* @param map 参数值对
* @return 格式化后的文本
*/
public static String format(String template, Map<?, ?> map) {
return StrKit.format(template, map);
}
/**
* 强转->string,并去掉多余空格
*
* @param str
* @return
*/
public static String toStr(Object str) {
return toStr(str, "");
}
/**
* 强转->string,并去掉多余空格
*
* @param str
* @param defaultValue
* @return
*/
public static String toStr(Object str, String defaultValue) {
if (null == str) {
return defaultValue;
}
return str.toString().trim();
}
/**
* 强转->int
*
* @param obj
* @return
*/
// public static int toInt(Object value) {
// return toInt(value, -1);
// }
/**
* 强转->int
*
* @param obj
* @param defaultValue
* @return
*/
// public static int toInt(Object value, int defaultValue) {
// return Convert.toInt(value, defaultValue);
// }
/**
* 强转->long
*
* @param obj
* @return
*/
// public static long toLong(Object value) {
// return toLong(value, -1);
// }
/**
* 强转->long
*
* @param obj
* @param defaultValue
* @return
*/
// public static long toLong(Object value, long defaultValue) {
// return Convert.toLong(value, defaultValue);
// }
//
// public static String encodeUrl(String url) {
// return URLKit.encode(url, CharsetKit.UTF_8);
// }
//
// public static String decodeUrl(String url) {
// return URLKit.decode(url, CharsetKit.UTF_8);
// }
/**
* map的key转为小写
*
* @param map
* @return Map<String,Object>
*/
public static Map<String, Object> caseInsensitiveMap(Map<String, Object> map) {
Map<String, Object> tempMap = new HashMap<>();
for (String key : map.keySet()) {
tempMap.put(key.toLowerCase(), map.get(key));
}
return tempMap;
}
/**
* 获取map中第一个数据值
*
* @param <K> Key的类型
* @param <V> Value的类型
* @param map 数据源
* @return 返回的值
*/
public static <K, V> V getFirstOrNull(Map<K, V> map) {
V obj = null;
for (Entry<K, V> entry : map.entrySet()) {
obj = entry.getValue();
if (obj != null) {
break;
}
}
return obj;
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder(String... strs) {
final StringBuilder sb = new StringBuilder();
for (String str : strs) {
sb.append(str);
}
return sb;
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static void builder(StringBuilder sb, String... strs) {
for (String str : strs) {
sb.append(str);
}
}
/**
* 去掉指定后缀
*
* @param str 字符串
* @param suffix 后缀
* @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
*/
public static String removeSuffix(String str, String suffix) {
if (isEmpty(str) || isEmpty(suffix)) {
return str;
}
if (str.endsWith(suffix)) {
return str.substring(0, str.length() - suffix.length());
}
return str;
}
/**
* 当前时间
*
* @author stylefeng
* @Date 2017/5/7 21:56
*/
public static String currentTime(){
return DateUtil.getTime();
}
/**
* 首字母大写
*
* @author stylefeng
* @Date 2017/5/7 22:01
*/
public static String firstLetterToUpper(String val){
return StrKit.firstCharToUpperCase(val);
}
/**
* 首字母小写
*
* @author stylefeng
* @Date 2017/5/7 22:02
*/
public static String firstLetterToLower(String val){
return StrKit.firstCharToLowerCase(val);
}
/**
* 判断是否是windows操作系统
*
* @author stylefeng
* @Date 2017/5/24 22:34
*/
public static Boolean isWinOs(){
String os = System.getProperty("os.name");
if(os.toLowerCase().startsWith("win")){
return true;
}else{
return false;
}
}
/**
* 获取临时目录
*
* @author stylefeng
* @Date 2017/5/24 22:35
*/
public static String getTempPath(){
return System.getProperty("java.io.tmpdir");
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util.qr;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 内嵌图片的二维码生成器
*
* @author lichunxi
*/
public class ImgQrTool {
private static Logger log = LoggerFactory.getLogger(ImgQrTool.class);
// 镶嵌的图片宽度的一般
private static final int IMAGE_WIDTH = 80;
private static final int IMAGE_HEIGHT = 80;
private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
private static final int FRAME_WIDTH = 2;
// 二维码写码器
private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
/**
* 生成带图片的二维码
*
* @param content 二维码的内容
* @param width 宽度
* @param height 高度
* @param srcImagePath 被镶嵌的图片的地址
* @param destImagePath 生成二维码图片的地址
* @author fengshuonan
* @since 2.3.0
*/
public static void encode(String content, int width, int height, String srcImagePath, String destImagePath) {
try {
ImageIO.write(genBarcode(content, width, height, srcImagePath), "jpg", new File(destImagePath));
} catch (IOException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
}
}
/**
* 生成带图片的二维码
*
* @param content 二维码的内容
* @param width 宽度
* @param height 高度
* @param srcImagePath 被镶嵌的图片的地址
* @param destImagePath 生成二维码图片的地址
* @author fengshuonan
* @since 2.3.0
*/
public static void encode(String content, int width, int height, String srcImagePath, OutputStream outputStream) {
try {
ImageIO.write(genBarcode(content, width, height, srcImagePath), "jpg", outputStream);
} catch (IOException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
}
}
/**
* 创建不带参数的二维码
*
* @author fengshuonan
* @since 2.3.0
*/
public static void createSimpleQr(String content, int width, int height, String destImagePath) {
FileOutputStream output = null;
try {
String format = "jpg";// 图像类型
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);// 生成矩阵
File dest = new File(destImagePath);
output = new FileOutputStream(dest);
MatrixToImageWriter.writeToStream(bitMatrix, format, output);// 输出图像
} catch (Exception e) {
log.error("生成二维码出错!ImgQrTool:createSimpleQr()", e);
} finally {
try {
output.close();
} catch (IOException e) {
log.error("生成二维码出错!ImgQrTool:createSimpleQr()", e);
}
}
}
private static BufferedImage genBarcode(String content, int width, int height, String srcImagePath)
throws WriterException, IOException {
// 读取源图像
BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH, IMAGE_HEIGHT, true);
int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
for (int i = 0; i < scaleImage.getWidth(); i++) {
for (int j = 0; j < scaleImage.getHeight(); j++) {
srcPixels[i][j] = scaleImage.getRGB(i, j);
}
}
Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hint.put(EncodeHintType.MARGIN, 1);// 二维码整体白框
// 生成二维码
BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint);
// 二维矩阵转为一维像素数组
int halfW = matrix.getWidth() / 2;
int halfH = matrix.getHeight() / 2;
int[] pixels = new int[width * height];
for (int y = 0; y < matrix.getHeight(); y++) {
for (int x = 0; x < matrix.getWidth(); x++) {
// 读取图片
if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH && y > halfH - IMAGE_HALF_WIDTH
&& y < halfH + IMAGE_HALF_WIDTH) {
pixels[y * width + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
}
// 在图片四周形成边框
else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& y < halfH - IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH
&& y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
pixels[y * width + x] = 0xfffffff;
} else {
// 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;
pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff;
}
}
}
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
image.getRaster().setDataElements(0, 0, width, height, pixels);
return image;
}
/**
* 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
*
* @param srcImageFile 源文件地址
* @param height 目标高度
* @param width 目标宽度
* @param hasFiller 比例不对时是否需要补白:true为补白; false为不补白;
* @throws IOException
*/
private static BufferedImage scale(String srcImageFile, int height, int width, boolean hasFiller)
throws IOException {
double ratio = 0.0; // 缩放比例
File file = new File(srcImageFile);
BufferedImage srcImage = ImageIO.read(file);
Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
// 计算比例
if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
if (srcImage.getHeight() > srcImage.getWidth()) {
ratio = (new Integer(height)).doubleValue() / srcImage.getHeight();
} else {
ratio = (new Integer(width)).doubleValue() / srcImage.getWidth();
}
AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
destImage = op.filter(srcImage, null);
}
if (hasFiller) {// 补白
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphic = image.createGraphics();
graphic.setColor(Color.white);
graphic.fillRect(0, 0, width, height);
if (width == destImage.getWidth(null))
graphic.drawImage(destImage, 0, (height - destImage.getHeight(null)) / 2, destImage.getWidth(null),
destImage.getHeight(null), Color.white, null);
else
graphic.drawImage(destImage, (width - destImage.getWidth(null)) / 2, 0, destImage.getWidth(null),
destImage.getHeight(null), Color.white, null);
graphic.dispose();
destImage = image;
}
return (BufferedImage) destImage;
}
/**
* 生成上方带文字的二维码
*/
public static void createQrWithFontsAbove(QrImage para) {
try {
// 首先生成二维码图片
BufferedImage qrImage = genBarcode(para.getQrContent(), para.getQrWidth(), para.getQrHeight(), para.getQrIconFilePath());
int qrImageWidth = qrImage.getWidth();
int qrImageHeight = qrImage.getHeight();
String[] splitStrLines = null;
splitStrLines = splitStrLines(para.getWordContent(), qrImageWidth / para.getWordSize());
int fontsImageHeight = splitStrLines.length * para.getWordSize() + 10; //防止文字遮挡
//创建顶部文字的图片
BufferedImage imageWithFonts = new BufferedImage(qrImageWidth, fontsImageHeight, BufferedImage.TYPE_4BYTE_ABGR);
Graphics fontsImageGraphics = imageWithFonts.getGraphics();
fontsImageGraphics.fillRect(0, 0, qrImageWidth, fontsImageHeight);
fontsImageGraphics.setColor(Color.black);
fontsImageGraphics.setFont(new Font("宋体", Font.PLAIN, para.getWordSize()));
//文字长度大于一行的长度,进行分行
if (para.getWordContent().length() > qrImageWidth / para.getWordSize()) {//每行限制的文字个数
for (int i = 0; i < splitStrLines.length; i++) {
fontsImageGraphics.drawString(splitStrLines[i], 0, para.getWordSize() * (i + 1));
}
} else {
fontsImageGraphics.drawString(
para.getWordContent(),
((qrImageWidth / para.getWordSize() - para.getWordContent().length()) / 2) * para.getWordSize() + 20, //总长度减去字长度除以2为向右偏移长度
para.getWordSize());
}
// 从图片中读取RGB
int[] ImageArrayFonts = new int[qrImageWidth * fontsImageHeight];
ImageArrayFonts = imageWithFonts.getRGB(0, 0, qrImageWidth, fontsImageHeight, ImageArrayFonts, 0, qrImageWidth);
int[] ImageArrayQr = new int[qrImageWidth * qrImageHeight];
ImageArrayQr = qrImage.getRGB(0, 0, qrImageWidth, qrImageHeight, ImageArrayQr, 0, qrImageWidth);
// 生成新图片
BufferedImage ImageNew = new BufferedImage(qrImageWidth, qrImageHeight + fontsImageHeight, BufferedImage.TYPE_INT_RGB);
ImageNew.setRGB(0, 0, qrImageWidth, fontsImageHeight, ImageArrayFonts, 0, qrImageWidth);// 设置上半部分的RGB
ImageNew.setRGB(0, fontsImageHeight, qrImageWidth, qrImageHeight, ImageArrayQr, 0, qrImageWidth);// 设置下半部分的RGB
File outFile = new File(para.getFileOutputPath());
ImageIO.write(ImageNew, "jpg", outFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 一行字符串拆分成多行
*/
private static String[] splitStrLines(String str, int len) {
int blocks = str.length() / len + 1;
String[] strs = new String[blocks];
for (int i = 0; i < blocks; i++) {
if ((i + 1) * len > str.length()) {
strs[i] = str.substring(i * len);
} else {
strs[i] = str.substring(i * len, (i + 1) * len);
}
}
return strs;
}
public static void main(String[] args) throws IOException {
for (int i = 1; i <= 1; i++) {
QrImage para = new QrImage.Builder()
.setFileOutputPath("D:\\二维码\\test\\" + i + ".jpg")
.setQrContent("http://www.baidu.com?a=" + "123")
.setQrHeight(300)
.setQrWidth(300)
.setQrIconFilePath("D:\\二维码\\中间图标\\1.png")
.setTopWrodHeight(100)
.setWordContent("test" + 1)
.setWordSize(18).build();
ImgQrTool.createQrWithFontsAbove(para);
}
}
}
/*
* Copyright 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util.qr;
import java.awt.image.BufferedImage;
/**
* Encapsulates custom configuration used in methods of {@link MatrixToImageWriter}.
*/
public final class MatrixToImageConfig {
public static final int BLACK = 0xFF000000;
public static final int WHITE = 0xFFFFFFFF;
private final int onColor;
private final int offColor;
/**
* Creates a default config with on color {@link #BLACK} and off color {@link #WHITE}, generating normal
* black-on-white barcodes.
*/
public MatrixToImageConfig() {
this(BLACK, WHITE);
}
/**
* @param onColor pixel on color, specified as an ARGB value as an int
* @param offColor pixel off color, specified as an ARGB value as an int
*/
public MatrixToImageConfig(int onColor, int offColor) {
this.onColor = onColor;
this.offColor = offColor;
}
public int getPixelOnColor() {
return onColor;
}
public int getPixelOffColor() {
return offColor;
}
int getBufferedImageColorModel() {
// Use faster BINARY if colors match default
return onColor == BLACK && offColor == WHITE ? BufferedImage.TYPE_BYTE_BINARY : BufferedImage.TYPE_INT_RGB;
}
}
\ No newline at end of file
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util.qr;
import com.google.zxing.common.BitMatrix;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
/**
* Writes a {@link BitMatrix} to {@link BufferedImage},
* file or stream. Provided here instead of core since it depends on
* Java SE libraries.
*
* @author Sean Owen
*/
public final class MatrixToImageWriter {
private static final MatrixToImageConfig DEFAULT_CONFIG = new MatrixToImageConfig();
private MatrixToImageWriter() {}
/**
* Renders a {@link BitMatrix} as an image, where "false" bits are rendered
* as white, and "true" bits are rendered as black.
*/
public static BufferedImage toBufferedImage(BitMatrix matrix) {
return toBufferedImage(matrix, DEFAULT_CONFIG);
}
/**
* As {@link #toBufferedImage(BitMatrix)}, but allows customization of the output.
*/
public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
int onColor = config.getPixelOnColor();
int offColor = config.getPixelOffColor();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
}
}
return image;
}
/**
* @deprecated use {@link #writeToPath(BitMatrix, String, Path)}
*/
@Deprecated
public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
writeToPath(matrix, format, file.toPath());
}
/**
* Writes a {@link BitMatrix} to a file.
*
* @see #toBufferedImage(BitMatrix)
*/
public static void writeToPath(BitMatrix matrix, String format, Path file) throws IOException {
writeToPath(matrix, format, file, DEFAULT_CONFIG);
}
/**
* @deprecated use {@link #writeToPath(BitMatrix, String, Path, MatrixToImageConfig)}
*/
@Deprecated
public static void writeToFile(BitMatrix matrix, String format, File file, MatrixToImageConfig config)
throws IOException {
writeToPath(matrix, format, file.toPath(), config);
}
/**
* As {@link #writeToFile(BitMatrix, String, File)}, but allows customization of the output.
*/
public static void writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config)
throws IOException {
BufferedImage image = toBufferedImage(matrix, config);
if (!ImageIO.write(image, format, file.toFile())) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
/**
* Writes a {@link BitMatrix} to a stream.
*
* @see #toBufferedImage(BitMatrix)
*/
public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
writeToStream(matrix, format, stream, DEFAULT_CONFIG);
}
/**
* As {@link #writeToStream(BitMatrix, String, OutputStream)}, but allows customization of the output.
*/
public static void writeToStream(BitMatrix matrix, String format, OutputStream stream, MatrixToImageConfig config)
throws IOException {
BufferedImage image = toBufferedImage(matrix, config);
if (!ImageIO.write(image, format, stream)) {
throw new IOException("Could not write an image of format " + format);
}
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util.qr;
/**
* 二维码图片对象
*
* @author fengshuonan
* @date 2016年12月8日 上午11:37:09
*/
public class QrImage {
/**
* 二维码的内容
*/
private String qrContent;
/**
* 二维码的宽度
*/
private int qrWidth;
/**
* 二维码的高度
*/
private int qrHeight;
/**
* 二维码中间图标的文件路径
*/
private String qrIconFilePath;
/**
* 二维码中间小图标的边长
*/
private int qrIconWidth;
/**
* 顶部文字的高度
*/
private int topWrodHeight;
/**
* 文字的大小
*/
private int wordSize;
/**
* 文字的内容
*/
private String wordContent;
/**
* 文件的输出路径
*/
private String fileOutputPath;
public static class Builder {
private String qrContent;
private int qrWidth;
private int qrHeight;
private String qrIconFilePath;
private int topWrodHeight;
private int wordSize;
private String wordContent;
private String fileOutputPath;
private int qrIconWidth;
public Builder() {
}
public Builder setQrContent(String qrContent) {
this.qrContent = qrContent;
return this;
}
public Builder setQrWidth(int qrWidth) {
this.qrWidth = qrWidth;
return this;
}
public Builder setQrHeight(int qrHeight) {
this.qrHeight = qrHeight;
return this;
}
public Builder setQrIconFilePath(String qrIconFilePath) {
this.qrIconFilePath = qrIconFilePath;
return this;
}
public Builder setTopWrodHeight(int topWrodHeight) {
this.topWrodHeight = topWrodHeight;
return this;
}
public Builder setWordSize(int wordSize) {
this.wordSize = wordSize;
return this;
}
public Builder setWordContent(String wordContent) {
this.wordContent = wordContent;
return this;
}
public Builder setFileOutputPath(String fileOutputPath) {
this.fileOutputPath = fileOutputPath;
return this;
}
public Builder setQrIconWidth(int qrIconWidth) {
this.qrIconWidth = qrIconWidth;
return this;
}
public QrImage build() {
return new QrImage(this.qrContent, this.qrWidth, this.qrHeight, this.qrIconFilePath, this.qrIconWidth,
this.topWrodHeight, this.wordSize, this.wordContent, this.fileOutputPath);
}
}
public QrImage(String qrContent, int qrWidth, int qrHeight, String qrIconFilePath, int qrIconWidth,
int topWrodHeight, int wordSize, String wordContent, String fileOutputPath) {
super();
this.qrContent = qrContent;
this.qrWidth = qrWidth;
this.qrHeight = qrHeight;
this.qrIconFilePath = qrIconFilePath;
this.qrIconWidth = qrIconWidth;
this.topWrodHeight = topWrodHeight;
this.wordSize = wordSize;
this.wordContent = wordContent;
this.fileOutputPath = fileOutputPath;
}
public String getQrContent() {
return qrContent;
}
public int getQrWidth() {
return qrWidth;
}
public int getQrHeight() {
return qrHeight;
}
public String getQrIconFilePath() {
return qrIconFilePath;
}
public int getTopWrodHeight() {
return topWrodHeight;
}
public int getWordSize() {
return wordSize;
}
public String getWordContent() {
return wordContent;
}
public String getFileOutputPath() {
return fileOutputPath;
}
public int getQrIconWidth() {
return qrIconWidth;
}
}
package com.stylefeng.guns.core.util.support;
import java.util.HashMap;
import java.util.Map;
/**
* 基本变量类型的枚举
* @author xiaoleilu
*/
public enum BasicType {
BYTE, SHORT, INT, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, CHAR, CHARACTER, STRING;
/** 原始类型为Key,包装类型为Value,例如: int.class -> Integer.class. */
public static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<Class<?>, Class<?>>(8);
/** 包装类型为Key,原始类型为Value,例如: Integer.class -> int.class. */
public static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>(8);
static {
wrapperPrimitiveMap.put(Boolean.class, boolean.class);
wrapperPrimitiveMap.put(Byte.class, byte.class);
wrapperPrimitiveMap.put(Character.class, char.class);
wrapperPrimitiveMap.put(Double.class, double.class);
wrapperPrimitiveMap.put(Float.class, float.class);
wrapperPrimitiveMap.put(Integer.class, int.class);
wrapperPrimitiveMap.put(Long.class, long.class);
wrapperPrimitiveMap.put(Short.class, short.class);
for (Map.Entry<Class<?>, Class<?>> entry : wrapperPrimitiveMap.entrySet()) {
primitiveWrapperMap.put(entry.getValue(), entry.getKey());
}
}
}
package com.stylefeng.guns.core.util.support;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.core.util.support.exception.ToolBoxException;
import java.beans.*;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
/**
* Bean工具类
* @author Looly
*
*/
public class BeanKit {
/**
* 判断是否为Bean对象
* @param clazz 待测试类
* @return 是否为Bean对象
*/
public static boolean isBean(Class<?> clazz){
if(ClassKit.isNormalClass(clazz)){
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if(method.getParameterTypes().length == 1 && method.getName().startsWith("set")){
//检测包含标准的setXXX方法即视为标准的JavaBean
return true;
}
}
}
return false;
}
public static PropertyEditor findEditor(Class<?> type){
return PropertyEditorManager.findEditor(type);
}
/**
* 获得Bean字段描述数组
*
* @param clazz Bean类
* @return 字段描述数组
* @throws IntrospectionException
*/
public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws IntrospectionException {
return Introspector.getBeanInfo(clazz).getPropertyDescriptors();
}
/**
* 获得字段名和字段描述Map
* @param clazz Bean类
* @return 字段名和字段描述Map
* @throws IntrospectionException
*/
public static Map<String, PropertyDescriptor> getFieldNamePropertyDescriptorMap(Class<?> clazz) throws IntrospectionException{
final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
Map<String, PropertyDescriptor> map = new HashMap<>();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
map.put(propertyDescriptor.getName(), propertyDescriptor);
}
return map;
}
/**
* 获得Bean类属性描述
*
* @param clazz Bean类
* @param fieldName 字段名
* @return PropertyDescriptor
* @throws IntrospectionException
*/
public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, final String fieldName) throws IntrospectionException {
PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (ObjectKit.equals(fieldName, propertyDescriptor.getName())) {
return propertyDescriptor;
}
}
return null;
}
/**
* Map转换为Bean对象
*
* @param map Map
* @param beanClass Bean Class
* @return Bean
*/
public static <T> T mapToBean(Map<?, ?> map, Class<T> beanClass) {
return fillBeanWithMap(map, ClassKit.newInstance(beanClass));
}
/**
* Map转换为Bean对象<br>
* 忽略大小写
*
* @param map Map
* @param beanClass Bean Class
* @return Bean
*/
public static <T> T mapToBeanIgnoreCase(Map<?, ?> map, Class<T> beanClass) {
return fillBeanWithMapIgnoreCase(map, ClassKit.newInstance(beanClass));
}
/**
* 使用Map填充Bean对象
*
* @param map Map
* @param bean Bean
* @return Bean
*/
public static <T> T fillBeanWithMap(final Map<?, ?> map, T bean) {
return fillBean(bean, new ValueProvider(){
@Override
public Object value(String name) {
return map.get(name);
}
});
}
/**
* 使用Map填充Bean对象,可配置将下划线转换为驼峰
*
* @param map Map
* @param bean Bean
* @param isToCamelCase 是否将下划线模式转换为驼峰模式
* @return Bean
*/
public static <T> T fillBeanWithMap(Map<?, ?> map, T bean, boolean isToCamelCase) {
if(isToCamelCase){
final Map<Object, Object> map2 = new HashMap<Object, Object>();
for (Entry<?, ?> entry : map.entrySet()) {
final Object key = entry.getKey();
if (null != key && key instanceof String) {
final String keyStr = (String) key;
map2.put(StrKit.toCamelCase(keyStr), entry.getValue());
} else {
map2.put(key, entry.getValue());
}
}
return fillBeanWithMap(map2, bean);
}
return fillBeanWithMap(map, bean);
}
/**
* 使用Map填充Bean对象,忽略大小写
*
* @param map Map
* @param bean Bean
* @return Bean
*/
public static <T> T fillBeanWithMapIgnoreCase(Map<?, ?> map, T bean) {
final Map<Object, Object> map2 = new HashMap<Object, Object>();
for (Entry<?, ?> entry : map.entrySet()) {
final Object key = entry.getKey();
if (key instanceof String) {
final String keyStr = (String) key;
map2.put(keyStr.toLowerCase(), entry.getValue());
} else {
map2.put(key, entry.getValue());
}
}
return fillBean(bean, new ValueProvider(){
@Override
public Object value(String name) {
return map2.get(name.toLowerCase());
}
});
}
/**
* ServletRequest 参数转Bean
*
* @param request ServletRequest
* @param beanClass Bean Class
* @return Bean
*/
public static <T> T requestParamToBean(javax.servlet.ServletRequest request, Class<T> beanClass) {
return fillBeanWithRequestParam(request, ClassKit.newInstance(beanClass));
}
/**
* ServletRequest 参数转Bean
*
* @param request ServletRequest
* @param bean Bean
* @return Bean
*/
public static <T> T fillBeanWithRequestParam(final javax.servlet.ServletRequest request, T bean) {
final String beanName = StrKit.lowerFirst(bean.getClass().getSimpleName());
return fillBean(bean, new ValueProvider(){
@Override
public Object value(String name) {
String value = request.getParameter(name);
if (StrKit.isEmpty(value)) {
// 使用类名前缀尝试查找值
value = request.getParameter(beanName + StrKit.DOT + name);
if (StrKit.isEmpty(value)) {
// 此处取得的值为空时跳过,包括null和""
value = null;
}
}
return value;
}
});
}
/**
* ServletRequest 参数转Bean
*
* @param <T>
* @param beanClass Bean Class
* @param valueProvider 值提供者
* @return Bean
*/
public static <T> T toBean(Class<T> beanClass, ValueProvider valueProvider) {
return fillBean(ClassKit.newInstance(beanClass), valueProvider);
}
/**
* 填充Bean
*
* @param <T>
* @param bean Bean
* @param valueProvider 值提供者
* @return Bean
*/
public static <T> T fillBean(T bean, ValueProvider valueProvider) {
if (null == valueProvider) {
return bean;
}
Class<?> beanClass = bean.getClass();
try {
PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(beanClass);
String propertyName;
Object value;
for (PropertyDescriptor property : propertyDescriptors) {
propertyName = property.getName();
value = valueProvider.value(propertyName);
if (null == value) {
continue;
}
try {
property.getWriteMethod().invoke(bean, Convert.parse(property.getPropertyType(), value));
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
throw new ToolBoxException(e);
}
return bean;
}
/**
* 对象转Map
*
* @param bean bean对象
* @return Map
*/
public static <T> Map<String, Object> beanToMap(T bean) {
return beanToMap(bean, false);
}
/**
* 对象转Map
*
* @param bean bean对象
* @param isToUnderlineCase 是否转换为下划线模式
* @return Map
*/
public static <T> Map<String, Object> beanToMap(T bean, boolean isToUnderlineCase) {
if (bean == null) {
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
try {
final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(bean.getClass());
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
// 过滤class属性
if (false == key.equals("class")) {
// 得到property对应的getter方法
Method getter = property.getReadMethod();
Object value = getter.invoke(bean);
if (null != value) {
map.put(isToUnderlineCase ? StrKit.toUnderlineCase(key) : key, value);
}
}
}
} catch (Exception e) {
throw new ToolBoxException(e);
}
return map;
}
/**
* 复制Bean对象属性
* @param source 源Bean对象
* @param target 目标Bean对象
*/
public static void copyProperties(Object source, Object target) {
copyProperties(source, target, CopyOptions.create());
}
/**
* 复制Bean对象属性<br>
* 限制类用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
* @param source 源Bean对象
* @param target 目标Bean对象
* @param ignoreProperties 不拷贝的的属性列表
*/
public static void copyProperties(Object source, Object target, String... ignoreProperties) {
copyProperties(source, target, CopyOptions.create().setIgnoreProperties(ignoreProperties));
}
/**
* 复制Bean对象属性<br>
* 限制类用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
* @param source 源Bean对象
* @param target 目标Bean对象
* @param copyOptions 拷贝选项,见 {@link CopyOptions}
*/
public static void copyProperties(Object source, Object target, CopyOptions copyOptions) {
if(null == copyOptions){
copyOptions = new CopyOptions();
}
Class<?> actualEditable = target.getClass();
if (copyOptions.editable != null) {
//检查限制类是否为target的父类或接口
if (!copyOptions.editable.isInstance(target)) {
throw new IllegalArgumentException(StrKit.format("Target class [{}] not assignable to Editable class [{}]", target.getClass().getName(), copyOptions.editable.getName()));
}
actualEditable = copyOptions.editable;
}
PropertyDescriptor[] targetPds = null;
Map<String, PropertyDescriptor> sourcePdMap;
try {
sourcePdMap = getFieldNamePropertyDescriptorMap(source.getClass());
targetPds = getPropertyDescriptors(actualEditable);
} catch (IntrospectionException e) {
throw new ToolBoxException(e);
}
HashSet<String> ignoreSet = copyOptions.ignoreProperties != null ? CollectionKit.newHashSet(copyOptions.ignoreProperties) : null;
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreSet == null || false == ignoreSet.contains(targetPd.getName()))) {
PropertyDescriptor sourcePd = sourcePdMap.get(targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
// 源对象字段的getter方法返回值必须可转换为目标对象setter方法的第一个参数
if (readMethod != null && ClassKit.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
try {
Object value = ClassKit.setAccessible(readMethod).invoke(source);
if(null != value || false == copyOptions.isIgnoreNullValue){
ClassKit.setAccessible(writeMethod).invoke(target, value);
}
} catch (Throwable ex) {
throw new ToolBoxException(ex, "Copy property [{}] to [{}] error: {}", sourcePd.getName(), targetPd.getName(), ex.getMessage());
}
}
}
}
}
}
/**
* 值提供者,用于提供Bean注入时参数对应值得抽象接口<br>
* 继承或匿名实例化此接口<br>
* 在Bean注入过程中,Bean获得字段名,通过外部方式根据这个字段名查找相应的字段值,然后注入Bean<br>
*
* @author Looly
*
*/
public static interface ValueProvider {
/**
* 获取值
*
* @param name Bean对象中参数名
* @return 对应参数名的值
*/
public Object value(String name);
}
/**
* 属性拷贝选项<br>
* 包括:<br>
* 1、限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类<br>
* 2、是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null<br>
* 3、忽略的属性列表,设置一个属性列表,不拷贝这些属性值<br>
*
* @author Looly
*/
public static class CopyOptions {
/** 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类 */
private Class<?> editable;
/** 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null */
private boolean isIgnoreNullValue;
/** 忽略的属性列表,设置一个属性列表,不拷贝这些属性值 */
private String[] ignoreProperties;
/**
* 创建拷贝选项
* @return 拷贝选项
*/
public static CopyOptions create(){
return new CopyOptions();
}
/**
* 创建拷贝选项
* @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性
* @param isIgnoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
* @return 拷贝选项
*/
public static CopyOptions create(Class<?> editable, boolean isIgnoreNullValue, String... ignoreProperties){
return new CopyOptions(editable, isIgnoreNullValue, ignoreProperties);
}
/**
* 构造拷贝选项
*/
public CopyOptions() {
}
/**
* 构造拷贝选项
* @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性
* @param isIgnoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
*/
public CopyOptions(Class<?> editable, boolean isIgnoreNullValue, String... ignoreProperties) {
this.editable = editable;
this.isIgnoreNullValue = isIgnoreNullValue;
this.ignoreProperties = ignoreProperties;
}
/**
* 设置限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性
* @param editable 限制的类或接口
* @return CopyOptions
*/
public CopyOptions setEditable(Class<?> editable){
this.editable = editable;
return this;
}
/**
* 设置是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* @param isIgnoreNullVall 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* @return CopyOptions
*/
public CopyOptions setIgnoreNullValue(boolean isIgnoreNullVall){
this.isIgnoreNullValue = isIgnoreNullVall;
return this;
}
/**
* 设置忽略的属性列表,设置一个属性列表,不拷贝这些属性值
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
* @return CopyOptions
*/
public CopyOptions setIgnoreProperties(String... ignoreProperties){
this.ignoreProperties = ignoreProperties;
return this;
}
}
}
package com.stylefeng.guns.core.util.support;
import com.stylefeng.guns.core.util.support.exception.ToolBoxException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 类工具类
* 1、扫描指定包下的所有类<br>
* 参考 http://www.oschina.net/code/snippet_234657_22722
* @author seaside_hi, xiaoleilu, chill
*
*/
public class ClassKit {
private ClassKit() {
// 静态类不可实例化
}
/**
* 是否为标准的类<br>
* 这个类必须:<br>
* 1、非接口 2、非抽象类 3、非Enum枚举 4、非数组 5、非注解 6、非原始类型(int, long等)
*
* @param clazz 类
* @return 是否为标准类
*/
public static boolean isNormalClass(Class<?> clazz) {
return null != clazz && false == clazz.isInterface() && false == isAbstract(clazz) && false == clazz.isEnum() && false == clazz.isArray() && false == clazz.isAnnotation() && false == clazz
.isSynthetic() && false == clazz.isPrimitive();
}
/**
* 是否为抽象类
*
* @param clazz 类
* @return 是否为抽象类
*/
public static boolean isAbstract(Class<?> clazz) {
return Modifier.isAbstract(clazz.getModifiers());
}
/**
* 实例化对象
*
* @param clazz 类名
* @return 对象
*/
@SuppressWarnings("unchecked")
public static <T> T newInstance(String clazz) {
if (null == clazz)
return null;
try {
return (T) Class.forName(clazz).newInstance();
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Instance class [{}] error!", clazz), e);
}
}
/**
* 实例化对象
*
* @param clazz 类
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz) {
if (null == clazz)
return null;
try {
return (T) clazz.newInstance();
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Instance class [{}] error!", clazz), e);
}
}
/**
* 实例化对象
*
* @param clazz 类
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz, Object... params) {
if (null == clazz)
return null;
if (CollectionKit.isEmpty(params)) {
return newInstance(clazz);
}
try {
return clazz.getDeclaredConstructor(getClasses(params)).newInstance(params);
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Instance class [{}] error!", clazz), e);
}
}
/**
* 获得对象数组的类数组
* @param objects 对象数组
* @return 类数组
*/
public static Class<?>[] getClasses(Object... objects){
Class<?>[] classes = new Class<?>[objects.length];
for (int i = 0; i < objects.length; i++) {
classes[i] = objects[i].getClass();
}
return classes;
}
/**
* 检查目标类是否可以从原类转化<br>
* 转化包括:<br>
* 1、原类是对象,目标类型是原类型实现的接口<br>
* 2、目标类型是原类型的父类<br>
* 3、两者是原始类型或者包装类型(相互转换)
*
* @param targetType 目标类型
* @param sourceType 原类型
* @return 是否可转化
*/
public static boolean isAssignable(Class<?> targetType, Class<?> sourceType) {
if (null == targetType || null == sourceType) {
return false;
}
// 对象类型
if (targetType.isAssignableFrom(sourceType)) {
return true;
}
// 基本类型
if (targetType.isPrimitive()) {
// 原始类型
Class<?> resolvedPrimitive = BasicType.wrapperPrimitiveMap.get(sourceType);
if (resolvedPrimitive != null && targetType.equals(resolvedPrimitive)) {
return true;
}
} else {
// 包装类型
Class<?> resolvedWrapper = BasicType.primitiveWrapperMap.get(sourceType);
if (resolvedWrapper != null && targetType.isAssignableFrom(resolvedWrapper)) {
return true;
}
}
return false;
}
/**
* 设置方法为可访问
*
* @param method 方法
* @return 方法
*/
public static Method setAccessible(Method method) {
if (null != method && ClassKit.isNotPublic(method)) {
method.setAccessible(true);
}
return method;
}
/**
* 指定类是否为非public
*
* @param clazz 类
* @return 是否为非public
*/
public static boolean isNotPublic(Class<?> clazz) {
return false == isPublic(clazz);
}
/**
* 指定方法是否为非public
*
* @param method 方法
* @return 是否为非public
*/
public static boolean isNotPublic(Method method) {
return false == isPublic(method);
}
/**
* 指定类是否为Public
*
* @param clazz 类
* @return 是否为public
*/
public static boolean isPublic(Class<?> clazz) {
if (null == clazz) {
throw new NullPointerException("Class to provided is null.");
}
return Modifier.isPublic(clazz.getModifiers());
}
/**
* 指定方法是否为Public
*
* @param method 方法
* @return 是否为public
*/
public static boolean isPublic(Method method) {
if (null == method) {
throw new NullPointerException("Method to provided is null.");
}
return isPublic(method.getDeclaringClass());
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util.support;
import com.stylefeng.guns.core.util.support.exception.ToolBoxException;
import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;
/**
* 集合相关工具类,包括数组
*
* @author xiaoleilu
*
*/
public class CollectionKit {
private CollectionKit() {
// 静态类不可实例化
}
/**
* 以 conjunction 为分隔符将集合转换为字符串
*
* @param <T> 被处理的集合
* @param collection 集合
* @param conjunction 分隔符
* @return 连接后的字符串
*/
public static <T> String join(Iterable<T> collection, String conjunction) {
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (T item : collection) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* 以 conjunction 为分隔符将数组转换为字符串
*
* @param <T> 被处理的集合
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
*/
public static <T> String join(T[] array, String conjunction) {
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (T item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* 将多个集合排序并显示不同的段落(分页)
* @param pageNo 页码
* @param numPerPage 每页的条目数
* @param comparator 比较器
* @param colls 集合数组
* @return 分页后的段落内容
*/
@SafeVarargs
public static <T> List<T> sortPageAll(int pageNo, int numPerPage, Comparator<T> comparator, Collection<T>... colls) {
final List<T> result = new ArrayList<T>();
for (Collection<T> coll : colls) {
result.addAll(coll);
}
Collections.sort(result, comparator);
//第一页且数目少于第一页显示的数目
if(pageNo <=1 && result.size() <= numPerPage) {
return result;
}
final int[] startEnd = PageKit.transToStartEnd(pageNo, numPerPage);
return result.subList(startEnd[0], startEnd[1]);
}
/**
* 将多个集合排序并显示不同的段落(分页)
* @param pageNo 页码
* @param numPerPage 每页的条目数
* @param comparator 比较器
* @param colls 集合数组
* @return 分业后的段落内容
*/
// @SafeVarargs
// public static <T> List<T> sortPageAll2(int pageNo, int numPerPage, Comparator<T> comparator, Collection<T>... colls) {
// BoundedPriorityQueue<T> queue = new BoundedPriorityQueue<T>(pageNo * numPerPage);
// for (Collection<T> coll : colls) {
// queue.addAll(coll);
// }
//
// //第一页且数目少于第一页显示的数目
// if(pageNo <=1 && queue.size() <= numPerPage) {
// return queue.toList();
// }
//
// final int[] startEnd = PageKit.transToStartEnd(pageNo, numPerPage);
// return queue.toList().subList(startEnd[0], startEnd[1]);
// }
/**
* 将Set排序(根据Entry的值)
*
* @param set 被排序的Set
* @return 排序后的Set
*/
public static List<Entry<Long, Long>> sortEntrySetToList(Set<Entry<Long, Long>> set) {
List<Entry<Long, Long>> list = new LinkedList<Entry<Long, Long>>(set);
Collections.sort(list, new Comparator<Entry<Long, Long>>(){
@Override
public int compare(Entry<Long, Long> o1, Entry<Long, Long> o2) {
if (o1.getValue() > o2.getValue()){
return 1;
}
if (o1.getValue() < o2.getValue()){
return -1;
}
return 0;
}
});
return list;
}
/**
* 切取部分数据
*
* @param <T> 集合元素类型
* @param surplusAlaDatas 原数据
* @param partSize 每部分数据的长度
* @return 切取出的数据或null
*/
public static <T> List<T> popPart(Stack<T> surplusAlaDatas, int partSize) {
if (surplusAlaDatas == null || surplusAlaDatas.size() <= 0){
return null;
}
final List<T> currentAlaDatas = new ArrayList<T>();
int size = surplusAlaDatas.size();
// 切割
if (size > partSize) {
for (int i = 0; i < partSize; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
} else {
for (int i = 0; i < size; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
}
return currentAlaDatas;
}
/**
* 切取部分数据
*
* @param <T> 集合元素类型
* @param surplusAlaDatas 原数据
* @param partSize 每部分数据的长度
* @return 切取出的数据或null
*/
public static <T> List<T> popPart(Deque<T> surplusAlaDatas, int partSize) {
if (surplusAlaDatas == null || surplusAlaDatas.size() <= 0){
return null;
}
final List<T> currentAlaDatas = new ArrayList<T>();
int size = surplusAlaDatas.size();
// 切割
if (size > partSize) {
for (int i = 0; i < partSize; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
} else {
for (int i = 0; i < size; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
}
return currentAlaDatas;
}
/**
* 新建一个HashMap
*
* @return HashMap对象
*/
public static <T, K> HashMap<T, K> newHashMap() {
return new HashMap<T, K>();
}
/**
* 新建一个HashMap
* @param size 初始大小,由于默认负载因子0.75,传入的size会实际初始大小为size / 0.75
* @return HashMap对象
*/
public static <T, K> HashMap<T, K> newHashMap(int size) {
return new HashMap<T, K>((int)(size / 0.75));
}
/**
* 新建一个HashSet
*
* @return HashSet对象
*/
public static <T> HashSet<T> newHashSet() {
return new HashSet<T>();
}
/**
* 新建一个HashSet
*
* @return HashSet对象
*/
@SafeVarargs
public static <T> HashSet<T> newHashSet(T... ts) {
HashSet<T> set = new HashSet<T>();
for (T t : ts) {
set.add(t);
}
return set;
}
/**
* 新建一个ArrayList
*
* @return ArrayList对象
*/
public static <T> ArrayList<T> newArrayList() {
return new ArrayList<T>();
}
/**
* 新建一个ArrayList
*
* @return ArrayList对象
*/
@SafeVarargs
public static <T> ArrayList<T> newArrayList(T... values) {
return new ArrayList<T>(Arrays.asList(values));
}
/**
* 将新元素添加到已有数组中<br/>
* 添加新元素会生成一个新的数组,不影响原数组
*
* @param buffer 已有数组
* @param newElement 新元素
* @return 新数组
*/
public static <T> T[] append(T[] buffer, T newElement) {
T[] t = resize(buffer, buffer.length + 1, newElement.getClass());
t[buffer.length] = newElement;
return t;
}
/**
* 生成一个新的重新设置大小的数组
*
* @param buffer 原数组
* @param newSize 新的数组大小
* @param componentType 数组元素类型
* @return 调整后的新数组
*/
public static <T> T[] resize(T[] buffer, int newSize, Class<?> componentType) {
T[] newArray = newArray(componentType, newSize);
System.arraycopy(buffer, 0, newArray, 0, buffer.length >= newSize ? newSize : buffer.length);
return newArray;
}
/**
* 新建一个空数组
* @param componentType 元素类型
* @param newSize 大小
* @return 空数组
*/
@SuppressWarnings("unchecked")
public static <T> T[] newArray(Class<?> componentType, int newSize) {
return (T[]) Array.newInstance(componentType, newSize);
}
/**
* 生成一个新的重新设置大小的数组<br/>
* 新数组的类型为原数组的类型
*
* @param buffer 原数组
* @param newSize 新的数组大小
* @return 调整后的新数组
*/
public static <T> T[] resize(T[] buffer, int newSize) {
return resize(buffer, newSize, buffer.getClass().getComponentType());
}
/**
* 将多个数组合并在一起<br>
* 忽略null的数组
*
* @param arrays 数组集合
* @return 合并后的数组
*/
@SafeVarargs
public static <T> T[] addAll(T[]... arrays) {
if (arrays.length == 1) {
return arrays[0];
}
int length = 0;
for (T[] array : arrays) {
if(array == null) {
continue;
}
length += array.length;
}
T[] result = newArray(arrays.getClass().getComponentType().getComponentType(), length);
length = 0;
for (T[] array : arrays) {
if(array == null) {
continue;
}
System.arraycopy(array, 0, result, length, array.length);
length += array.length;
}
return result;
}
/**
* 克隆数组
* @param array 被克隆的数组
* @return 新数组
*/
public static <T> T[] clone(T[] array) {
if (array == null) {
return null;
}
return array.clone();
}
/**
* 生成一个数字列表<br>
* 自动判定正序反序
* @param excludedEnd 结束的数字(不包含)
* @return 数字列表
*/
public static int[] range(int excludedEnd) {
return range(0, excludedEnd, 1);
}
/**
* 生成一个数字列表<br>
* 自动判定正序反序
* @param includedStart 开始的数字(包含)
* @param excludedEnd 结束的数字(不包含)
* @return 数字列表
*/
public static int[] range(int includedStart, int excludedEnd) {
return range(includedStart, excludedEnd, 1);
}
/**
* 生成一个数字列表<br>
* 自动判定正序反序
* @param includedStart 开始的数字(包含)
* @param excludedEnd 结束的数字(不包含)
* @param step 步进
* @return 数字列表
*/
public static int[] range(int includedStart, int excludedEnd, int step) {
if(includedStart > excludedEnd) {
int tmp = includedStart;
includedStart = excludedEnd;
excludedEnd = tmp;
}
if(step <=0) {
step = 1;
}
int deviation = excludedEnd - includedStart;
int length = deviation / step;
if(deviation % step != 0) {
length += 1;
}
int[] range = new int[length];
for(int i = 0; i < length; i++) {
range[i] = includedStart;
includedStart += step;
}
return range;
}
/**
* 截取数组的部分
* @param list 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @return 截取后的数组,当开始位置超过最大时,返回null
*/
public static <T> List<T> sub(List<T> list, int start, int end) {
if(list == null || list.isEmpty()) {
return null;
}
if(start < 0) {
start = 0;
}
if(end < 0) {
end = 0;
}
if(start > end) {
int tmp = start;
start = end;
end = tmp;
}
final int size = list.size();
if(end > size) {
if(start >= size) {
return null;
}
end = size;
}
return list.subList(start, end);
}
/**
* 截取集合的部分
* @param list 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @return 截取后的数组,当开始位置超过最大时,返回null
*/
public static <T> List<T> sub(Collection<T> list, int start, int end) {
if(list == null || list.isEmpty()) {
return null;
}
return sub(new ArrayList<T>(list), start, end);
}
/**
* 数组是否为空
* @param array 数组
* @return 是否为空
*/
public static <T> boolean isEmpty(T[] array) {
return array == null || array.length == 0;
}
/**
* 数组是否为非空
* @param array 数组
* @return 是否为非空
*/
public static <T> boolean isNotEmpty(T[] array) {
return false == isEmpty(array);
}
/**
* 集合是否为空
* @param collection 集合
* @return 是否为空
*/
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
/**
* 集合是否为非空
* @param collection 集合
* @return 是否为非空
*/
public static boolean isNotEmpty(Collection<?> collection) {
return false == isEmpty(collection);
}
/**
* Map是否为空
* @param map 集合
* @return 是否为空
*/
public static boolean isEmpty(Map<?, ?> map) {
return map == null || map.isEmpty();
}
/**
* Map是否为非空
* @param map 集合
* @return 是否为非空
*/
public static <T> boolean isNotEmpty(Map<?, ?> map) {
return false == isEmpty(map);
}
/**
* 映射键值(参考Python的zip()函数)<br>
* 例如:<br>
* keys = [a,b,c,d]<br>
* values = [1,2,3,4]<br>
* 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
* 如果两个数组长度不同,则只对应最短部分
* @param keys 键列表
* @param values 值列表
* @return Map
*/
public static <T, K> Map<T, K> zip(T[] keys, K[] values) {
if(isEmpty(keys) || isEmpty(values)) {
return null;
}
final int size = Math.min(keys.length, values.length);
final Map<T, K> map = new HashMap<T, K>((int)(size / 0.75));
for(int i = 0; i < size; i++) {
map.put(keys[i], values[i]);
}
return map;
}
/**
* 映射键值(参考Python的zip()函数)<br>
* 例如:<br>
* keys = a,b,c,d<br>
* values = 1,2,3,4<br>
* delimiter = ,
* 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
* 如果两个数组长度不同,则只对应最短部分
* @param keys 键列表
* @param values 值列表
* @return Map
*/
public static Map<String, String> zip(String keys, String values, String delimiter) {
return zip(StrKit.split(keys, delimiter), StrKit.split(values, delimiter));
}
/**
* 映射键值(参考Python的zip()函数)<br>
* 例如:<br>
* keys = [a,b,c,d]<br>
* values = [1,2,3,4]<br>
* 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
* 如果两个数组长度不同,则只对应最短部分
* @param keys 键列表
* @param values 值列表
* @return Map
*/
public static <T, K> Map<T, K> zip(Collection<T> keys, Collection<K> values) {
if(isEmpty(keys) || isEmpty(values)) {
return null;
}
final List<T> keyList = new ArrayList<T>(keys);
final List<K> valueList = new ArrayList<K>(values);
final int size = Math.min(keys.size(), values.size());
final Map<T, K> map = new HashMap<T, K>((int)(size / 0.75));
for(int i = 0; i < size; i++) {
map.put(keyList.get(i), valueList.get(i));
}
return map;
}
/**
* 数组中是否包含元素
* @param array 数组
* @param value 被检查的元素
* @return 是否包含
*/
public static <T> boolean contains(T[] array, T value) {
final Class<?> componetType = array.getClass().getComponentType();
boolean isPrimitive = false;
if(null != componetType) {
isPrimitive = componetType.isPrimitive();
}
for (T t : array) {
if(t == value) {
return true;
}else if(false == isPrimitive && null != value && value.equals(t)) {
return true;
}
}
return false;
}
/**
* 将Entry集合转换为HashMap
* @param entryCollection entry集合
* @return Map
*/
public static <T, K> HashMap<T, K> toMap(Collection<Entry<T, K>> entryCollection) {
HashMap<T,K> map = new HashMap<T, K>();
for (Entry<T, K> entry : entryCollection) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
/**
* 将集合转换为排序后的TreeSet
* @param collection 集合
* @param comparator 比较器
* @return treeSet
*/
public static <T> TreeSet<T> toTreeSet(Collection<T> collection, Comparator<T> comparator){
final TreeSet<T> treeSet = new TreeSet<T>(comparator);
for (T t : collection) {
treeSet.add(t);
}
return treeSet;
}
/**
* 排序集合
* @param collection 集合
* @param comparator 比较器
* @return treeSet
*/
public static <T> List<T> sort(Collection<T> collection, Comparator<T> comparator){
List<T> list = new ArrayList<T>(collection);
Collections.sort(list, comparator);
return list;
}
//------------------------------------------------------------------- 基本类型的数组转换为包装类型数组
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Integer[] wrap(int... values){
final int length = values.length;
Integer[] array = new Integer[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Long[] wrap(long... values){
final int length = values.length;
Long[] array = new Long[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Character[] wrap(char... values){
final int length = values.length;
Character[] array = new Character[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Byte[] wrap(byte... values){
final int length = values.length;
Byte[] array = new Byte[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Short[] wrap(short... values){
final int length = values.length;
Short[] array = new Short[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Float[] wrap(float... values){
final int length = values.length;
Float[] array = new Float[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Double[] wrap(double... values){
final int length = values.length;
Double[] array = new Double[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 将基本类型数组包装为包装类型
* @param values 基本类型数组
* @return 包装类型数组
*/
public static Boolean[] wrap(boolean... values){
final int length = values.length;
Boolean[] array = new Boolean[length];
for(int i = 0; i < length; i++){
array[i] = values[i];
}
return array;
}
/**
* 判定给定对象是否为数组类型
* @param obj 对象
* @return 是否为数组类型
*/
public static boolean isArray(Object obj){
return obj.getClass().isArray();
}
/**
* 数组或集合转String
*
* @param obj 集合或数组对象
* @return 数组字符串,与集合转字符串格式相同
*/
public static String toString(Object obj) {
if (null == obj) {
return null;
}
if (isArray(obj)) {
try {
return Arrays.deepToString((Object[]) obj);
} catch (Exception e) {
final String className = obj.getClass().getComponentType().getName();
switch (className) {
case "long":
return Arrays.toString((long[]) obj);
case "int":
return Arrays.toString((int[]) obj);
case "short":
return Arrays.toString((short[]) obj);
case "char":
return Arrays.toString((char[]) obj);
case "byte":
return Arrays.toString((byte[]) obj);
case "boolean":
return Arrays.toString((boolean[]) obj);
case "float":
return Arrays.toString((float[]) obj);
case "double":
return Arrays.toString((double[]) obj);
default:
throw new ToolBoxException(e);
}
}
}
return obj.toString();
}
}
package com.stylefeng.guns.core.util.support;
import java.util.Date;
/**
* 封装java.util.Date
* @author xiaoleilu
*
*/
public class DateTime extends Date{
private static final long serialVersionUID = -5395712593979185936L;
/**
* 转换JDK date为 DateTime
* @param date JDK Date
* @return DateTime
*/
public static DateTime parse(Date date) {
return new DateTime(date);
}
/**
* 当前时间
*/
public DateTime() {
super();
}
/**
* 给定日期的构造
* @param date 日期
*/
public DateTime(Date date) {
this(date.getTime());
}
/**
* 给定日期毫秒数的构造
* @param timeMillis 日期毫秒数
*/
public DateTime(long timeMillis) {
super(timeMillis);
}
@Override
public String toString() {
return DateTimeKit.formatDateTime(this);
}
public String toString(String format) {
return DateTimeKit.format(this, format);
}
/**
* @return 输出精确到毫秒的标准日期形式
*/
public String toMsStr() {
return DateTimeKit.format(this, DateTimeKit.NORM_DATETIME_MS_PATTERN);
}
/**
* @return java.util.Date
*/
public Date toDate() {
return new Date(this.getTime());
}
}
package com.stylefeng.guns.core.util.support;
import com.stylefeng.guns.core.util.support.exception.ToolBoxException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Locale;
/**
* 时间工具类
* @author xiaoleilu
*/
public class DateTimeKit {
/** 毫秒 */
public final static long MS = 1;
/** 每秒钟的毫秒数 */
public final static long SECOND_MS = MS * 1000;
/** 每分钟的毫秒数 */
public final static long MINUTE_MS = SECOND_MS * 60;
/** 每小时的毫秒数 */
public final static long HOUR_MS = MINUTE_MS * 60;
/** 每天的毫秒数 */
public final static long DAY_MS = HOUR_MS * 24;
/** 标准日期格式 */
public final static String NORM_DATE_PATTERN = "yyyy-MM-dd";
/** 标准时间格式 */
public final static String NORM_TIME_PATTERN = "HH:mm:ss";
/** 标准日期时间格式,精确到分 */
public final static String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm";
/** 标准日期时间格式,精确到秒 */
public final static String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/** 标准日期时间格式,精确到毫秒 */
public final static String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
/** HTTP头中日期时间格式 */
public final static String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
/** 标准日期(不含时间)格式化器 */
// private final static SimpleDateFormat NORM_DATE_FORMAT = new SimpleDateFormat(NORM_DATE_PATTERN);
private static ThreadLocal<SimpleDateFormat> NORM_DATE_FORMAT = new ThreadLocal<SimpleDateFormat>(){
synchronized protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(NORM_DATE_PATTERN);
};
};
/** 标准时间格式化器 */
// private final static SimpleDateFormat NORM_TIME_FORMAT = new SimpleDateFormat(NORM_TIME_PATTERN);
private static ThreadLocal<SimpleDateFormat> NORM_TIME_FORMAT = new ThreadLocal<SimpleDateFormat>(){
synchronized protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(NORM_TIME_PATTERN);
};
};
/** 标准日期时间格式化器 */
// private final static SimpleDateFormat NORM_DATETIME_FORMAT = new SimpleDateFormat(NORM_DATETIME_PATTERN);
private static ThreadLocal<SimpleDateFormat> NORM_DATETIME_FORMAT = new ThreadLocal<SimpleDateFormat>(){
synchronized protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(NORM_DATETIME_PATTERN);
};
};
/** HTTP日期时间格式化器 */
// private final static SimpleDateFormat HTTP_DATETIME_FORMAT = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
private static ThreadLocal<SimpleDateFormat> HTTP_DATETIME_FORMAT = new ThreadLocal<SimpleDateFormat>(){
synchronized protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
};
};
/**
* 当前时间,格式 yyyy-MM-dd HH:mm:ss
*
* @return 当前时间的标准形式字符串
*/
public static String now() {
return formatDateTime(new DateTime());
}
/**
* 当前时间long
*
* @param isNano 是否为高精度时间
* @return 时间
*/
public static long current(boolean isNano) {
return isNano ? System.nanoTime() : System.currentTimeMillis();
}
/**
* 当前日期,格式 yyyy-MM-dd
*
* @return 当前日期的标准形式字符串
*/
public static String today() {
return formatDate(new DateTime());
}
/**
* @return 当前月份
*/
public static int thisMonth() {
return month(date());
}
/**
* @return 今年
*/
public static int thisYear() {
return year(date());
}
/**
* @return 当前时间
*/
public static DateTime date() {
return new DateTime();
}
/**
* Long类型时间转为Date
*
* @param date Long类型Date(Unix时间戳)
* @return 时间对象
*/
public static DateTime date(long date) {
return new DateTime(date);
}
/**
* 转换为Calendar对象
*
* @param date 日期对象
* @return Calendar对象
*/
public static Calendar toCalendar(Date date) {
final Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal;
}
/**
* 获得月份,从1月开始计数
*
* @param date 日期
* @return 月份
*/
public static int month(Date date) {
return toCalendar(date).get(Calendar.MONTH) + 1;
}
/**
* 获得年
*
* @param date 日期
* @return 年
*/
public static int year(Date date) {
return toCalendar(date).get(Calendar.YEAR);
}
/**
* 获得季节
*
* @param date 日期
* @return 第几个季节
*/
public static int season(Date date) {
return toCalendar(date).get(Calendar.MONTH) / 3 + 1;
}
/**
* 获得指定日期年份和季节<br>
* 格式:[20131]表示2013年第一季度
*
* @param date 日期
* @return Season ,类似于 20132
*/
public static String yearAndSeason(Date date) {
return yearAndSeason(toCalendar(date));
}
/**
* 获得指定日期区间内的年份和季节<br>
*
* @param startDate 其实日期(包含)
* @param endDate 结束日期(包含)
* @return Season列表 ,元素类似于 20132
*/
public static LinkedHashSet<String> yearAndSeasons(Date startDate, Date endDate) {
final LinkedHashSet<String> seasons = new LinkedHashSet<String>();
if (startDate == null || endDate == null) {
return seasons;
}
final Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
while (true) {
// 如果开始时间超出结束时间,让结束时间为开始时间,处理完后结束循环
if (startDate.after(endDate)) {
startDate = endDate;
}
seasons.add(yearAndSeason(cal));
if (startDate.equals(endDate)) {
break;
}
cal.add(Calendar.MONTH, 3);
startDate = cal.getTime();
}
return seasons;
}
// ------------------------------------ Format start ----------------------------------------------
/**
* 根据特定格式格式化日期
*
* @param date 被格式化的日期
* @param format 格式
* @return 格式化后的字符串
*/
public static String format(Date date, String format) {
return new SimpleDateFormat(format).format(date);
}
/**
* 格式 yyyy-MM-dd HH:mm:ss
*
* @param date 被格式化的日期
* @return 格式化后的日期
*/
public static String formatDateTime(Date date) {
if(null == date){
return null;
}
return NORM_DATETIME_FORMAT.get().format(date);
}
/**
* 格式 yyyy-MM-dd
*
* @param date 被格式化的日期
* @return 格式化后的字符串
*/
public static String formatDate(Date date) {
if(null == date){
return null;
}
return NORM_DATE_FORMAT.get().format(date);
}
/**
* 格式化为Http的标准日期格式
*
* @param date 被格式化的日期
* @return HTTP标准形式日期字符串
*/
public static String formatHttpDate(Date date) {
if(null == date){
return null;
}
return HTTP_DATETIME_FORMAT.get().format(date);
}
// ------------------------------------ Format end ----------------------------------------------
// ------------------------------------ Parse start ----------------------------------------------
/**
* 构建DateTime对象
*
* @param dateStr Date字符串
* @param simpleDateFormat 格式化器
* @return DateTime对象
*/
public static DateTime parse(String dateStr, SimpleDateFormat simpleDateFormat) {
try {
return new DateTime(simpleDateFormat.parse(dateStr));
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Parse [{}] with format [{}] error!", dateStr, simpleDateFormat.toPattern()), e);
}
}
/**
* 将特定格式的日期转换为Date对象
*
* @param dateString 特定格式的日期
* @param format 格式,例如yyyy-MM-dd
* @return 日期对象
*/
public static DateTime parse(String dateString, String format) {
return parse(dateString, new SimpleDateFormat(format));
}
/**
* 格式yyyy-MM-dd HH:mm:ss
*
* @param dateString 标准形式的时间字符串
* @return 日期对象
*/
public static DateTime parseDateTime(String dateString) {
return parse(dateString, NORM_DATETIME_FORMAT.get());
}
/**
* 格式yyyy-MM-dd
*
* @param dateString 标准形式的日期字符串
* @return 日期对象
*/
public static DateTime parseDate(String dateString) {
return parse(dateString, NORM_DATE_FORMAT.get());
}
/**
* 格式HH:mm:ss
*
* @param timeString 标准形式的日期字符串
* @return 日期对象
*/
public static DateTime parseTime(String timeString) {
return parse(timeString, NORM_TIME_FORMAT.get());
}
/**
* 格式:<br>
* 1、yyyy-MM-dd HH:mm:ss<br>
* 2、yyyy-MM-dd<br>
* 3、HH:mm:ss<br>
* 4、yyyy-MM-dd HH:mm 5、yyyy-MM-dd HH:mm:ss.SSS
*
* @param dateStr 日期字符串
* @return 日期
*/
public static DateTime parse(String dateStr) {
if (null == dateStr) {
return null;
}
dateStr = dateStr.trim();
int length = dateStr.length();
try {
if (length == NORM_DATETIME_PATTERN.length()) {
return parseDateTime(dateStr);
} else if (length == NORM_DATE_PATTERN.length()) {
return parseDate(dateStr);
} else if (length == NORM_TIME_PATTERN.length()) {
return parseTime(dateStr);
} else if (length == NORM_DATETIME_MINUTE_PATTERN.length()) {
return parse(dateStr, NORM_DATETIME_MINUTE_PATTERN);
} else if (length >= NORM_DATETIME_MS_PATTERN.length() - 2) {
return parse(dateStr, NORM_DATETIME_MS_PATTERN);
}
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Parse [{}] with format normal error!", dateStr));
}
// 没有更多匹配的时间格式
throw new ToolBoxException(StrKit.format(" [{}] format is not fit for date pattern!", dateStr));
}
// ------------------------------------ Parse end ----------------------------------------------
// ------------------------------------ Offset start ----------------------------------------------
/**
* 获取某天的开始时间
*
* @param date 日期
* @return 某天的开始时间
*/
public static DateTime getBeginTimeOfDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return new DateTime(calendar.getTime());
}
/**
* 获取某天的结束时间
*
* @param date 日期
* @return 某天的结束时间
*/
public static DateTime getEndTimeOfDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
return new DateTime(calendar.getTime());
}
/**
* 昨天
*
* @return 昨天
*/
public static DateTime yesterday() {
return offsiteDay(new DateTime(), -1);
}
/**
* 上周
*
* @return 上周
*/
public static DateTime lastWeek() {
return offsiteWeek(new DateTime(), -1);
}
/**
* 上个月
*
* @return 上个月
*/
public static DateTime lastMouth() {
return offsiteMonth(new DateTime(), -1);
}
/**
* 偏移天
*
* @param date 日期
* @param offsite 偏移天数,正数向未来偏移,负数向历史偏移
* @return 偏移后的日期
*/
public static DateTime offsiteDay(Date date, int offsite) {
return offsiteDate(date, Calendar.DAY_OF_YEAR, offsite);
}
/**
* 偏移周
*
* @param date 日期
* @param offsite 偏移周数,正数向未来偏移,负数向历史偏移
* @return 偏移后的日期
*/
public static DateTime offsiteWeek(Date date, int offsite) {
return offsiteDate(date, Calendar.WEEK_OF_YEAR, offsite);
}
/**
* 偏移月
*
* @param date 日期
* @param offsite 偏移月数,正数向未来偏移,负数向历史偏移
* @return 偏移后的日期
*/
public static DateTime offsiteMonth(Date date, int offsite) {
return offsiteDate(date, Calendar.MONTH, offsite);
}
/**
* 获取指定日期偏移指定时间后的时间
*
* @param date 基准日期
* @param calendarField 偏移的粒度大小(小时、天、月等)使用Calendar中的常数
* @param offsite 偏移量,正数为向后偏移,负数为向前偏移
* @return 偏移后的日期
*/
public static DateTime offsiteDate(Date date, int calendarField, int offsite) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(calendarField, offsite);
return new DateTime(cal.getTime());
}
// ------------------------------------ Offset end ----------------------------------------------
/**
* 判断两个日期相差的时长<br/>
* 返回 minuend - subtrahend 的差
*
* @param subtrahend 减数日期
* @param minuend 被减数日期
* @param diffField 相差的选项:相差的天、小时
* @return 日期差
*/
public static long diff(Date subtrahend, Date minuend, long diffField) {
long diff = minuend.getTime() - subtrahend.getTime();
return diff / diffField;
}
/**
* 计时,常用于记录某段代码的执行时间,单位:纳秒
*
* @param preTime 之前记录的时间
* @return 时间差,纳秒
*/
public static long spendNt(long preTime) {
return System.nanoTime() - preTime;
}
/**
* 计时,常用于记录某段代码的执行时间,单位:毫秒
*
* @param preTime 之前记录的时间
* @return 时间差,毫秒
*/
public static long spendMs(long preTime) {
return System.currentTimeMillis() - preTime;
}
/**
* 格式化成yyMMddHHmm后转换为int型
*
* @param date 日期
* @return int
*/
public static int toIntSecond(Date date) {
return Integer.parseInt(format(date, "yyMMddHHmm"));
}
/**
* 计算指定指定时间区间内的周数
*
* @param start 开始时间
* @param end 结束时间
* @return 周数
*/
public static int weekCount(Date start, Date end) {
final Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(start);
final Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(end);
final int startWeekofYear = startCalendar.get(Calendar.WEEK_OF_YEAR);
final int endWeekofYear = endCalendar.get(Calendar.WEEK_OF_YEAR);
int count = endWeekofYear - startWeekofYear + 1;
if (Calendar.SUNDAY != startCalendar.get(Calendar.DAY_OF_WEEK)) {
count--;
}
return count;
}
/**
* 计时器<br>
* 计算某个过程话费的时间,精确到毫秒
*
* @return Timer
*/
public static Timer timer() {
return new Timer();
}
/**
* 生日转为年龄,计算法定年龄
* @param birthDay 生日,标准日期字符串
* @return 年龄
* @throws Exception
*/
public static int ageOfNow(String birthDay) {
return ageOfNow(parse(birthDay));
}
/**
* 生日转为年龄,计算法定年龄
* @param birthDay 生日
* @return 年龄
* @throws Exception
*/
public static int ageOfNow(Date birthDay) {
return age(birthDay,date());
}
/**
* 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
* @param birthDay 生日
* @param dateToCompare 需要对比的日期
* @return 年龄
* @throws Exception
*/
public static int age(Date birthDay, Date dateToCompare) {
Calendar cal = Calendar.getInstance();
cal.setTime(dateToCompare);
if (cal.before(birthDay)) {
throw new IllegalArgumentException(StrKit.format("Birthday is after date {}!", formatDate(dateToCompare)));
}
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(birthDay);
int age = year - cal.get(Calendar.YEAR);
int monthBirth = cal.get(Calendar.MONTH);
if (month == monthBirth) {
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
if (dayOfMonth < dayOfMonthBirth) {
//如果生日在当月,但是未达到生日当天的日期,年龄减一
age--;
}
} else if (month < monthBirth){
//如果当前月份未达到生日的月份,年龄计算减一
age--;
}
return age;
}
/**
* 计时器<br>
* 计算某个过程话费的时间,精确到毫秒
*
* @author Looly
*
*/
public static class Timer {
private long time;
private boolean isNano;
public Timer() {
this(false);
}
public Timer(boolean isNano) {
this.isNano = isNano;
start();
}
/**
* @return 开始计时并返回当前时间
*/
public long start() {
time = current(isNano);
return time;
}
/**
* @return 重新计时并返回从开始到当前的持续时间
*/
public long durationRestart() {
long now = current(isNano);
long d = now - time;
time = now;
return d;
}
/**
* @return 从开始到当前的持续时间
*/
public long duration() {
return current(isNano) - time;
}
}
// ------------------------------------------------------------------------ Private method start
/**
* 获得指定日期年份和季节<br>
* 格式:[20131]表示2013年第一季度
*
* @param cal 日期
*/
private static String yearAndSeason(Calendar cal) {
return new StringBuilder().append(cal.get(Calendar.YEAR)).append(cal.get(Calendar.MONTH) / 3 + 1).toString();
}
// ------------------------------------------------------------------------ Private method end
}
package com.stylefeng.guns.core.util.support;
import java.nio.charset.Charset;
/**
* 十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制,一般用数字0到9和字母A到F表示(其中:A~F即10~15)。<br>
* 例如十进制数57,在二进制写作111001,在16进制写作39。<br>
* 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20<br>
*
* 参考:https://my.oschina.net/xinxingegeya/blog/287476
*
* @author Looly
*
*/
public class HexKit {
/**
* 用于建立十六进制字符的输出的小写字符数组
*/
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 用于建立十六进制字符的输出的大写字符数组
*/
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
//---------------------------------------------------------------------------------------------------- encode
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @return 十六进制char[]
*/
public static char[] encodeHex(byte[] data) {
return encodeHex(data, true);
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param str 字符串
* @param charset 编码
* @return 十六进制char[]
*/
public static char[] encodeHex(String str, Charset charset) {
return encodeHex(StrKit.getBytes(str, charset), true);
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
* @return 十六进制char[]
*/
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data) {
return encodeHexStr(data, true);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
//---------------------------------------------------------------------------------------------------- decode
/**
* 将十六进制字符数组转换为字符串
*
* @param hexStr 十六进制String
* @param charset 编码
* @return 字符串
*/
public static String decodeHexStr(String hexStr, Charset charset) {
if(StrKit.isEmpty(hexStr)){
return hexStr;
}
return decodeHexStr(hexStr.toCharArray(), charset);
}
/**
* 将十六进制字符数组转换为字符串
*
* @param hexData 十六进制char[]
* @param charset 编码
* @return 字符串
*/
public static String decodeHexStr(char[] hexData, Charset charset) {
return StrKit.str(decodeHex(hexData), charset);
}
/**
* 将十六进制字符数组转换为字节数组
*
* @param hexData 十六进制char[]
* @return byte[]
* @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
*/
public static byte[] decodeHex(char[] hexData) {
int len = hexData.length;
if ((len & 0x01) != 0) {
throw new RuntimeException("Odd number of characters.");
}
byte[] out = new byte[len >> 1];
// two characters form the hex value.
for (int i = 0, j = 0; j < len; i++) {
int f = toDigit(hexData[j], j) << 4;
j++;
f = f | toDigit(hexData[j], j);
j++;
out[i] = (byte) (f & 0xFF);
}
return out;
}
//---------------------------------------------------------------------------------------- Private method start
/**
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @param toDigits 用于控制输出的char[]
* @return 十六进制String
*/
private static String encodeHexStr(byte[] data, char[] toDigits) {
return new String(encodeHex(data, toDigits));
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @param toDigits 用于控制输出的char[]
* @return 十六进制char[]
*/
private static char[] encodeHex(byte[] data, char[] toDigits) {
int l = data.length;
char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
/**
* 将十六进制字符转换成一个整数
*
* @param ch 十六进制char
* @param index 十六进制字符在字符数组中的位置
* @return 一个整数
* @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
*/
private static int toDigit(char ch, int index) {
int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
}
return digit;
}
//---------------------------------------------------------------------------------------- Private method end
/**
* 2进制转16进制
* @param bString 2进制字符串
* @return
*/
public static String binary2Hex(String bString) {
if (bString == null || bString.equals("") || bString.length() % 8 != 0)
return null;
StringBuffer tmp = new StringBuffer();
int iTmp = 0;
for (int i = 0; i < bString.length(); i += 4) {
iTmp = 0;
for (int j = 0; j < 4; j++) {
iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
}
tmp.append(Integer.toHexString(iTmp));
}
return tmp.toString();
}
/**
* 16进制转2进制
* @param hexString
* @return
*/
public static String hex2Binary(String hexString) {
if (hexString == null || hexString.length() % 2 != 0)
return null;
String bString = "", tmp;
for (int i = 0; i < hexString.length(); i++) {
tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
bString += tmp.substring(tmp.length() - 4);
}
return bString;
}
/**
* 将二进制转换成16进制
* @param buf
* @return
*/
public static String binary2Hex(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] hex2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
/**
* Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util.support;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HttpKit {
public static String getIp(){
return HttpKit.getRequest().getRemoteHost();
}
/**
* 获取所有请求的值
*/
public static Map<String, String> getRequestParameters() {
HashMap<String, String> values = new HashMap<>();
HttpServletRequest request = HttpKit.getRequest();
Enumeration enums = request.getParameterNames();
while ( enums.hasMoreElements()){
String paramName = (String) enums.nextElement();
String paramValue = request.getParameter(paramName);
values.put(paramName, paramValue);
}
return values;
}
/**
* 获取 HttpServletRequest
*/
public static HttpServletResponse getResponse() {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
return response;
}
/**
* 获取 包装防Xss Sql注入的 HttpServletRequest
* @return request
*/
public static HttpServletRequest getRequest() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
return new WafRequestWrapper(request);
}
/**
* 向指定URL发送GET方法的请求
*
* @param url 发送请求的URL
* @param param 请求参数
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, Map<String, String> param) {
String result = "";
BufferedReader in = null;
try {
String para = "";
for (String key : param.keySet()) {
para += (key + "=" + param.get(key) + "&");
}
if (para.lastIndexOf("&") > 0) {
para = para.substring(0, para.length() - 1);
}
String urlNameString = url + "?" + para;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, Map<String, String> param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
String para = "";
for (String key : param.keySet()) {
para += (key + "=" + param.get(key) + "&");
}
if (para.lastIndexOf("&") > 0) {
para = para.substring(0, para.length() - 1);
}
String urlNameString = url + "?" + para;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
}
package com.stylefeng.guns.core.util.support;
/**
* 一些通用的函数
*
* @author Looly
*
*/
public class ObjectKit {
/**
* 比较两个对象是否相等。<br>
* 相同的条件有两个,满足其一即可:<br>
* 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
*
* @param obj1 对象1
* @param obj2 对象2
* @return 是否相等
*/
public static boolean equals(Object obj1, Object obj2) {
return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
}
}
package com.stylefeng.guns.core.util.support;
/**
* 分页工具类
*
* @author xiaoleilu
*
*/
public class PageKit {
/**
* 将页数和每页条目数转换为开始位置和结束位置<br>
* 此方法用于不包括结束位置的分页方法<br>
* 例如:<br>
* 页码:1,每页10 -> [0, 10]<br>
* 页码:2,每页10 -> [10, 20]<br>
* 。。。<br>
*
* @param pageNo
* 页码(从1计数)
* @param countPerPage
* 每页条目数
* @return 第一个数为开始位置,第二个数为结束位置
*/
public static int[] transToStartEnd(int pageNo, int countPerPage) {
if (pageNo < 1) {
pageNo = 1;
}
if (countPerPage < 1) {
countPerPage = 0;
// LogKit.warn("Count per page [" + countPerPage + "] is not valid!");
}
int start = (pageNo - 1) * countPerPage;
int end = start + countPerPage;
return new int[] { start, end };
}
/**
* 根据总数计算总页数
*
* @param totalCount
* 总数
* @param numPerPage
* 每页数
* @return 总页数
*/
public static int totalPage(int totalCount, int numPerPage) {
if (numPerPage == 0) {
return 0;
}
return totalCount % numPerPage == 0 ? (totalCount / numPerPage)
: (totalCount / numPerPage + 1);
}
}
package com.stylefeng.guns.core.util.support;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* 字符串工具类
*
* @author xiaoleilu
*
*/
public class StrKit {
public static final String SPACE = " ";
public static final String DOT = ".";
public static final String SLASH = "/";
public static final String BACKSLASH = "\\";
public static final String EMPTY = "";
public static final String CRLF = "\r\n";
public static final String NEWLINE = "\n";
public static final String UNDERLINE = "_";
public static final String COMMA = ",";
public static final String HTML_NBSP = "&nbsp;";
public static final String HTML_AMP = "&amp";
public static final String HTML_QUOTE = "&quot;";
public static final String HTML_LT = "&lt;";
public static final String HTML_GT = "&gt;";
public static final String EMPTY_JSON = "{}";
/**
* 首字母变小写
*/
public static String firstCharToLowerCase(String str) {
char firstChar = str.charAt(0);
if (firstChar >= 'A' && firstChar <= 'Z') {
char[] arr = str.toCharArray();
arr[0] += ('a' - 'A');
return new String(arr);
}
return str;
}
/**
* 首字母变大写
*/
public static String firstCharToUpperCase(String str) {
char firstChar = str.charAt(0);
if (firstChar >= 'a' && firstChar <= 'z') {
char[] arr = str.toCharArray();
arr[0] -= ('a' - 'A');
return new String(arr);
}
return str;
}
// ------------------------------------------------------------------------ Blank
/**
* 字符串是否为空白 空白的定义如下: <br>
* 1、为null <br>
* 2、为不可见字符(如空格)<br>
* 3、""<br>
*
* @param str 被检测的字符串
* @return 是否为空
*/
public static boolean isBlank(String str) {
int length;
if ((str == null) || ((length = str.length()) == 0)) {
return true;
}
for (int i = 0; i < length; i++) {
// 只要有一个非空字符即为非空字符串
if (false == Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 字符串是否为非空白 空白的定义如下: <br>
* 1、不为null <br>
* 2、不为不可见字符(如空格)<br>
* 3、不为""<br>
*
* @param str 被检测的字符串
* @return 是否为非空
*/
public static boolean notBlank(String str) {
return false == isBlank(str);
}
/**
* 是否包含空字符串
*
* @param strs 字符串列表
* @return 是否包含空字符串
*/
public static boolean hasBlank(String... strs) {
if (CollectionKit.isEmpty(strs)) {
return true;
}
for (String str : strs) {
if (isBlank(str)) {
return true;
}
}
return false;
}
/**
* 给定所有字符串是否为空白
*
* @param strs 字符串
* @return 所有字符串是否为空白
*/
public static boolean isAllBlank(String... strs) {
if (CollectionKit.isEmpty(strs)) {
return true;
}
for (String str : strs) {
if (notBlank(str)) {
return false;
}
}
return true;
}
// ------------------------------------------------------------------------ Empty
/**
* 字符串是否为空,空的定义如下 1、为null <br>
* 2、为""<br>
*
* @param str 被检测的字符串
* @return 是否为空
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* 字符串是否为非空白 空白的定义如下: <br>
* 1、不为null <br>
* 2、不为""<br>
*
* @param str 被检测的字符串
* @return 是否为非空
*/
public static boolean isNotEmpty(String str) {
return false == isEmpty(str);
}
/**
* 当给定字符串为null时,转换为Empty
*
* @param str 被转换的字符串
* @return 转换后的字符串
*/
public static String nullToEmpty(String str) {
return nullToDefault(str, EMPTY);
}
/**
* 如果字符串是<code>null</code>,则返回指定默认字符串,否则返回字符串本身。
*
* <pre>
* nullToDefault(null, &quot;default&quot;) = &quot;default&quot;
* nullToDefault(&quot;&quot;, &quot;default&quot;) = &quot;&quot;
* nullToDefault(&quot; &quot;, &quot;default&quot;) = &quot; &quot;
* nullToDefault(&quot;bat&quot;, &quot;default&quot;) = &quot;bat&quot;
* </pre>
*
* @param str 要转换的字符串
* @param defaultStr 默认字符串
*
* @return 字符串本身或指定的默认字符串
*/
public static String nullToDefault(String str, String defaultStr) {
return (str == null) ? defaultStr : str;
}
/**
* 当给定字符串为空字符串时,转换为<code>null</code>
*
* @param str 被转换的字符串
* @return 转换后的字符串
*/
public static String emptyToNull(String str) {
return isEmpty(str) ? null : str;
}
/**
* 是否包含空字符串
*
* @param strs 字符串列表
* @return 是否包含空字符串
*/
public static boolean hasEmpty(String... strs) {
if (CollectionKit.isEmpty(strs)) {
return true;
}
for (String str : strs) {
if (isEmpty(str)) {
return true;
}
}
return false;
}
/**
* 是否全部为空字符串
*
* @param strs 字符串列表
* @return 是否全部为空字符串
*/
public static boolean isAllEmpty(String... strs) {
if (CollectionKit.isEmpty(strs)) {
return true;
}
for (String str : strs) {
if (isNotEmpty(str)) {
return false;
}
}
return true;
}
// ------------------------------------------------------------------------ Trim
/**
* 除去字符串头尾部的空白,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* trim(null) = null
* trim(&quot;&quot;) = &quot;&quot;
* trim(&quot; &quot;) = &quot;&quot;
* trim(&quot;abc&quot;) = &quot;abc&quot;
* trim(&quot; abc &quot;) = &quot;abc&quot;
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
public static String trim(String str) {
return (null == str) ? null : trim(str, 0);
}
/**
* 给定字符串数组全部做去首尾空格
*
* @param strs 字符串数组
*/
public static void trim(String[] strs) {
if (null == strs) {
return;
}
String str;
for (int i = 0; i < strs.length; i++) {
str = strs[i];
if (null != str) {
strs[i] = str.trim();
}
}
}
/**
* 除去字符串头部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* trimStart(null) = null
* trimStart(&quot;&quot;) = &quot;&quot;
* trimStart(&quot;abc&quot;) = &quot;abc&quot;
* trimStart(&quot; abc&quot;) = &quot;abc&quot;
* trimStart(&quot;abc &quot;) = &quot;abc &quot;
* trimStart(&quot; abc &quot;) = &quot;abc &quot;
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimStart(String str) {
return trim(str, -1);
}
/**
* 除去字符串尾部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* trimEnd(null) = null
* trimEnd(&quot;&quot;) = &quot;&quot;
* trimEnd(&quot;abc&quot;) = &quot;abc&quot;
* trimEnd(&quot; abc&quot;) = &quot; abc&quot;
* trimEnd(&quot;abc &quot;) = &quot;abc&quot;
* trimEnd(&quot; abc &quot;) = &quot; abc&quot;
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimEnd(String str) {
return trim(str, 1);
}
/**
* 除去字符串头尾部的空白符,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* @param str 要处理的字符串
* @param mode <code>-1</code>表示trimStart,<code>0</code>表示trim全部, <code>1</code>表示trimEnd
*
* @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
public static String trim(String str, int mode) {
if (str == null) {
return null;
}
int length = str.length();
int start = 0;
int end = length;
// 扫描字符串头部
if (mode <= 0) {
while ((start < end) && (Character.isWhitespace(str.charAt(start)))) {
start++;
}
}
// 扫描字符串尾部
if (mode >= 0) {
while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) {
end--;
}
}
if ((start > 0) || (end < length)) {
return str.substring(start, end);
}
return str;
}
/**
* 是否以指定字符串开头
* @param str 被监测字符串
* @param prefix 开头字符串
* @param isIgnoreCase 是否忽略大小写
* @return 是否以指定字符串开头
*/
public static boolean startWith(String str, String prefix, boolean isIgnoreCase){
if(isIgnoreCase){
return str.toLowerCase().startsWith(prefix.toLowerCase());
}else{
return str.startsWith(prefix);
}
}
/**
* 是否以指定字符串结尾
* @param str 被监测字符串
* @param suffix 结尾字符串
* @param isIgnoreCase 是否忽略大小写
* @return 是否以指定字符串结尾
*/
public static boolean endWith(String str, String suffix, boolean isIgnoreCase){
if(isIgnoreCase){
return str.toLowerCase().endsWith(suffix.toLowerCase());
}else{
return str.endsWith(suffix);
}
}
/**
* 是否包含特定字符,忽略大小写,如果给定两个参数都为<code>null</code>,返回true
* @param str 被检测字符串
* @param testStr 被测试是否包含的字符串
* @return 是否包含
*/
public static boolean containsIgnoreCase(String str, String testStr){
if(null == str){
//如果被监测字符串和
return null == testStr;
}
return str.toLowerCase().contains(testStr.toLowerCase());
}
/**
* 获得set或get方法对应的标准属性名<br/>
* 例如:setName 返回 name
*
* @param getOrSetMethodName
* @return 如果是set或get方法名,返回field, 否则null
*/
public static String getGeneralField(String getOrSetMethodName) {
if (getOrSetMethodName.startsWith("get") || getOrSetMethodName.startsWith("set")) {
return cutPreAndLowerFirst(getOrSetMethodName, 3);
}
return null;
}
/**
* 生成set方法名<br/>
* 例如:name 返回 setName
*
* @param fieldName 属性名
* @return setXxx
*/
public static String genSetter(String fieldName) {
return upperFirstAndAddPre(fieldName, "set");
}
/**
* 生成get方法名
*
* @param fieldName 属性名
* @return getXxx
*/
public static String genGetter(String fieldName) {
return upperFirstAndAddPre(fieldName, "get");
}
/**
* 去掉首部指定长度的字符串并将剩余字符串首字母小写<br/>
* 例如:str=setName, preLength=3 -> return name
*
* @param str 被处理的字符串
* @param preLength 去掉的长度
* @return 处理后的字符串,不符合规范返回null
*/
public static String cutPreAndLowerFirst(String str, int preLength) {
if (str == null) {
return null;
}
if (str.length() > preLength) {
char first = Character.toLowerCase(str.charAt(preLength));
if (str.length() > preLength + 1) {
return first + str.substring(preLength + 1);
}
return String.valueOf(first);
}
return null;
}
/**
* 原字符串首字母大写并在其首部添加指定字符串 例如:str=name, preString=get -> return getName
*
* @param str 被处理的字符串
* @param preString 添加的首部
* @return 处理后的字符串
*/
public static String upperFirstAndAddPre(String str, String preString) {
if (str == null || preString == null) {
return null;
}
return preString + upperFirst(str);
}
/**
* 大写首字母<br>
* 例如:str = name, return Name
*
* @param str 字符串
* @return 字符串
*/
public static String upperFirst(String str) {
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
/**
* 小写首字母<br>
* 例如:str = Name, return name
*
* @param str 字符串
* @return 字符串
*/
public static String lowerFirst(String str) {
if(isBlank(str)){
return str;
}
return Character.toLowerCase(str.charAt(0)) + str.substring(1);
}
/**
* 去掉指定前缀
*
* @param str 字符串
* @param prefix 前缀
* @return 切掉后的字符串,若前缀不是 preffix, 返回原字符串
*/
public static String removePrefix(String str, String prefix) {
if(isEmpty(str) || isEmpty(prefix)){
return str;
}
if (str.startsWith(prefix)) {
return str.substring(prefix.length());
}
return str;
}
/**
* 忽略大小写去掉指定前缀
*
* @param str 字符串
* @param prefix 前缀
* @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串
*/
public static String removePrefixIgnoreCase(String str, String prefix) {
if(isEmpty(str) || isEmpty(prefix)){
return str;
}
if (str.toLowerCase().startsWith(prefix.toLowerCase())) {
return str.substring(prefix.length());
}
return str;
}
/**
* 去掉指定后缀
*
* @param str 字符串
* @param suffix 后缀
* @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
*/
public static String removeSuffix(String str, String suffix) {
if(isEmpty(str) || isEmpty(suffix)){
return str;
}
if (str.endsWith(suffix)) {
return str.substring(0, str.length() - suffix.length());
}
return str;
}
/**
* 获得字符串对应byte数组
* @param str 字符串
* @param charset 编码,如果为<code>null</code>使用系统默认编码
* @return bytes
*/
public static byte[] getBytes(String str, Charset charset){
if(null == str){
return null;
}
return null == charset ? str.getBytes() : str.getBytes(charset);
}
/**
* 忽略大小写去掉指定后缀
*
* @param str 字符串
* @param suffix 后缀
* @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
*/
public static String removeSuffixIgnoreCase(String str, String suffix) {
if(isEmpty(str) || isEmpty(suffix)){
return str;
}
if (str.toLowerCase().endsWith(suffix.toLowerCase())) {
return str.substring(0, str.length() - suffix.length());
}
return str;
}
/**
* 如果给定字符串不是以prefix开头的,在开头补充 prefix
* @param str 字符串
* @param prefix 前缀
* @return 补充后的字符串
*/
public static String addPrefixIfNot(String str, String prefix){
if(isEmpty(str) || isEmpty(prefix)){
return str;
}
if(false == str.startsWith(prefix)){
str = prefix + str;
}
return str;
}
/**
* 如果给定字符串不是以suffix结尾的,在尾部补充 suffix
* @param str 字符串
* @param suffix 后缀
* @return 补充后的字符串
*/
public static String addSuffixIfNot(String str, String suffix){
if(isEmpty(str) || isEmpty(suffix)){
return str;
}
if(false == str.endsWith(suffix)){
str += suffix;
}
return str;
}
/**
* 清理空白字符
*
* @param str 被清理的字符串
* @return 清理后的字符串
*/
public static String cleanBlank(String str) {
if (str == null) {
return null;
}
return str.replaceAll("\\s*", EMPTY);
}
/**
* 切分字符串<br>
* a#b#c -> [a,b,c] <br>
* a##b#c -> [a,"",b,c]
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @return 切分后的集合
*/
public static List<String> split(String str, char separator) {
return split(str, separator, 0);
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数
* @return 切分后的集合
*/
public static List<String> split(String str, char separator, int limit) {
if (str == null) {
return null;
}
List<String> list = new ArrayList<String>(limit == 0 ? 16 : limit);
if (limit == 1) {
list.add(str);
return list;
}
boolean isNotEnd = true; // 未结束切分的标志
int strLen = str.length();
StringBuilder sb = new StringBuilder(strLen);
for (int i = 0; i < strLen; i++) {
char c = str.charAt(i);
if (isNotEnd && c == separator) {
list.add(sb.toString());
// 清空StringBuilder
sb.delete(0, sb.length());
// 当达到切分上限-1的量时,将所剩字符全部作为最后一个串
if (limit != 0 && list.size() == limit - 1) {
isNotEnd = false;
}
} else {
sb.append(c);
}
}
list.add(sb.toString());// 加入尾串
return list;
}
/**
* 切分字符串<br>
* from jodd
*
* @param str 被切分的字符串
* @param delimiter 分隔符
* @return 字符串
*/
public static String[] split(String str, String delimiter) {
if (str == null) {
return null;
}
if (str.trim().length() == 0) {
return new String[] { str };
}
int dellen = delimiter.length(); // del length
int maxparts = (str.length() / dellen) + 2; // one more for the last
int[] positions = new int[maxparts];
int i, j = 0;
int count = 0;
positions[0] = -dellen;
while ((i = str.indexOf(delimiter, j)) != -1) {
count++;
positions[count] = i;
j = i + dellen;
}
count++;
positions[count] = str.length();
String[] result = new String[count];
for (i = 0; i < count; i++) {
result[i] = str.substring(positions[i] + dellen, positions[i + 1]);
}
return result;
}
/**
* 改进JDK subString<br>
* index从0开始计算,最后一个字符为-1<br>
* 如果from和to位置一样,返回 "" <br>
* 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length<br>
* 如果经过修正的index中from大于to,则互换from和to
* example: <br>
* abcdefgh 2 3 -> c <br>
* abcdefgh 2 -3 -> cde <br>
*
* @param string String
* @param fromIndex 开始的index(包括)
* @param toIndex 结束的index(不包括)
* @return 字串
*/
public static String sub(String string, int fromIndex, int toIndex) {
int len = string.length();
if (fromIndex < 0) {
fromIndex = len + fromIndex;
if(fromIndex < 0 ) {
fromIndex = 0;
}
} else if(fromIndex >= len) {
fromIndex = len -1;
}
if (toIndex < 0) {
toIndex = len + toIndex;
if(toIndex < 0) {
toIndex = len;
}
} else if(toIndex > len) {
toIndex = len;
}
if (toIndex < fromIndex) {
int tmp = fromIndex;
fromIndex = toIndex;
toIndex = tmp;
}
if (fromIndex == toIndex) {
return EMPTY;
}
char[] strArray = string.toCharArray();
char[] newStrArray = Arrays.copyOfRange(strArray, fromIndex, toIndex);
return new String(newStrArray);
}
/**
* 切割前部分
*
* @param string 字符串
* @param toIndex 切割到的位置(不包括)
* @return 切割后的字符串
*/
public static String subPre(String string, int toIndex) {
return sub(string, 0, toIndex);
}
/**
* 切割后部分
*
* @param string 字符串
* @param fromIndex 切割开始的位置(包括)
* @return 切割后的字符串
*/
public static String subSuf(String string, int fromIndex) {
if (isEmpty(string)) {
return null;
}
return sub(string, fromIndex, string.length());
}
/**
* 给定字符串是否被字符包围
*
* @param str 字符串
* @param prefix 前缀
* @param suffix 后缀
* @return 是否包围,空串不包围
*/
public static boolean isSurround(String str, String prefix, String suffix) {
if (StrKit.isBlank(str)) {
return false;
}
if (str.length() < (prefix.length() + suffix.length())) {
return false;
}
return str.startsWith(prefix) && str.endsWith(suffix);
}
/**
* 给定字符串是否被字符包围
*
* @param str 字符串
* @param prefix 前缀
* @param suffix 后缀
* @return 是否包围,空串不包围
*/
public static boolean isSurround(String str, char prefix, char suffix) {
if (StrKit.isBlank(str)) {
return false;
}
if (str.length() < 2) {
return false;
}
return str.charAt(0) == prefix && str.charAt(str.length() - 1) == suffix;
}
/**
* 重复某个字符
*
* @param c 被重复的字符
* @param count 重复的数目
* @return 重复字符字符串
*/
public static String repeat(char c, int count) {
char[] result = new char[count];
for (int i = 0; i < count; i++) {
result[i] = c;
}
return new String(result);
}
/**
* 重复某个字符串
*
* @param str 被重复的字符
* @param count 重复的数目
* @return 重复字符字符串
*/
public static String repeat(String str, int count) {
// 检查
final int len = str.length();
final long longSize = (long) len * (long) count;
final int size = (int) longSize;
if (size != longSize) {
throw new ArrayIndexOutOfBoundsException("Required String length is too large: " + longSize);
}
final char[] array = new char[size];
str.getChars(0, len, array, 0);
int n;
for (n = len; n < size - n; n <<= 1) {// n <<= 1相当于n *2
System.arraycopy(array, 0, array, n, n);
}
System.arraycopy(array, 0, array, n, size - n);
return new String(array);
}
/**
* 比较两个字符串(大小写敏感)。
*
* <pre>
* equals(null, null) = true
* equals(null, &quot;abc&quot;) = false
* equals(&quot;abc&quot;, null) = false
* equals(&quot;abc&quot;, &quot;abc&quot;) = true
* equals(&quot;abc&quot;, &quot;ABC&quot;) = false
* </pre>
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
*
* @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
*/
public static boolean equals(String str1, String str2) {
if (str1 == null) {
return str2 == null;
}
return str1.equals(str2);
}
/**
* 比较两个字符串(大小写不敏感)。
*
* <pre>
* equalsIgnoreCase(null, null) = true
* equalsIgnoreCase(null, &quot;abc&quot;) = false
* equalsIgnoreCase(&quot;abc&quot;, null) = false
* equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
* equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
* </pre>
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
*
* @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
*/
public static boolean equalsIgnoreCase(String str1, String str2) {
if (str1 == null) {
return str2 == null;
}
return str1.equalsIgnoreCase(str2);
}
/**
* 格式化文本, {} 表示占位符<br>
* 例如:format("aaa {} ccc", "bbb") ----> aaa bbb ccc
*
* @param template 文本模板,被替换的部分用 {} 表示
* @param values 参数值
* @return 格式化后的文本
*/
public static String format(String template, Object... values) {
if (CollectionKit.isEmpty(values) || isBlank(template)) {
return template;
}
final StringBuilder sb = new StringBuilder();
final int length = template.length();
int valueIndex = 0;
char currentChar;
for (int i = 0; i < length; i++) {
if (valueIndex >= values.length) {
sb.append(sub(template, i, length));
break;
}
currentChar = template.charAt(i);
if (currentChar == '{') {
final char nextChar = template.charAt(++i);
if (nextChar == '}') {
sb.append(values[valueIndex++]);
} else {
sb.append('{').append(nextChar);
}
} else {
sb.append(currentChar);
}
}
return sb.toString();
}
/**
* 格式化文本,使用 {varName} 占位<br>
* map = {a: "aValue", b: "bValue"}
* format("{a} and {b}", map) ----> aValue and bValue
*
* @param template 文本模板,被替换的部分用 {key} 表示
* @param map 参数值对
* @return 格式化后的文本
*/
public static String format(String template, Map<?, ?> map) {
if (null == map || map.isEmpty()) {
return template;
}
for (Entry<?, ?> entry : map.entrySet()) {
template = template.replace("{" + entry.getKey() + "}", entry.getValue().toString());
}
return template;
}
/**
* 编码字符串
*
* @param str 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 编码后的字节码
*/
public static byte[] bytes(String str, String charset) {
return bytes(str, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset));
}
/**
* 编码字符串
*
* @param str 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 编码后的字节码
*/
public static byte[] bytes(String str, Charset charset) {
if (str == null) {
return null;
}
if (null == charset) {
return str.getBytes();
}
return str.getBytes(charset);
}
/**
* 将byte数组转为字符串
*
* @param bytes byte数组
* @param charset 字符集
* @return 字符串
*/
public static String str(byte[] bytes, String charset) {
return str(bytes, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset));
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 解码后的字符串
*/
public static String str(byte[] data, Charset charset) {
if (data == null) {
return null;
}
if (null == charset) {
return new String(data);
}
return new String(data, charset);
}
/**
* 将编码的byteBuffer数据转换为字符串
* @param data 数据
* @param charset 字符集,如果为空使用当前系统字符集
* @return 字符串
*/
public static String str(ByteBuffer data, String charset){
if(data == null) {
return null;
}
return str(data, Charset.forName(charset));
}
/**
* 将编码的byteBuffer数据转换为字符串
* @param data 数据
* @param charset 字符集,如果为空使用当前系统字符集
* @return 字符串
*/
public static String str(ByteBuffer data, Charset charset){
if(null == charset) {
charset = Charset.defaultCharset();
}
return charset.decode(data).toString();
}
/**
* 字符串转换为byteBuffer
* @param str 字符串
* @param charset 编码
* @return byteBuffer
*/
public static ByteBuffer byteBuffer(String str, String charset) {
return ByteBuffer.wrap(StrKit.bytes(str, charset));
}
/**
* 以 conjunction 为分隔符将多个对象转换为字符串
*
* @param conjunction 分隔符
* @param objs 数组
* @return 连接后的字符串
*/
public static String join(String conjunction, Object... objs) {
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (Object item : objs) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br>
* 例如:HelloWorld->hello_world
*
* @param camelCaseStr 转换前的驼峰式命名的字符串
* @return 转换后下划线大写方式命名的字符串
*/
public static String toUnderlineCase(String camelCaseStr) {
if (camelCaseStr == null) {
return null;
}
final int length = camelCaseStr.length();
StringBuilder sb = new StringBuilder();
char c;
boolean isPreUpperCase = false;
for (int i = 0; i < length; i++) {
c = camelCaseStr.charAt(i);
boolean isNextUpperCase = true;
if (i < (length - 1)) {
isNextUpperCase = Character.isUpperCase(camelCaseStr.charAt(i + 1));
}
if (Character.isUpperCase(c)) {
if (!isPreUpperCase || !isNextUpperCase) {
if (i > 0) sb.append(UNDERLINE);
}
isPreUpperCase = true;
} else {
isPreUpperCase = false;
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
* 例如:hello_world->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String toCamelCase(String name) {
if (name == null) {
return null;
}
if (name.contains(UNDERLINE)) {
name = name.toLowerCase();
StringBuilder sb = new StringBuilder(name.length());
boolean upperCase = false;
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '_') {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
} else
return name;
}
/**
* 包装指定字符串
*
* @param str 被包装的字符串
* @param prefix 前缀
* @param suffix 后缀
* @return 包装后的字符串
*/
public static String wrap(String str, String prefix, String suffix) {
return format("{}{}{}", prefix, str, suffix);
}
/**
* 指定字符串是否被包装
*
* @param str 字符串
* @param prefix 前缀
* @param suffix 后缀
* @return 是否被包装
*/
public static boolean isWrap(String str, String prefix, String suffix) {
return str.startsWith(prefix) && str.endsWith(suffix);
}
/**
* 指定字符串是否被同一字符包装(前后都有这些字符串)
*
* @param str 字符串
* @param wrapper 包装字符串
* @return 是否被包装
*/
public static boolean isWrap(String str, String wrapper) {
return isWrap(str, wrapper, wrapper);
}
/**
* 指定字符串是否被同一字符包装(前后都有这些字符串)
*
* @param str 字符串
* @param wrapper 包装字符
* @return 是否被包装
*/
public static boolean isWrap(String str, char wrapper) {
return isWrap(str, wrapper, wrapper);
}
/**
* 指定字符串是否被包装
*
* @param str 字符串
* @param prefixChar 前缀
* @param suffixChar 后缀
* @return 是否被包装
*/
public static boolean isWrap(String str, char prefixChar, char suffixChar) {
return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar;
}
/**
* 补充字符串以满足最小长度 StrUtil.padPre("1", 3, '0');//"001"
*
* @param str 字符串
* @param minLength 最小长度
* @param padChar 补充的字符
* @return 补充后的字符串
*/
public static String padPre(String str, int minLength, char padChar) {
if (str.length() >= minLength) {
return str;
}
StringBuilder sb = new StringBuilder(minLength);
for (int i = str.length(); i < minLength; i++) {
sb.append(padChar);
}
sb.append(str);
return sb.toString();
}
/**
* 补充字符串以满足最小长度 StrUtil.padEnd("1", 3, '0');//"100"
*
* @param str 字符串
* @param minLength 最小长度
* @param padChar 补充的字符
* @return 补充后的字符串
*/
public static String padEnd(String str, int minLength, char padChar) {
if (str.length() >= minLength) {
return str;
}
StringBuilder sb = new StringBuilder(minLength);
sb.append(str);
for (int i = str.length(); i < minLength; i++) {
sb.append(padChar);
}
return sb.toString();
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder() {
return new StringBuilder();
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder(int capacity) {
return new StringBuilder(capacity);
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder(String... strs) {
final StringBuilder sb = new StringBuilder();
for (String str : strs) {
sb.append(str);
}
return sb;
}
/**
* 获得StringReader
*
* @param str 字符串
* @return StringReader
*/
public static StringReader getReader(String str) {
return new StringReader(str);
}
/**
* 获得StringWriter
*
* @return StringWriter
*/
public static StringWriter getWriter() {
return new StringWriter();
}
/**
* 编码字符串
*
* @param str 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 编码后的字节码
*/
public static byte[] encode(String str, String charset) {
if (str == null) {
return null;
}
if(isBlank(charset)) {
return str.getBytes();
}
try {
return str.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(format("Charset [{}] unsupported!", charset));
}
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 解码后的字符串
*/
public static String decode(byte[] data, String charset) {
if (data == null) {
return null;
}
if(isBlank(charset)) {
return new String(data);
}
try {
return new String(data, charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(format("Charset [{}] unsupported!", charset));
}
}
}
/**
* Copyright (c) 2011-2014, hubin (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util.support;
import java.util.regex.Pattern;
/**
* Web防火墙工具类
* <p>
* @author hubin
* @Date 2014-5-8
*/
public class WafKit {
/**
* @Description 过滤XSS脚本内容
* @param value
* 待处理内容
* @return
*/
public static String stripXSS(String value) {
String rlt = null;
if (null != value) {
// NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
rlt = value.replaceAll("", "");
// Avoid anything between script tags
Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid anything in a src='...' type of expression
/*scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");*/
// Remove any lonesome </script> tag
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Remove any lonesome <script ...> tag
scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid eval(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid expression(...) expressions
scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid onload= expressions
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
}
return rlt;
}
/**
* @Description 过滤SQL注入内容
* @param value
* 待处理内容
* @return
*/
public static String stripSqlInjection(String value) {
return (null == value) ? null : value.replaceAll("('.+--)|(--)|(%7C)", ""); //value.replaceAll("('.+--)|(--)|(\\|)|(%7C)", "");
}
/**
* @Description 过滤SQL/XSS注入内容
* @param value
* 待处理内容
* @return
*/
public static String stripSqlXSS(String value) {
return stripXSS(stripSqlInjection(value));
}
}
/**
* Copyright (c) 2011-2014, hubin (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.stylefeng.guns.core.util.support;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.Map;
/**
* Request请求过滤包装
* <p>
* @author hubin
* @Date 2014-5-8
*/
public class WafRequestWrapper extends HttpServletRequestWrapper {
private boolean filterXSS = true;
private boolean filterSQL = true;
public WafRequestWrapper(HttpServletRequest request, boolean filterXSS, boolean filterSQL) {
super(request);
this.filterXSS = filterXSS;
this.filterSQL = filterSQL;
}
public WafRequestWrapper(HttpServletRequest request) {
this(request, true, true);
}
/**
* @Description 数组参数过滤
* @param parameter
* 过滤参数
* @return
*/
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if ( values == null ) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for ( int i = 0 ; i < count ; i++ ) {
encodedValues[i] = filterParamString(values[i]);
}
return encodedValues;
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Map getParameterMap() {
Map<String, String[]> primary = super.getParameterMap();
Map<String, String[]> result = new HashMap<String, String[]>(primary.size());
for ( Map.Entry<String, String[]> entry : primary.entrySet() ) {
result.put(entry.getKey(), filterEntryString(entry.getValue()));
}
return result;
}
protected String[] filterEntryString(String[] rawValue) {
for ( int i = 0 ; i < rawValue.length ; i++ ) {
rawValue[i] = filterParamString(rawValue[i]);
}
return rawValue;
}
/**
* @Description 参数过滤
* @param parameter
* 过滤参数
* @return
*/
@Override
public String getParameter(String parameter) {
return filterParamString(super.getParameter(parameter));
}
/**
* @Description 请求头过滤
* @param name
* 过滤内容
* @return
*/
@Override
public String getHeader(String name) {
return filterParamString(super.getHeader(name));
}
/**
* @Description Cookie内容过滤
* @return
*/
@Override
public Cookie[] getCookies() {
Cookie[] existingCookies = super.getCookies();
if (existingCookies != null) {
for (int i = 0 ; i < existingCookies.length ; ++i) {
Cookie cookie = existingCookies[i];
cookie.setValue(filterParamString(cookie.getValue()));
}
}
return existingCookies;
}
/**
* @Description 过滤字符串内容
* @param rawValue
* 待处理内容
* @return
*/
protected String filterParamString(String rawValue) {
if (null == rawValue) {
return null;
}
String tmpStr = rawValue;
if (this.filterXSS) {
tmpStr = WafKit.stripXSS(rawValue);
}
if (this.filterSQL) {
tmpStr = WafKit.stripSqlInjection(tmpStr);
}
return tmpStr;
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util.support.exception;
import com.stylefeng.guns.core.util.support.StrKit;
/**
* 工具类初始化异常
*/
public class ToolBoxException extends RuntimeException{
private static final long serialVersionUID = 8247610319171014183L;
public ToolBoxException(Throwable e) {
super(e.getMessage(), e);
}
public ToolBoxException(String message) {
super(message);
}
public ToolBoxException(String messageTemplate, Object... params) {
super(StrKit.format(messageTemplate, params));
}
public ToolBoxException(String message, Throwable throwable) {
super(message, throwable);
}
public ToolBoxException(Throwable throwable, String messageTemplate, Object... params) {
super(StrKit.format(messageTemplate, params), throwable);
}
}
package com.stylefeng.guns.core.util.xss;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class XssFilter implements Filter {
FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new XssHttpServletRequestWrapper(
(HttpServletRequest) request), response);
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util.xss;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return cleanXSS(value);
}
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null)
return null;
return cleanXSS(value);
}
private String cleanXSS(String value) {
//You'll need to remove the spaces from the html entities below
value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
value = value.replaceAll("'", "& #39;");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
return value;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment