#2 加强Utils Modules模块 Random,Hash的性能优化等
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springside.examples.bootapi.service.AccountService;
|
||||
import org.springside.examples.bootapi.service.exception.ErrorCode;
|
||||
import org.springside.examples.bootapi.service.exception.ServiceException;
|
||||
import org.springside.modules.utils.net.MediaTypes;
|
||||
import org.springside.modules.web.MediaTypes;
|
||||
|
||||
// Spring Restful MVC Controller的标识, 直接输出内容,不调用template引擎.
|
||||
@RestController
|
||||
|
||||
+1
-1
@@ -20,8 +20,8 @@ import org.springside.examples.bootapi.service.BookAdminService;
|
||||
import org.springside.examples.bootapi.service.BookBorrowService;
|
||||
import org.springside.examples.bootapi.service.exception.ErrorCode;
|
||||
import org.springside.examples.bootapi.service.exception.ServiceException;
|
||||
import org.springside.modules.utils.net.MediaTypes;
|
||||
import org.springside.modules.utils.reflect.BeanMapper;
|
||||
import org.springside.modules.web.MediaTypes;
|
||||
|
||||
// Spring Restful MVC Controller的标识, 直接输出内容,不调用template引擎.
|
||||
@RestController
|
||||
|
||||
+1
-1
@@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
import org.springside.examples.bootapi.service.exception.ServiceException;
|
||||
import org.springside.modules.utils.net.MediaTypes;
|
||||
import org.springside.modules.utils.text.JsonMapper;
|
||||
import org.springside.modules.web.MediaTypes;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
||||
+1
-1
@@ -15,8 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springside.modules.utils.net.MediaTypes;
|
||||
import org.springside.modules.utils.text.JsonMapper;
|
||||
import org.springside.modules.web.MediaTypes;
|
||||
|
||||
/**
|
||||
* 重载替换Spring Boot默认的BasicErrorController, 增加日志并让错误返回方式统一.
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import org.javasimon.aop.Monitored;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springside.modules.utils.net.MediaTypes;
|
||||
import org.springside.modules.web.MediaTypes;
|
||||
|
||||
@RestController
|
||||
public class HelloController {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.springside.modules.utils.collection;
|
||||
package org.springside.modules.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package org.springside.modules.mapper;
|
||||
package org.springside.modules.web;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package org.springside.modules.utils.net;
|
||||
package org.springside.modules.web;
|
||||
|
||||
/**
|
||||
* 带UTF-8 charset 定义的MediaType.
|
||||
+2
-1
@@ -3,13 +3,14 @@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package org.springside.modules.utils.collection;
|
||||
package org.springside.modules.mapper;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springside.modules.web.CollectionExtractor;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.dom4j.DocumentException;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.junit.Test;
|
||||
import org.springside.modules.web.JaxbMapper;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.springside.modules.utils.number.NumberUtil;
|
||||
/**
|
||||
* 关于Properties的工具类
|
||||
*
|
||||
* 1. Boolean.readBoolean(name) 与其他类型如Integer.readInteger()等的行为不一致,进行扩展.
|
||||
* 1. 统一的读取系统变量,其中Boolean.readBoolean的风格不统一,Double则不支持,都进行了扩展.
|
||||
*
|
||||
* 2. 简单的合并系统变量(-D),环境变量 和默认值,以系统变量优先,在未引入Commons Config时使用.
|
||||
*
|
||||
@@ -34,50 +34,84 @@ public abstract class PropertiesUtil {
|
||||
|
||||
/////////// Boolean.readBoolean()扩展 ///////////////
|
||||
|
||||
/**
|
||||
* 读取Boolean类型的系统变量,为空时返回False,与Boolean.getBoolean()一致.
|
||||
*/
|
||||
public static boolean getBooleanDefaultFalse(String name) {
|
||||
return Boolean.getBoolean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Boolean类型的系统变量,为空时返回null,代表未设置,而不是Boolean.getBoolean()的false.
|
||||
*/
|
||||
public static Boolean getBooleanDefaultNull(String name) {
|
||||
public static Boolean booleanSystemProperty(String name) {
|
||||
String stringResult = System.getProperty(name);
|
||||
if (stringResult != null) {
|
||||
return Boolean.valueOf(stringResult);
|
||||
}
|
||||
return null; // NOSONAR
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Boolean类型的系统变量,为空时返回默认值, 而不是Boolean.getBoolean()的false.
|
||||
*
|
||||
* 因为默认值为Boolean,返回值也是Boolean
|
||||
*/
|
||||
public static Boolean getBoolean(String name, Boolean defaultVal) {
|
||||
public static Boolean booleanSystemProperty(String name, Boolean defaultValue) {
|
||||
String stringResult = System.getProperty(name);
|
||||
if (stringResult != null) {
|
||||
return Boolean.valueOf(stringResult);
|
||||
} else {
|
||||
return defaultVal;
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Boolean类型的系统变量,为空时返回默认值, 而不是Boolean.getBoolean()的false.
|
||||
*
|
||||
* 因为默认值为boolean,返回值也是boolean
|
||||
* 读取String类型的系统变量,为空时返回null.
|
||||
*/
|
||||
public static boolean getBoolean(String name, boolean defaultVal) {
|
||||
String stringResult = System.getProperty(name);
|
||||
if (stringResult != null) {
|
||||
return Boolean.parseBoolean(stringResult);
|
||||
} else {
|
||||
return defaultVal;
|
||||
}
|
||||
public static String stringSystemProperty(String name) {
|
||||
return System.getProperty(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取String类型的系统变量,为空时返回默认值
|
||||
*/
|
||||
public static String stringSystemProperty(String name, String defaultValue) {
|
||||
return System.getProperty(name, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Integer类型的系统变量,为空时返回null.
|
||||
*/
|
||||
public static Integer intSystemProperty(String name) {
|
||||
return Integer.getInteger(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Integer类型的系统变量,为空时返回默认值
|
||||
*/
|
||||
public static Integer intSystemProperty(String name, Integer defaultValue) {
|
||||
return Integer.getInteger(name, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Long类型的系统变量,为空时返回null.
|
||||
*/
|
||||
public static Long longSystemProperty(String name) {
|
||||
return Long.getLong(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Integer类型的系统变量,为空时返回默认值
|
||||
*/
|
||||
public static Long longSystemProperty(String name, Long defaultValue) {
|
||||
return Long.getLong(name, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Double类型的系统变量,为空时返回null.
|
||||
*/
|
||||
public static Double doubleSystemProperty(String propertyName) {
|
||||
return NumberUtil.toDoubleObject(System.getProperty(propertyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Double类型的系统变量,为空时返回默认值.
|
||||
*/
|
||||
public static Double doubleSystemProperty(String propertyName, Double defaultValue) {
|
||||
Double propertyValue = NumberUtil.toDoubleObject(System.getProperty(propertyName));
|
||||
return propertyValue != null ? propertyValue : defaultValue;
|
||||
}
|
||||
|
||||
/////////// 简单的合并系统变量(-D),环境变量 和默认值,以系统变量优先.///////////////
|
||||
@@ -85,7 +119,7 @@ public abstract class PropertiesUtil {
|
||||
/**
|
||||
* 合并系统变量(-D),环境变量 和默认值,以系统变量优先
|
||||
*/
|
||||
public static String readString(String propertyName, String envName, String defaultValue) {
|
||||
public static String stringSystemProperty(String propertyName, String envName, String defaultValue) {
|
||||
checkEnvName(envName);
|
||||
String propertyValue = System.getProperty(propertyName);
|
||||
if (propertyValue != null) {
|
||||
@@ -99,7 +133,7 @@ public abstract class PropertiesUtil {
|
||||
/**
|
||||
* 合并系统变量(-D),环境变量 和默认值,以系统变量优先
|
||||
*/
|
||||
public static Integer readInt(String propertyName, String envName, Integer defaultValue) {
|
||||
public static Integer intSystemProperty(String propertyName, String envName, Integer defaultValue) {
|
||||
checkEnvName(envName);
|
||||
Integer propertyValue = NumberUtil.toIntObject(System.getProperty(propertyName));
|
||||
if (propertyValue != null) {
|
||||
@@ -113,7 +147,7 @@ public abstract class PropertiesUtil {
|
||||
/**
|
||||
* 合并系统变量(-D),环境变量 和默认值,以系统变量优先
|
||||
*/
|
||||
public static Long readLong(String propertyName, String envName, Long defaultValue) {
|
||||
public static Long longSystemProperty(String propertyName, String envName, Long defaultValue) {
|
||||
checkEnvName(envName);
|
||||
Long propertyValue = NumberUtil.toLongObject(System.getProperty(propertyName));
|
||||
if (propertyValue != null) {
|
||||
@@ -127,7 +161,7 @@ public abstract class PropertiesUtil {
|
||||
/**
|
||||
* 合并系统变量(-D),环境变量 和默认值,以系统变量优先
|
||||
*/
|
||||
public static Double readDouble(String propertyName, String envName, Double defaultValue) {
|
||||
public static Double doubleSystemProperty(String propertyName, String envName, Double defaultValue) {
|
||||
checkEnvName(envName);
|
||||
Double propertyValue = NumberUtil.toDoubleObject(System.getProperty(propertyName));
|
||||
if (propertyValue != null) {
|
||||
@@ -141,7 +175,7 @@ public abstract class PropertiesUtil {
|
||||
/**
|
||||
* 合并系统变量(-D),环境变量 和默认值,以系统变量优先
|
||||
*/
|
||||
public static Boolean readBoolean(String propertyName, String envName, Boolean defaultValue) {
|
||||
public static Boolean booleanSystemProperty(String propertyName, String envName, Boolean defaultValue) {
|
||||
checkEnvName(envName);
|
||||
Boolean propertyValue = toBooleanObject(System.getProperty(propertyName));
|
||||
if (propertyValue != null) {
|
||||
|
||||
@@ -99,25 +99,57 @@ public abstract class FileUtil {
|
||||
return Files.newWriter(getFileByPath(fileName), Charsets.UTF_8);
|
||||
}
|
||||
|
||||
///// 文件操作/////
|
||||
///// 文件操作 /////
|
||||
|
||||
/**
|
||||
* 复制文件或目录
|
||||
*/
|
||||
public static void copy(File from, File to) throws IOException {
|
||||
if (from.isDirectory())
|
||||
copyDir(from, to);
|
||||
else
|
||||
copyFile(from, to);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件复制.
|
||||
*
|
||||
* 如果文件不存在或者是目录,不做修改
|
||||
*/
|
||||
public static void copy(@Nullable File from, File to) throws IOException {
|
||||
public static void copyFile(@Nullable File from, File to) throws IOException {
|
||||
if (isFileExists(from)) {
|
||||
Files.copy(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制目录
|
||||
*/
|
||||
public static void copyDir(File from, File to) throws IOException {
|
||||
if (to.exists()) {
|
||||
if (!to.isDirectory())
|
||||
throw new IllegalArgumentException(to.toString());
|
||||
} else {
|
||||
to.mkdirs();
|
||||
}
|
||||
|
||||
File[] files = from.listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
String name = files[i].getName();
|
||||
if (".".equals(name) || "..".equals(name))
|
||||
continue;
|
||||
copy(files[i], new File(to, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件移动/重命名.
|
||||
*
|
||||
* 如果文件不存在或者是目录,不做修改.
|
||||
*/
|
||||
public static void move(@Nullable File from, File to) throws IOException {
|
||||
public static void moveFile(@Nullable File from, File to) throws IOException {
|
||||
if (isFileExists(from)) {
|
||||
Files.move(from, to);
|
||||
}
|
||||
@@ -155,7 +187,7 @@ public abstract class FileUtil {
|
||||
if (!isDirExists(dir)) {
|
||||
return;
|
||||
}
|
||||
//后序遍历,先删掉子目录中的文件/目录
|
||||
// 后序遍历,先删掉子目录中的文件/目录
|
||||
Iterator<File> iterator = Files.fileTreeTraverser().postOrderTraversal(dir).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next().delete();
|
||||
@@ -182,13 +214,7 @@ public abstract class FileUtil {
|
||||
* 前序递归列出所有文件, 只包含后缀名匹配的文件. (后缀名不包含.)
|
||||
*/
|
||||
public static List<File> listFileWithExtension(final File rootDir, final String extension) {
|
||||
return Files.fileTreeTraverser().preOrderTraversal(rootDir).filter(new Predicate<File>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(File input) {
|
||||
return input.isFile() && extension.equals(FilePathUtil.getFileExtension(input));
|
||||
}
|
||||
}).toList();
|
||||
return Files.fileTreeTraverser().preOrderTraversal(rootDir).filter(new FileExtensionFilter(extension)).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,6 +245,9 @@ public abstract class FileUtil {
|
||||
return dir.exists() && dir.isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保目录存在, 如不存在则创建
|
||||
*/
|
||||
public static void makeSureDirExists(String dirPath) throws IOException {
|
||||
makeSureDirExists(getFileByPath(dirPath));
|
||||
}
|
||||
@@ -289,4 +318,20 @@ public abstract class FileUtil {
|
||||
private static File getFileByPath(String filePath) {
|
||||
return StringUtils.isBlank(filePath) ? null : new File(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以文件名后缀做filter,配合fileTreeTraverser使用
|
||||
*/
|
||||
public static final class FileExtensionFilter implements Predicate<File> {
|
||||
private final String extension;
|
||||
|
||||
private FileExtensionFilter(String extension) {
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(File input) {
|
||||
return input.isFile() && extension.equals(FilePathUtil.getFileExtension(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.zip.ZipFile;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springside.modules.utils.io.type.StringBuilderWriter;
|
||||
import org.springside.modules.utils.text.Charsets;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springside.modules.utils.io;
|
||||
package org.springside.modules.utils.io.type;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
@@ -149,10 +149,10 @@ public abstract class NetUtil {
|
||||
*/
|
||||
private static InetAddress findLocalAddressViaNetworkInterface() {
|
||||
// 如果hostname +/etc/hosts 得到的是127.0.0.1, 则首选这块网卡
|
||||
String preferNamePrefix = PropertiesUtil.readString("localhost.prefer.nic.prefix",
|
||||
String preferNamePrefix = PropertiesUtil.stringSystemProperty("localhost.prefer.nic.prefix",
|
||||
"LOCALHOST_PREFER_NIC_PREFIX", "bond0.");
|
||||
// 如果hostname +/etc/hosts 得到的是127.0.0.1, 和首选网卡都不符合要求,则按顺序遍历下面的网卡
|
||||
String defaultNicList = PropertiesUtil.readString("localhost.default.nic.list", "LOCALHOST_DEFAULT_NIC_LIST",
|
||||
String defaultNicList = PropertiesUtil.stringSystemProperty("localhost.default.nic.list", "LOCALHOST_DEFAULT_NIC_LIST",
|
||||
"bond0,eth0,em0,br0");
|
||||
|
||||
InetAddress resultAddress = null;
|
||||
|
||||
@@ -83,4 +83,16 @@ public abstract class MathUtil {
|
||||
public static long gcd(long a, long b) {
|
||||
return LongMath.gcd(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保证结果为正数的取模,from ElasticSearch
|
||||
*/
|
||||
public static int mod(int v, int m) {
|
||||
int r = v % m;
|
||||
if (r < 0) {
|
||||
r += m;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,13 @@ public abstract class NumberUtil {
|
||||
return Longs.toByteArray(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* from ElasticSearch Numbers
|
||||
*/
|
||||
public static byte[] toBytes(double val) {
|
||||
return toBytes(Double.doubleToRawLongBits(val));
|
||||
}
|
||||
|
||||
public static int toInt(byte[] bytes) {
|
||||
return Ints.fromByteArray(bytes);
|
||||
}
|
||||
@@ -35,6 +42,13 @@ public abstract class NumberUtil {
|
||||
return Longs.fromByteArray(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* from ElasticSearch Numbers
|
||||
*/
|
||||
public static double toDouble(byte[] bytes) {
|
||||
return Double.longBitsToDouble(toLong(bytes));
|
||||
}
|
||||
|
||||
/////// 判断字符串类型//////////
|
||||
/**
|
||||
* 判断字符串是否合法数字
|
||||
|
||||
@@ -11,23 +11,25 @@ import org.springside.modules.utils.base.Platforms;
|
||||
/**
|
||||
* 随机数工具集.
|
||||
*
|
||||
* 1. 获取无锁的ThreadLocalRandom
|
||||
* 1. 获取无锁的兼容JDK6的ThreadLocalRandom
|
||||
*
|
||||
* 2. 获取性能较佳的SecureRandom
|
||||
*
|
||||
* 3. 保证没有负数陷阱,也能更精确she定范围的nextInt 与 nextLong(copy from Common Lang RandomUtils)
|
||||
* 3. 保证没有负数陷阱,也能更精确设定范围的nextInt/nextLong/nextDouble
|
||||
* (copy from Common Lang RandomUtils,但默认使用性能较优的ThreadLocalRandom,并可配置其他的Random)
|
||||
*
|
||||
* 4. 随机字符串
|
||||
*
|
||||
* @author calvin
|
||||
*/
|
||||
public abstract class RandomUtil {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
|
||||
/////////////////// 获取Random实例//////////////
|
||||
/**
|
||||
* 返回无锁的ThreadLocalRandom
|
||||
*
|
||||
* 如果JDK6,使用移植于JDK7的版本,否则使用JDK自带
|
||||
* 如果JDK6,使用移植于jsr166e的版本(相当于JDK7的实现)
|
||||
*/
|
||||
public static Random threadLocalRandom() {
|
||||
if (Platforms.IS_ATLEASET_JAVA7) {
|
||||
@@ -57,7 +59,7 @@ public abstract class RandomUtil {
|
||||
* 返回0到Intger.MAX_VALUE的随机Int, 使用内置全局普通Random.
|
||||
*/
|
||||
public static int nextInt() {
|
||||
return nextInt(RANDOM);
|
||||
return nextInt(threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +80,7 @@ public abstract class RandomUtil {
|
||||
* 返回0到max的随机Int, 使用内置全局普通Random.
|
||||
*/
|
||||
public static int nextInt(int max) {
|
||||
return nextInt(RANDOM, max);
|
||||
return nextInt(threadLocalRandom(), max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +96,7 @@ public abstract class RandomUtil {
|
||||
* min必须大于0.
|
||||
*/
|
||||
public static int nextInt(int min, int max) {
|
||||
return nextInt(RANDOM, min, max);
|
||||
return nextInt(threadLocalRandom(), min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +124,7 @@ public abstract class RandomUtil {
|
||||
* 返回0-Long.MAX_VALUE间的随机Long, 使用内置全局普通Random.
|
||||
*/
|
||||
public static long nextLong() {
|
||||
return nextLong(RANDOM);
|
||||
return nextLong(threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +144,7 @@ public abstract class RandomUtil {
|
||||
* 返回0-max间的随机Long, 使用内置全局普通Random.
|
||||
*/
|
||||
public static long nextLong(long max) {
|
||||
return nextLong(RANDOM, 0, max);
|
||||
return nextLong(threadLocalRandom(), 0, max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +160,7 @@ public abstract class RandomUtil {
|
||||
* min必须大于0.
|
||||
*/
|
||||
public static long nextLong(long min, long max) {
|
||||
return nextLong(RANDOM, min, max);
|
||||
return nextLong(threadLocalRandom(), min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +188,7 @@ public abstract class RandomUtil {
|
||||
* 返回0-之间的double
|
||||
*/
|
||||
public static double nextDouble() {
|
||||
return nextDouble(RANDOM, 0, Double.MAX_VALUE);
|
||||
return nextDouble(threadLocalRandom(), 0, Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +202,7 @@ public abstract class RandomUtil {
|
||||
* 返回0-max之间的double
|
||||
*/
|
||||
public static double nextDouble(double max) {
|
||||
return nextDouble(RANDOM, 0, max);
|
||||
return nextDouble(threadLocalRandom(), 0, max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +216,7 @@ public abstract class RandomUtil {
|
||||
* 返回min-max之间的double
|
||||
*/
|
||||
public static double nextDouble(final double min, final double max) {
|
||||
return nextDouble(RANDOM, min, max);
|
||||
return nextDouble(threadLocalRandom(), min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +238,7 @@ public abstract class RandomUtil {
|
||||
* 随机字母或数字,固定长度
|
||||
*/
|
||||
public static String randomStringFixLength(int length) {
|
||||
return RandomStringUtils.random(length, 0, 0, true, true, null, RANDOM);
|
||||
return RandomStringUtils.random(length, 0, 0, true, true, null, threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +252,7 @@ public abstract class RandomUtil {
|
||||
* 随机字母或数字,随机长度
|
||||
*/
|
||||
public static String randomStringRandomLength(int minLength, int maxLength) {
|
||||
return RandomStringUtils.random(nextInt(minLength, maxLength), 0, 0, true, true, null, RANDOM);
|
||||
return RandomStringUtils.random(nextInt(minLength, maxLength), 0, 0, true, true, null, threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +266,7 @@ public abstract class RandomUtil {
|
||||
* 随机字母,固定长度
|
||||
*/
|
||||
public static String randomLetterFixLength(int length) {
|
||||
return RandomStringUtils.random(length, 0, 0, true, false, null, RANDOM);
|
||||
return RandomStringUtils.random(length, 0, 0, true, false, null, threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,7 +280,7 @@ public abstract class RandomUtil {
|
||||
* 随机字母,随机长度
|
||||
*/
|
||||
public static String randomLetterRandomLength(int minLength, int maxLength) {
|
||||
return RandomStringUtils.random(nextInt(minLength, maxLength), 0, 0, true, false, null, RANDOM);
|
||||
return RandomStringUtils.random(nextInt(minLength, maxLength), 0, 0, true, false, null, threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +294,7 @@ public abstract class RandomUtil {
|
||||
* 随机ASCII字符(含字母,数字及其他符号),固定长度
|
||||
*/
|
||||
public static String randomAsciiFixLength(int length) {
|
||||
return RandomStringUtils.random(length, 32, 127, false, false, null, RANDOM);
|
||||
return RandomStringUtils.random(length, 32, 127, false, false, null, threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,7 +308,8 @@ public abstract class RandomUtil {
|
||||
* 随机ASCII字符(含字母,数字及其他符号),随机长度
|
||||
*/
|
||||
public static String randomAsciiRandomLength(int minLength, int maxLength) {
|
||||
return RandomStringUtils.random(nextInt(minLength, maxLength), 32, 127, false, false, null, RANDOM);
|
||||
return RandomStringUtils.random(nextInt(minLength, maxLength), 32, 127, false, false, null,
|
||||
threadLocalRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,8 +7,8 @@ package org.springside.modules.utils.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -16,7 +16,6 @@ import java.util.Iterator;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.springside.modules.utils.base.ExceptionUtil;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
|
||||
@@ -25,11 +24,13 @@ import com.google.common.hash.Hashing;
|
||||
*
|
||||
* 1.集合类的HashCode, 返回int
|
||||
*
|
||||
* 2.SHA-1, 安全性较高, 返回byte[](可用Encodes进一步被编码为Hex, Base64),
|
||||
* 2.SHA-1, 安全性较高, 返回byte[](可用Encodes进一步被编码为Hex, Base64)
|
||||
*
|
||||
* 性能优化,使用ThreadLocal的MessageDigest(from ElasticSearch)
|
||||
*
|
||||
* 支持带salt并且进行迭代达到更高的安全性.
|
||||
*
|
||||
* MD5的安全性较低, 默认已不支持.
|
||||
* MD5的安全性较低, 只在文件Checksum时支持.
|
||||
*
|
||||
* 3.crc32, murmur32这些不追求安全性, 性能较高, 返回int.
|
||||
*
|
||||
@@ -39,8 +40,22 @@ import com.google.common.hash.Hashing;
|
||||
*/
|
||||
public abstract class HashUtil {
|
||||
|
||||
private static final String SHA1_ALG = "SHA-1";
|
||||
private static final String MD5_ALG = "MD5";
|
||||
private static ThreadLocal<MessageDigest> createThreadLocalMessageDigest(final String digest) {
|
||||
return new ThreadLocal<MessageDigest>() {
|
||||
@Override
|
||||
protected MessageDigest initialValue() {
|
||||
try {
|
||||
return MessageDigest.getInstance(digest);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(
|
||||
"unexpected exception creating MessageDigest instance for [" + digest + "]", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static final ThreadLocal<MessageDigest> MD5_DIGEST = createThreadLocalMessageDigest("MD5");
|
||||
private static final ThreadLocal<MessageDigest> SHA_1_DIGEST = createThreadLocalMessageDigest("SHA-1");
|
||||
|
||||
private static SecureRandom random = new SecureRandom();
|
||||
|
||||
@@ -74,28 +89,28 @@ public abstract class HashUtil {
|
||||
* 对输入字符串进行sha1散列.
|
||||
*/
|
||||
public static byte[] sha1(byte[] input) {
|
||||
return digest(input, SHA1_ALG, null, 1);
|
||||
return digest(input, get(SHA_1_DIGEST), null, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对输入字符串进行sha1散列, 编码默认为UTF8.
|
||||
*/
|
||||
public static byte[] sha1(String input) {
|
||||
return digest(input.getBytes(Charsets.UTF_8), SHA1_ALG, null, 1);
|
||||
return digest(input.getBytes(Charsets.UTF_8), get(SHA_1_DIGEST), null, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对输入字符串进行sha1散列,带salt达到更高的安全性.
|
||||
*/
|
||||
public static byte[] sha1(byte[] input, byte[] salt) {
|
||||
return digest(input, SHA1_ALG, salt, 1);
|
||||
return digest(input, get(SHA_1_DIGEST), salt, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对输入字符串进行sha1散列,带salt达到更高的安全性.
|
||||
*/
|
||||
public static byte[] sha1(String input, byte[] salt) {
|
||||
return digest(input.getBytes(Charsets.UTF_8), SHA1_ALG, salt, 1);
|
||||
return digest(input.getBytes(Charsets.UTF_8), get(SHA_1_DIGEST), salt, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +119,7 @@ public abstract class HashUtil {
|
||||
* @see #generateSalt(int)
|
||||
*/
|
||||
public static byte[] sha1(byte[] input, byte[] salt, int iterations) {
|
||||
return digest(input, SHA1_ALG, salt, iterations);
|
||||
return digest(input, get(SHA_1_DIGEST), salt, iterations);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,34 +128,34 @@ public abstract class HashUtil {
|
||||
* @see #generateSalt(int)
|
||||
*/
|
||||
public static byte[] sha1(String input, byte[] salt, int iterations) {
|
||||
return digest(input.getBytes(Charsets.UTF_8), SHA1_ALG, salt, iterations);
|
||||
return digest(input.getBytes(Charsets.UTF_8), get(SHA_1_DIGEST), salt, iterations);
|
||||
}
|
||||
|
||||
private static MessageDigest get(ThreadLocal<MessageDigest> messageDigest) {
|
||||
MessageDigest instance = messageDigest.get();
|
||||
instance.reset();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串进行散列, 支持md5与sha1算法.
|
||||
*/
|
||||
private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance(algorithm);
|
||||
|
||||
// 带盐
|
||||
if (salt != null) {
|
||||
digest.update(salt);
|
||||
}
|
||||
|
||||
// 第一次散列
|
||||
byte[] result = digest.digest(input);
|
||||
|
||||
// 如果迭代次数>1,进一步迭代散列
|
||||
for (int i = 1; i < iterations; i++) {
|
||||
digest.reset();
|
||||
result = digest.digest(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw ExceptionUtil.unchecked(e);
|
||||
private static byte[] digest(byte[] input, MessageDigest digest, byte[] salt, int iterations) {
|
||||
// 带盐
|
||||
if (salt != null) {
|
||||
digest.update(salt);
|
||||
}
|
||||
|
||||
// 第一次散列
|
||||
byte[] result = digest.digest(input);
|
||||
|
||||
// 如果迭代次数>1,进一步迭代散列
|
||||
for (int i = 1; i < iterations; i++) {
|
||||
digest.reset();
|
||||
result = digest.digest(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,32 +175,27 @@ public abstract class HashUtil {
|
||||
* 对文件进行sha1散列.
|
||||
*/
|
||||
public static byte[] sha1File(InputStream input) throws IOException {
|
||||
return digestFile(input, SHA1_ALG);
|
||||
return digestFile(input, get(SHA_1_DIGEST));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对文件进行md5散列,被破解后MD5已较少人用.
|
||||
*/
|
||||
public static byte[] md5File(InputStream input) throws IOException {
|
||||
return digestFile(input, MD5_ALG);
|
||||
return digestFile(input, get(MD5_DIGEST));
|
||||
}
|
||||
|
||||
private static byte[] digestFile(InputStream input, String algorithm) throws IOException {
|
||||
try {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
|
||||
int bufferLength = 8 * 1024;
|
||||
byte[] buffer = new byte[bufferLength];
|
||||
int read = input.read(buffer, 0, bufferLength);
|
||||
private static byte[] digestFile(InputStream input, MessageDigest messageDigest) throws IOException {
|
||||
int bufferLength = 8 * 1024;
|
||||
byte[] buffer = new byte[bufferLength];
|
||||
int read = input.read(buffer, 0, bufferLength);
|
||||
|
||||
while (read > -1) {
|
||||
messageDigest.update(buffer, 0, read);
|
||||
read = input.read(buffer, 0, bufferLength);
|
||||
}
|
||||
|
||||
return messageDigest.digest();
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw ExceptionUtil.unchecked(e);
|
||||
while (read > -1) {
|
||||
messageDigest.update(buffer, 0, read);
|
||||
read = input.read(buffer, 0, bufferLength);
|
||||
}
|
||||
|
||||
return messageDigest.digest();
|
||||
}
|
||||
|
||||
////////////////// 基于JDK的CRC32 ///////////////////
|
||||
|
||||
@@ -26,6 +26,7 @@ public abstract class DateUtil {
|
||||
|
||||
private static final int[] MONTH_LENGTH = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
//////// 日期比较 ///////////
|
||||
/**
|
||||
* 是否同一天.
|
||||
*
|
||||
@@ -39,9 +40,23 @@ public abstract class DateUtil {
|
||||
* 是否同一时刻.
|
||||
*/
|
||||
public static boolean isSameTime(@NotNull final Date date1, @NotNull final Date date2) {
|
||||
return date1.getTime() == date2.getTime();
|
||||
// date.getMillisOf() 比date.getTime()快
|
||||
return date1.compareTo(date2) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断日期是否在范围内,包含相等的日期
|
||||
*/
|
||||
public static boolean isBetween(@NotNull final Date date, @NotNull final Date start, @NotNull final Date end) {
|
||||
if (date == null || start == null || end == null || start.after(end)) {
|
||||
throw new IllegalArgumentException("some date parameters is null or dateBein after dateEnd");
|
||||
}
|
||||
return !date.before(start) && !date.after(end);
|
||||
}
|
||||
|
||||
|
||||
/////////// 日期设置处理 /////////
|
||||
|
||||
/**
|
||||
* 日期往下取整.
|
||||
*
|
||||
|
||||
+79
-32
@@ -12,53 +12,100 @@ import org.springside.modules.utils.number.RandomUtil;
|
||||
public class PropertiesUtilTest {
|
||||
|
||||
@Test
|
||||
public void getBoolean() {
|
||||
public void systemProperty() {
|
||||
String name = "ss.test" + RandomUtil.nextInt();
|
||||
|
||||
boolean result = PropertiesUtil.getBooleanDefaultFalse(name);
|
||||
assertThat(result).isFalse();
|
||||
|
||||
Boolean result0 = PropertiesUtil.getBooleanDefaultNull(name);
|
||||
Boolean result0 = PropertiesUtil.booleanSystemProperty(name);
|
||||
assertThat(result0).isNull();
|
||||
|
||||
Boolean result1 = PropertiesUtil.getBoolean(name, null);
|
||||
Boolean result1 = PropertiesUtil.booleanSystemProperty(name, null);
|
||||
assertThat(result1).isNull();
|
||||
|
||||
boolean result2 = PropertiesUtil.getBoolean(name, false);
|
||||
assertThat(result2).isFalse();
|
||||
|
||||
Boolean result3 = PropertiesUtil.getBoolean(name, Boolean.TRUE);
|
||||
Boolean result3 = PropertiesUtil.booleanSystemProperty(name, Boolean.TRUE);
|
||||
assertThat(result3).isTrue();
|
||||
|
||||
System.setProperty(name, "true");
|
||||
Boolean result4 = PropertiesUtil.getBoolean(name, false);
|
||||
assertThat(result4).isTrue();
|
||||
|
||||
Boolean result5 = PropertiesUtil.getBoolean(name, Boolean.FALSE);
|
||||
|
||||
Boolean result5 = PropertiesUtil.booleanSystemProperty(name, Boolean.FALSE);
|
||||
assertThat(result5).isTrue();
|
||||
|
||||
System.clearProperty(name);
|
||||
|
||||
/// int
|
||||
Integer result6 = PropertiesUtil.intSystemProperty(name);
|
||||
assertThat(result6).isNull();
|
||||
|
||||
result6 = PropertiesUtil.intSystemProperty(name, 1);
|
||||
assertThat(result6).isEqualTo(1);
|
||||
|
||||
System.setProperty(name, "2");
|
||||
result6 = PropertiesUtil.intSystemProperty(name, 1);
|
||||
assertThat(result6).isEqualTo(2);
|
||||
|
||||
System.clearProperty(name);
|
||||
|
||||
///// long
|
||||
Long result7 = PropertiesUtil.longSystemProperty(name);
|
||||
assertThat(result7).isNull();
|
||||
|
||||
result7 = PropertiesUtil.longSystemProperty(name, 1L);
|
||||
assertThat(result7).isEqualTo(1L);
|
||||
|
||||
System.setProperty(name, "2");
|
||||
result7 = PropertiesUtil.longSystemProperty(name, 1L);
|
||||
assertThat(result7).isEqualTo(2L);
|
||||
|
||||
System.clearProperty(name);
|
||||
|
||||
///// doulbe
|
||||
Double result8 = PropertiesUtil.doubleSystemProperty(name);
|
||||
assertThat(result8).isNull();
|
||||
|
||||
result8 = PropertiesUtil.doubleSystemProperty(name, 1.1);
|
||||
assertThat(result8).isEqualTo(1.1);
|
||||
|
||||
System.setProperty(name, "2.1");
|
||||
result8 = PropertiesUtil.doubleSystemProperty(name, 1.1);
|
||||
assertThat(result8).isEqualTo(2.1);
|
||||
|
||||
System.clearProperty(name);
|
||||
|
||||
///// String
|
||||
String result9 = PropertiesUtil.stringSystemProperty(name);
|
||||
assertThat(result9).isNull();
|
||||
|
||||
result9 = PropertiesUtil.stringSystemProperty(name, "1.1");
|
||||
assertThat(result9).isEqualTo("1.1");
|
||||
|
||||
System.setProperty(name, "2.1");
|
||||
result9 = PropertiesUtil.stringSystemProperty(name, "1.1");
|
||||
assertThat(result9).isEqualTo("2.1");
|
||||
|
||||
System.clearProperty(name);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readString() {
|
||||
public void stringSystemProperty() {
|
||||
String name = "ss.test" + RandomUtil.nextInt();
|
||||
String envName = "ss_test" + RandomUtil.nextInt();
|
||||
|
||||
// default 值
|
||||
String result = PropertiesUtil.readString(name, envName, "123");
|
||||
String result = PropertiesUtil.stringSystemProperty(name, envName, "123");
|
||||
assertThat(result).isEqualTo("123");
|
||||
|
||||
// env值
|
||||
String result2 = PropertiesUtil.readString(name, "HOME", "123");
|
||||
String result2 = PropertiesUtil.stringSystemProperty(name, "HOME", "123");
|
||||
assertThat(result2).isNotEqualTo("123");
|
||||
|
||||
// system properties值
|
||||
System.setProperty(name, "456");
|
||||
String result3 = PropertiesUtil.readString(name, envName, "123");
|
||||
String result3 = PropertiesUtil.stringSystemProperty(name, envName, "123");
|
||||
assertThat(result3).isEqualTo("456");
|
||||
|
||||
try {
|
||||
// 非法字符
|
||||
String result4 = PropertiesUtil.readString(name, name, "123");
|
||||
String result4 = PropertiesUtil.stringSystemProperty(name, name, "123");
|
||||
Assert.fail("should fail before");
|
||||
} catch (Exception e) {
|
||||
assertThat(e).isInstanceOf(IllegalArgumentException.class);
|
||||
@@ -68,81 +115,81 @@ public class PropertiesUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readInt() {
|
||||
public void intSystemProperty() {
|
||||
String name = "ss.test" + RandomUtil.nextInt();
|
||||
String envName = "ss_test" + RandomUtil.nextInt();
|
||||
|
||||
// default 值
|
||||
int result = PropertiesUtil.readInt(name, envName, 123);
|
||||
int result = PropertiesUtil.intSystemProperty(name, envName, 123);
|
||||
assertThat(result).isEqualTo(123);
|
||||
|
||||
// env值没有数字类型的,忽略
|
||||
|
||||
// system properties值
|
||||
System.setProperty(name, "456");
|
||||
int result3 = PropertiesUtil.readInt(name, envName, 123);
|
||||
int result3 = PropertiesUtil.intSystemProperty(name, envName, 123);
|
||||
assertThat(result3).isEqualTo(456);
|
||||
|
||||
System.clearProperty(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readLong() {
|
||||
public void longSystemProperty() {
|
||||
String name = "ss.test" + RandomUtil.nextInt();
|
||||
String envName = "ss_test" + RandomUtil.nextInt();
|
||||
|
||||
// default 值
|
||||
long result = PropertiesUtil.readLong(name, envName, 123L);
|
||||
long result = PropertiesUtil.longSystemProperty(name, envName, 123L);
|
||||
assertThat(result).isEqualTo(123L);
|
||||
|
||||
// env值没有数字类型的,忽略
|
||||
|
||||
// system properties值
|
||||
System.setProperty(name, "456");
|
||||
long result3 = PropertiesUtil.readLong(name, envName, 123L);
|
||||
long result3 = PropertiesUtil.longSystemProperty(name, envName, 123L);
|
||||
assertThat(result3).isEqualTo(456L);
|
||||
|
||||
System.clearProperty(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readDouble() {
|
||||
public void doubleSystemProperty() {
|
||||
String name = "ss.test" + RandomUtil.nextInt();
|
||||
String envName = "ss_test" + RandomUtil.nextInt();
|
||||
|
||||
// default 值
|
||||
double result = PropertiesUtil.readDouble(name, envName, 123d);
|
||||
double result = PropertiesUtil.doubleSystemProperty(name, envName, 123d);
|
||||
assertThat(result).isEqualTo(123d);
|
||||
|
||||
// env值没有数字类型的,忽略
|
||||
|
||||
// system properties值
|
||||
System.setProperty(name, "456");
|
||||
double result3 = PropertiesUtil.readDouble(name, envName, 123d);
|
||||
double result3 = PropertiesUtil.doubleSystemProperty(name, envName, 123d);
|
||||
assertThat(result3).isEqualTo(456d);
|
||||
|
||||
System.clearProperty(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readBoolean() {
|
||||
public void booleanSystemProperty() {
|
||||
String name = "ss.test" + RandomUtil.nextInt();
|
||||
String envName = "ss_test" + RandomUtil.nextInt();
|
||||
|
||||
// default 值
|
||||
boolean result = PropertiesUtil.readBoolean(name, envName, true);
|
||||
boolean result = PropertiesUtil.booleanSystemProperty(name, envName, true);
|
||||
assertThat(result).isTrue();
|
||||
|
||||
// env值没有boolean类型的,忽略
|
||||
|
||||
// system properties值
|
||||
System.setProperty(name, "true");
|
||||
boolean result3 = PropertiesUtil.readBoolean(name, envName, false);
|
||||
boolean result3 = PropertiesUtil.booleanSystemProperty(name, envName, false);
|
||||
assertThat(result3).isTrue();
|
||||
|
||||
System.clearProperty(name);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void loadProperties() {
|
||||
Properties p1 = PropertiesUtil.loadFromFile("classpath://application.properties");
|
||||
|
||||
+2
@@ -26,6 +26,8 @@ public class ThreadLocalContextTest {
|
||||
ThreadLocalContext.put("myname", Thread.currentThread().getName());
|
||||
ThreadUtil.sleep(RandomUtil.nextLong(100, 300));
|
||||
System.out.println(ThreadLocalContext.get("myname"));
|
||||
ThreadLocalContext.reset();
|
||||
System.out.println("shoud null for " +Thread.currentThread().getName() + ":"+ThreadLocalContext.get("myname"));
|
||||
countdown.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ public class FileUtilTest {
|
||||
FileUtil.write(content, file);
|
||||
File newFile = new File(FilePathUtil.contact(Platforms.TMP_DIR, "testFile" + RandomUtil.nextInt()));
|
||||
|
||||
FileUtil.copy(file, newFile);
|
||||
FileUtil.copyFile(file, newFile);
|
||||
assertThat(FileUtil.isFileExists(newFile)).isTrue();
|
||||
|
||||
String result = FileUtil.toString(newFile);
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springside.modules.utils.io.type.StringBuilderWriter;
|
||||
import org.springside.modules.utils.text.Charsets;
|
||||
|
||||
public class IOUtilTest {
|
||||
|
||||
Reference in New Issue
Block a user