mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-18 05:59:35 +08:00
Prepare release
This commit is contained in:
commit
acfb7bcdba
23
CHANGELOG.md
23
CHANGELOG.md
@ -3,6 +3,27 @@
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# 5.8.2 (2022-05-27)
|
||||||
|
|
||||||
|
### 🐣新特性
|
||||||
|
* 【core 】 BeanUtil拷贝对象增加空检查(issue#I58CJ3@Gitee)
|
||||||
|
* 【db 】 Column#size改为long
|
||||||
|
* 【core 】 ClassUtil增加isInterface等方法(pr#623@Gitee)
|
||||||
|
* 【socket 】 增加ChannelUtil
|
||||||
|
|
||||||
|
### 🐞Bug修复
|
||||||
|
* 【extra 】 修复SshjSftp初始化未能代入端口配置问题(issue#2333@Github)
|
||||||
|
* 【core 】 修复Convert.numberToSimple转换问题(issue#2334@Github)
|
||||||
|
* 【core 】 修复TemporalAccessorConverter导致的转换问题(issue#2341@Github)
|
||||||
|
* 【core 】 修复NumberUtil除法空指针问题(issue#I58XKE@Gitee)
|
||||||
|
* 【core 】 修复CAR_VIN正则(pr#624@Gitee)
|
||||||
|
* 【db 】 修复count查询别名问题(issue#I590YB@Gitee)
|
||||||
|
* 【json 】 修复json中byte[]无法转换问题(issue#I59LW4@Gitee)
|
||||||
|
* 【core 】 修复NumberUtil.isXXX未判空问题(issue#2350@Github)
|
||||||
|
* 【core 】 修复Singleton中ConcurrentHashMap在JDK8下的bug引起的可能的死循环问题(issue#2349@Github)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# 5.8.1 (2022-05-16)
|
# 5.8.1 (2022-05-16)
|
||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
@ -13,7 +34,7 @@
|
|||||||
* 【core 】 ByteUtil新增bytesToShort重载(issue#I57FA7@Gitee)
|
* 【core 】 ByteUtil新增bytesToShort重载(issue#I57FA7@Gitee)
|
||||||
* 【core 】 ReflectUtil.invoke方法抛出运行时异常增加InvocationTargetRuntimeException(issue#I57GI2@Gitee)
|
* 【core 】 ReflectUtil.invoke方法抛出运行时异常增加InvocationTargetRuntimeException(issue#I57GI2@Gitee)
|
||||||
* 【core 】 NumberUtil.parseNumber支持16进制(issue#2328@Github)
|
* 【core 】 NumberUtil.parseNumber支持16进制(issue#2328@Github)
|
||||||
*
|
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【core 】 MapUtil.map对null友好,且修复了测试用例中分组问题(pr#614@Gitee)
|
* 【core 】 MapUtil.map对null友好,且修复了测试用例中分组问题(pr#614@Gitee)
|
||||||
* 【core 】 修复BeanUtil.beanToMap中properties为null的空指针问题(issue#2303@Github)
|
* 【core 】 修复BeanUtil.beanToMap中properties为null的空指针问题(issue#2303@Github)
|
||||||
|
@ -144,18 +144,18 @@ We provide the T-Shirt and Sweater with Hutool Logo, please visit the shop:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🍐Gradle
|
### 🍐Gradle
|
||||||
```
|
```
|
||||||
implementation 'cn.hutool:hutool-all:5.8.1'
|
implementation 'cn.hutool:hutool-all:5.8.2'
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📥Download
|
## 📥Download
|
||||||
|
|
||||||
- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.1/)
|
- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.2/)
|
||||||
|
|
||||||
> 🔔️note:
|
> 🔔️note:
|
||||||
> Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available.
|
> Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available.
|
||||||
|
@ -144,20 +144,20 @@ Hutool的存在就是为了减少代码搜索成本,避免网络上参差不
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🍐Gradle
|
### 🍐Gradle
|
||||||
```
|
```
|
||||||
implementation 'cn.hutool:hutool-all:5.8.1'
|
implementation 'cn.hutool:hutool-all:5.8.2'
|
||||||
```
|
```
|
||||||
|
|
||||||
### 📥下载jar
|
### 📥下载jar
|
||||||
|
|
||||||
点击以下链接,下载`hutool-all-X.X.X.jar`即可:
|
点击以下链接,下载`hutool-all-X.X.X.jar`即可:
|
||||||
|
|
||||||
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.1/)
|
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.2/)
|
||||||
|
|
||||||
> 🔔️注意
|
> 🔔️注意
|
||||||
> Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。
|
> Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。
|
||||||
|
@ -1 +1 @@
|
|||||||
5.8.1
|
5.8.2
|
||||||
|
@ -1 +1 @@
|
|||||||
var version = '5.8.1'
|
var version = '5.8.2'
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-aop</artifactId>
|
<artifactId>hutool-aop</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-bloomFilter</artifactId>
|
<artifactId>hutool-bloomFilter</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-bom</artifactId>
|
<artifactId>hutool-bom</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-cache</artifactId>
|
<artifactId>hutool-cache</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-captcha</artifactId>
|
<artifactId>hutool-captcha</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-core</artifactId>
|
<artifactId>hutool-core</artifactId>
|
||||||
|
@ -728,6 +728,9 @@ public class BeanUtil {
|
|||||||
* @return 目标对象
|
* @return 目标对象
|
||||||
*/
|
*/
|
||||||
public static <T> T copyProperties(Object source, Class<T> tClass, String... ignoreProperties) {
|
public static <T> T copyProperties(Object source, Class<T> tClass, String... ignoreProperties) {
|
||||||
|
if(null == source){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
T target = ReflectUtil.newInstanceIfPossible(tClass);
|
T target = ReflectUtil.newInstanceIfPossible(tClass);
|
||||||
copyProperties(source, target, CopyOptions.create().setIgnoreProperties(ignoreProperties));
|
copyProperties(source, target, CopyOptions.create().setIgnoreProperties(ignoreProperties));
|
||||||
return target;
|
return target;
|
||||||
@ -765,6 +768,9 @@ public class BeanUtil {
|
|||||||
* @param copyOptions 拷贝选项,见 {@link CopyOptions}
|
* @param copyOptions 拷贝选项,见 {@link CopyOptions}
|
||||||
*/
|
*/
|
||||||
public static void copyProperties(Object source, Object target, CopyOptions copyOptions) {
|
public static void copyProperties(Object source, Object target, CopyOptions copyOptions) {
|
||||||
|
if(null == source){
|
||||||
|
return;
|
||||||
|
}
|
||||||
BeanCopier.create(source, target, ObjectUtil.defaultIfNull(copyOptions, CopyOptions::create)).copy();
|
BeanCopier.create(source, target, ObjectUtil.defaultIfNull(copyOptions, CopyOptions::create)).copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.hutool.core.bean.copier;
|
package cn.hutool.core.bean.copier;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.lang.copier.Copier;
|
import cn.hutool.core.lang.copier.Copier;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -62,6 +63,8 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
|
|||||||
* @param copyOptions 拷贝属性选项
|
* @param copyOptions 拷贝属性选项
|
||||||
*/
|
*/
|
||||||
public BeanCopier(Object source, T target, Type targetType, CopyOptions copyOptions) {
|
public BeanCopier(Object source, T target, Type targetType, CopyOptions copyOptions) {
|
||||||
|
Assert.notNull(source, "Source bean must be not null!");
|
||||||
|
Assert.notNull(target, "Target bean must be not null!");
|
||||||
Copier<T> copier;
|
Copier<T> copier;
|
||||||
if (source instanceof Map) {
|
if (source instanceof Map) {
|
||||||
if (target instanceof Map) {
|
if (target instanceof Map) {
|
||||||
|
@ -63,7 +63,7 @@ public class NumberWordFormatter {
|
|||||||
int index = -1;
|
int index = -1;
|
||||||
double res = value;
|
double res = value;
|
||||||
while (res > 10 && (false == isTwo || index < 1)) {
|
while (res > 10 && (false == isTwo || index < 1)) {
|
||||||
if (res > 1000) {
|
if (res >= 1000) {
|
||||||
res = res / 1000;
|
res = res / 1000;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,12 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
this.format = format;
|
this.format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Class<TemporalAccessor> getTargetType() {
|
||||||
|
return (Class<TemporalAccessor>) this.targetType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TemporalAccessor convertInternal(Object value) {
|
protected TemporalAccessor convertInternal(Object value) {
|
||||||
if (value instanceof Long) {
|
if (value instanceof Long) {
|
||||||
|
@ -168,7 +168,7 @@ public interface RegexPool {
|
|||||||
* 十七位码、车架号
|
* 十七位码、车架号
|
||||||
* 车辆的唯一标示
|
* 车辆的唯一标示
|
||||||
*/
|
*/
|
||||||
String CAR_VIN = "^[A-Za-z0-9]{17}$";
|
String CAR_VIN = "^[A-HJ-NPR-Z0-9]{8}[0-9X][A-HJ-NPR-Z0-9]{2}\\d{6}$";
|
||||||
/**
|
/**
|
||||||
* 驾驶证 别名:驾驶证档案编号、行驶证编号
|
* 驾驶证 别名:驾驶证档案编号、行驶证编号
|
||||||
* eg:430101758218
|
* eg:430101758218
|
||||||
|
@ -52,7 +52,15 @@ public final class Singleton {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T get(String key, Func0<T> supplier) {
|
public static <T> T get(String key, Func0<T> supplier) {
|
||||||
return (T) POOL.computeIfAbsent(key, (k)-> supplier.callWithRuntimeException());
|
//return (T) POOL.computeIfAbsent(key, (k)-> supplier.callWithRuntimeException());
|
||||||
|
// issues#2349
|
||||||
|
// ConcurrentHashMap.computeIfAbsent在某些情况下会导致死循环问题,此处采用Dubbo的解决方案
|
||||||
|
Object value = POOL.get(key);
|
||||||
|
if(null == value){
|
||||||
|
POOL.putIfAbsent(key, supplier.callWithRuntimeException());
|
||||||
|
value = POOL.get(key);
|
||||||
|
}
|
||||||
|
return (T) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1110,4 +1110,26 @@ public class ClassUtil {
|
|||||||
}
|
}
|
||||||
return location.getPath();
|
return location.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为抽象类或接口
|
||||||
|
*
|
||||||
|
* @param clazz 类
|
||||||
|
* @return 是否为抽象类或接口
|
||||||
|
* @since 5.8.2
|
||||||
|
*/
|
||||||
|
public static boolean isAbstractOrInterface(Class<?> clazz) {
|
||||||
|
return isAbstract(clazz) || isInterface(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为接口
|
||||||
|
*
|
||||||
|
* @param clazz 类
|
||||||
|
* @return 是否为接口
|
||||||
|
* @since 5.8.2
|
||||||
|
*/
|
||||||
|
public static boolean isInterface(Class<?> clazz) {
|
||||||
|
return clazz.isInterface();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,7 +719,7 @@ public class NumberUtil {
|
|||||||
if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) {
|
if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) {
|
||||||
return div((BigDecimal) v1, (BigDecimal) v2, scale, roundingMode);
|
return div((BigDecimal) v1, (BigDecimal) v2, scale, roundingMode);
|
||||||
}
|
}
|
||||||
return div(v1.toString(), v2.toString(), scale, roundingMode);
|
return div(StrUtil.toStringOrNull(v1), StrUtil.toStringOrNull(v2), scale, roundingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1238,10 +1238,12 @@ public class NumberUtil {
|
|||||||
* @return 是否为整数
|
* @return 是否为整数
|
||||||
*/
|
*/
|
||||||
public static boolean isInteger(String s) {
|
public static boolean isInteger(String s) {
|
||||||
try {
|
if(StrUtil.isNotBlank(s)) {
|
||||||
Integer.parseInt(s);
|
try {
|
||||||
} catch (NumberFormatException e) {
|
Integer.parseInt(s);
|
||||||
return false;
|
} catch (NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1255,10 +1257,12 @@ public class NumberUtil {
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
public static boolean isLong(String s) {
|
public static boolean isLong(String s) {
|
||||||
try {
|
if(StrUtil.isNotBlank(s)) {
|
||||||
Long.parseLong(s);
|
try {
|
||||||
} catch (NumberFormatException e) {
|
Long.parseLong(s);
|
||||||
return false;
|
} catch (NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1270,11 +1274,13 @@ public class NumberUtil {
|
|||||||
* @return 是否为{@link Double}类型
|
* @return 是否为{@link Double}类型
|
||||||
*/
|
*/
|
||||||
public static boolean isDouble(String s) {
|
public static boolean isDouble(String s) {
|
||||||
try {
|
if(StrUtil.isNotBlank(s)) {
|
||||||
Double.parseDouble(s);
|
try {
|
||||||
return s.contains(".");
|
Double.parseDouble(s);
|
||||||
} catch (NumberFormatException ignore) {
|
return s.contains(".");
|
||||||
// ignore
|
} catch (NumberFormatException ignore) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -567,6 +567,11 @@ public class BeanUtilTest {
|
|||||||
Assert.assertNull(newFood.getCode());
|
Assert.assertNull(newFood.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void copyNullTest() {
|
||||||
|
Assert.assertNull(BeanUtil.copyProperties(null, Food.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void copyBeanPropertiesFilterTest() {
|
public void copyBeanPropertiesFilterTest() {
|
||||||
Food info = new Food();
|
Food info = new Food();
|
||||||
|
@ -15,6 +15,8 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -383,4 +385,11 @@ public class ConvertTest {
|
|||||||
float b = Convert.toFloat(a);
|
float b = Convert.toFloat(a);
|
||||||
Assert.assertEquals(a, b, 5);
|
Assert.assertEquals(a, b, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void localDateTimeToLocalDateTest(){
|
||||||
|
final LocalDateTime localDateTime = LocalDateTime.now();
|
||||||
|
final LocalDate convert = Convert.convert(LocalDate.class, localDateTime);
|
||||||
|
Assert.assertEquals(localDateTime.toLocalDate(), convert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,4 +31,10 @@ public class NumberWordFormatTest {
|
|||||||
String format5 = NumberWordFormatter.formatSimple(438);
|
String format5 = NumberWordFormatter.formatSimple(438);
|
||||||
Assert.assertEquals("438", format5);
|
Assert.assertEquals("438", format5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatSimpleTest2(){
|
||||||
|
final String s = NumberWordFormatter.formatSimple(1000);
|
||||||
|
Assert.assertEquals("1k", s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,7 @@ public class ValidatorTest {
|
|||||||
public void isCarVinTest(){
|
public void isCarVinTest(){
|
||||||
Assert.assertTrue(Validator.isCarVin("LSJA24U62JG269225"));
|
Assert.assertTrue(Validator.isCarVin("LSJA24U62JG269225"));
|
||||||
Assert.assertTrue(Validator.isCarVin("LDC613P23A1305189"));
|
Assert.assertTrue(Validator.isCarVin("LDC613P23A1305189"));
|
||||||
|
Assert.assertFalse(Validator.isCarVin("LOC613P23A1305189"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -439,6 +439,16 @@ public class NumberUtilTest {
|
|||||||
Assert.assertFalse(NumberUtil.isEven(a[4]));
|
Assert.assertFalse(NumberUtil.isEven(a[4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void divIntegerTest(){
|
||||||
|
Assert.assertEquals(1001013, NumberUtil.div(100101300, (Number) 100).intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isDoubleTest(){
|
||||||
|
Assert.assertFalse(NumberUtil.isDouble(null));
|
||||||
|
Assert.assertFalse(NumberUtil.isDouble(""));
|
||||||
|
Assert.assertFalse(NumberUtil.isDouble(" "));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-cron</artifactId>
|
<artifactId>hutool-cron</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-crypto</artifactId>
|
<artifactId>hutool-crypto</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-db</artifactId>
|
<artifactId>hutool-db</artifactId>
|
||||||
@ -22,12 +22,12 @@
|
|||||||
<dbcp2.version>2.9.0</dbcp2.version>
|
<dbcp2.version>2.9.0</dbcp2.version>
|
||||||
<tomcat-jdbc.version>10.0.20</tomcat-jdbc.version>
|
<tomcat-jdbc.version>10.0.20</tomcat-jdbc.version>
|
||||||
<druid.version>1.2.9</druid.version>
|
<druid.version>1.2.9</druid.version>
|
||||||
<hikariCP.version>2.4.13</hikariCP.version>
|
<hikariCP.version>4.0.3</hikariCP.version>
|
||||||
<mongo4.version>4.6.0</mongo4.version>
|
<mongo4.version>4.6.0</mongo4.version>
|
||||||
<sqlite.version>3.36.0.3</sqlite.version>
|
<sqlite.version>3.36.0.3</sqlite.version>
|
||||||
<!-- 此处固定2.5.x,支持到JDK8 -->
|
<!-- 此处固定2.5.x,支持到JDK8 -->
|
||||||
<hsqldb.version>2.5.2</hsqldb.version>
|
<hsqldb.version>2.5.2</hsqldb.version>
|
||||||
<jedis.version>4.2.2</jedis.version>
|
<jedis.version>4.2.3</jedis.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -62,7 +62,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.zaxxer</groupId>
|
<groupId>com.zaxxer</groupId>
|
||||||
<artifactId>HikariCP-java7</artifactId>
|
<artifactId>HikariCP</artifactId>
|
||||||
<version>${hikariCP.version}</version>
|
<version>${hikariCP.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -156,7 +156,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.microsoft.sqlserver</groupId>
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
<artifactId>mssql-jdbc</artifactId>
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
<version>10.2.0.jre8</version>
|
<version>10.2.1.jre8</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package cn.hutool.db.dialect;
|
package cn.hutool.db.dialect;
|
||||||
|
|
||||||
import cn.hutool.core.collection.ListUtil;
|
|
||||||
import cn.hutool.db.Entity;
|
import cn.hutool.db.Entity;
|
||||||
import cn.hutool.db.Page;
|
import cn.hutool.db.Page;
|
||||||
import cn.hutool.db.sql.Order;
|
import cn.hutool.db.sql.Order;
|
||||||
@ -134,8 +133,7 @@ public interface Dialect extends Serializable {
|
|||||||
* @throws SQLException SQL执行异常
|
* @throws SQLException SQL执行异常
|
||||||
*/
|
*/
|
||||||
default PreparedStatement psForCount(Connection conn, Query query) throws SQLException {
|
default PreparedStatement psForCount(Connection conn, Query query) throws SQLException {
|
||||||
query.setFields(ListUtil.toList("count(1)"));
|
return psForCount(conn, SqlBuilder.create().query(query));
|
||||||
return psForFind(conn, query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,7 @@ public class Column implements Serializable, Cloneable {
|
|||||||
/**
|
/**
|
||||||
* 大小或数据长度
|
* 大小或数据长度
|
||||||
*/
|
*/
|
||||||
private int size;
|
private long size;
|
||||||
private Integer digit;
|
private Integer digit;
|
||||||
/**
|
/**
|
||||||
* 是否为可空
|
* 是否为可空
|
||||||
@ -118,7 +118,7 @@ public class Column implements Serializable, Cloneable {
|
|||||||
typeName = ReUtil.delLast("\\(\\d+\\)", typeName);
|
typeName = ReUtil.delLast("\\(\\d+\\)", typeName);
|
||||||
this.typeName = typeName;
|
this.typeName = typeName;
|
||||||
|
|
||||||
this.size = columnMetaRs.getInt("COLUMN_SIZE");
|
this.size = columnMetaRs.getLong("COLUMN_SIZE");
|
||||||
this.isNullable = columnMetaRs.getBoolean("NULLABLE");
|
this.isNullable = columnMetaRs.getBoolean("NULLABLE");
|
||||||
this.comment = columnMetaRs.getString("REMARKS");
|
this.comment = columnMetaRs.getString("REMARKS");
|
||||||
this.columnDef = columnMetaRs.getString("COLUMN_DEF");
|
this.columnDef = columnMetaRs.getString("COLUMN_DEF");
|
||||||
@ -238,7 +238,7 @@ public class Column implements Serializable, Cloneable {
|
|||||||
*
|
*
|
||||||
* @return 大小或数据长度
|
* @return 大小或数据长度
|
||||||
*/
|
*/
|
||||||
public int getSize() {
|
public long getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,12 @@ public class DbTest {
|
|||||||
Assert.assertEquals(4, count);
|
Assert.assertEquals(4, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void countByQueryTest() throws SQLException {
|
||||||
|
final long count = Db.use().count(Entity.create("user"));
|
||||||
|
Assert.assertEquals(4, count);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void countTest2() throws SQLException {
|
public void countTest2() throws SQLException {
|
||||||
final long count = Db.use().count("select * from user order by name DESC");
|
final long count = Db.use().count("select * from user order by name DESC");
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-dfa</artifactId>
|
<artifactId>hutool-dfa</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-extra</artifactId>
|
<artifactId>hutool-extra</artifactId>
|
||||||
|
@ -102,7 +102,7 @@ public class SshjSftp extends AbstractFtp {
|
|||||||
this.ssh = new SSHClient();
|
this.ssh = new SSHClient();
|
||||||
ssh.addHostKeyVerifier(new PromiscuousVerifier());
|
ssh.addHostKeyVerifier(new PromiscuousVerifier());
|
||||||
try {
|
try {
|
||||||
ssh.connect(ftpConfig.getHost());
|
ssh.connect(ftpConfig.getHost(), ftpConfig.getPort());
|
||||||
ssh.authPassword(ftpConfig.getUser(), ftpConfig.getPassword());
|
ssh.authPassword(ftpConfig.getUser(), ftpConfig.getPassword());
|
||||||
ssh.setRemoteCharset(ftpConfig.getCharset());
|
ssh.setRemoteCharset(ftpConfig.getCharset());
|
||||||
this.sftp = ssh.newSFTPClient();
|
this.sftp = ssh.newSFTPClient();
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-http</artifactId>
|
<artifactId>hutool-http</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-json</artifactId>
|
<artifactId>hutool-json</artifactId>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.hutool.json;
|
package cn.hutool.json;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.convert.ConvertException;
|
import cn.hutool.core.convert.ConvertException;
|
||||||
import cn.hutool.core.convert.Converter;
|
import cn.hutool.core.convert.Converter;
|
||||||
@ -85,6 +86,9 @@ public class JSONConverter implements Converter<JSON> {
|
|||||||
}
|
}
|
||||||
target.parse(value);
|
target.parse(value);
|
||||||
return (T) target;
|
return (T) target;
|
||||||
|
} else if(targetType == byte[].class && value instanceof CharSequence){
|
||||||
|
// issue#I59LW4
|
||||||
|
return (T) Base64.decode((CharSequence) value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +190,17 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
|||||||
return Convert.toLocalDateTime(obj, defaultValue);
|
return Convert.toLocalDateTime(obj, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取byte[]数据
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return 值
|
||||||
|
* @since 5.8.2
|
||||||
|
*/
|
||||||
|
default byte[] getBytes(K key) {
|
||||||
|
return get(key, byte[].class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定类型的对象<br>
|
* 获取指定类型的对象<br>
|
||||||
* 转换失败或抛出异常
|
* 转换失败或抛出异常
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.hutool.json;
|
package cn.hutool.json;
|
||||||
|
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
import cn.hutool.core.io.file.FileReader;
|
import cn.hutool.core.io.file.FileReader;
|
||||||
import cn.hutool.core.lang.TypeReference;
|
import cn.hutool.core.lang.TypeReference;
|
||||||
@ -784,6 +785,12 @@ public class JSONUtil {
|
|||||||
|
|
||||||
// JSONArray
|
// JSONArray
|
||||||
if (object instanceof Iterable || ArrayUtil.isArray(object)) {
|
if (object instanceof Iterable || ArrayUtil.isArray(object)) {
|
||||||
|
if(object instanceof byte[]){
|
||||||
|
// issue#I59LW4
|
||||||
|
// json内容中的bytes默认转为Base64
|
||||||
|
return Base64.encode((byte[]) object);
|
||||||
|
}
|
||||||
|
|
||||||
return new JSONArray(object, jsonConfig);
|
return new JSONArray(object, jsonConfig);
|
||||||
}
|
}
|
||||||
// JSONObject
|
// JSONObject
|
||||||
|
@ -144,6 +144,7 @@ public class ObjectMapper {
|
|||||||
} else if (source instanceof InputStream) {
|
} else if (source instanceof InputStream) {
|
||||||
mapFromTokener(new JSONTokener((InputStream) source, jsonArray.getConfig()), jsonArray, filter);
|
mapFromTokener(new JSONTokener((InputStream) source, jsonArray.getConfig()), jsonArray, filter);
|
||||||
} else if (source instanceof byte[]) {
|
} else if (source instanceof byte[]) {
|
||||||
|
// bytes按照JSON的二进制流对待
|
||||||
mapFromTokener(new JSONTokener(IoUtil.toStream((byte[]) source), jsonArray.getConfig()), jsonArray, filter);
|
mapFromTokener(new JSONTokener(IoUtil.toStream((byte[]) source), jsonArray.getConfig()), jsonArray, filter);
|
||||||
} else if (source instanceof JSONTokener) {
|
} else if (source instanceof JSONTokener) {
|
||||||
mapFromTokener((JSONTokener) source, jsonArray, filter);
|
mapFromTokener((JSONTokener) source, jsonArray, filter);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.hutool.json.serialize;
|
package cn.hutool.json.serialize;
|
||||||
|
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.date.TemporalAccessorUtil;
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
||||||
@ -167,7 +168,6 @@ public class JSONWriter extends Writer {
|
|||||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeKey(key).writeValueDirect(value);
|
return writeKey(key).writeValueDirect(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,13 @@ public class JSONWriter extends Writer {
|
|||||||
} else if (value instanceof Map || value instanceof Map.Entry) {
|
} else if (value instanceof Map || value instanceof Map.Entry) {
|
||||||
new JSONObject(value).write(writer, indentFactor, indent);
|
new JSONObject(value).write(writer, indentFactor, indent);
|
||||||
} else if (value instanceof Iterable || value instanceof Iterator || ArrayUtil.isArray(value)) {
|
} else if (value instanceof Iterable || value instanceof Iterator || ArrayUtil.isArray(value)) {
|
||||||
new JSONArray(value).write(writer, indentFactor, indent);
|
if(value instanceof byte[]){
|
||||||
|
// issue#I59LW4
|
||||||
|
// json内容中的bytes默认转为Base64
|
||||||
|
writeStrValue(Base64.encode((byte[]) value));
|
||||||
|
}else{
|
||||||
|
new JSONArray(value).write(writer, indentFactor, indent);
|
||||||
|
}
|
||||||
} else if (value instanceof Number) {
|
} else if (value instanceof Number) {
|
||||||
writeNumberValue((Number) value);
|
writeNumberValue((Number) value);
|
||||||
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
|
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package cn.hutool.json;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class IssueI59LW4Test {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bytesTest(){
|
||||||
|
final JSONObject jsonObject = JSONUtil.createObj().set("bytes", new byte[]{1});
|
||||||
|
Assert.assertEquals("{\"bytes\":\"AQ==\"}", jsonObject.toString());
|
||||||
|
|
||||||
|
final byte[] bytes = jsonObject.getBytes("bytes");
|
||||||
|
Assert.assertArrayEquals(new byte[]{1}, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bytesInJSONArrayTest(){
|
||||||
|
final JSONArray jsonArray = JSONUtil.createArray().set(new byte[]{1});
|
||||||
|
Assert.assertEquals("[\"AQ==\"]", jsonArray.toString());
|
||||||
|
|
||||||
|
final byte[] bytes = jsonArray.getBytes(0);
|
||||||
|
Assert.assertArrayEquals(new byte[]{1}, bytes);
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-jwt</artifactId>
|
<artifactId>hutool-jwt</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-log</artifactId>
|
<artifactId>hutool-log</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-poi</artifactId>
|
<artifactId>hutool-poi</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-script</artifactId>
|
<artifactId>hutool-script</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-setting</artifactId>
|
<artifactId>hutool-setting</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-socket</artifactId>
|
<artifactId>hutool-socket</artifactId>
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package cn.hutool.socket;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.thread.ThreadFactoryBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.channels.AsynchronousChannelGroup;
|
||||||
|
import java.nio.channels.AsynchronousSocketChannel;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Channel相关封装
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.8.2
|
||||||
|
*/
|
||||||
|
public class ChannelUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建{@link AsynchronousChannelGroup}
|
||||||
|
*
|
||||||
|
* @param poolSize 线程池大小
|
||||||
|
* @return {@link AsynchronousChannelGroup}
|
||||||
|
*/
|
||||||
|
public static AsynchronousChannelGroup createFixedGroup(int poolSize) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return AsynchronousChannelGroup.withFixedThreadPool(//
|
||||||
|
poolSize, // 默认线程池大小
|
||||||
|
ThreadFactoryBuilder.create().setNamePrefix("Huool-socket-").build()//
|
||||||
|
);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IORuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接到指定地址
|
||||||
|
*
|
||||||
|
* @param group {@link AsynchronousChannelGroup}
|
||||||
|
* @param address 地址信息,包括地址和端口
|
||||||
|
* @return {@link AsynchronousSocketChannel}
|
||||||
|
*/
|
||||||
|
public static AsynchronousSocketChannel connect(AsynchronousChannelGroup group, InetSocketAddress address) {
|
||||||
|
AsynchronousSocketChannel channel;
|
||||||
|
try {
|
||||||
|
channel = AsynchronousSocketChannel.open(group);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IORuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
channel.connect(address).get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
IoUtil.close(channel);
|
||||||
|
throw new SocketRuntimeException(e);
|
||||||
|
}
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,14 @@
|
|||||||
package cn.hutool.socket.aio;
|
package cn.hutool.socket.aio;
|
||||||
|
|
||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.socket.ChannelUtil;
|
||||||
import cn.hutool.core.io.IoUtil;
|
|
||||||
import cn.hutool.core.thread.ThreadFactoryBuilder;
|
|
||||||
import cn.hutool.socket.SocketConfig;
|
import cn.hutool.socket.SocketConfig;
|
||||||
import cn.hutool.socket.SocketRuntimeException;
|
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketOption;
|
import java.net.SocketOption;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.AsynchronousChannelGroup;
|
|
||||||
import java.nio.channels.AsynchronousSocketChannel;
|
import java.nio.channels.AsynchronousSocketChannel;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aio Socket客户端
|
* Aio Socket客户端
|
||||||
@ -120,25 +115,7 @@ public class AioClient implements Closeable{
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
private static AsynchronousSocketChannel createChannel(InetSocketAddress address, int poolSize) {
|
private static AsynchronousSocketChannel createChannel(InetSocketAddress address, int poolSize) {
|
||||||
|
return ChannelUtil.connect(ChannelUtil.createFixedGroup(poolSize), address);
|
||||||
AsynchronousSocketChannel channel;
|
|
||||||
try {
|
|
||||||
AsynchronousChannelGroup group = AsynchronousChannelGroup.withFixedThreadPool(//
|
|
||||||
poolSize, // 默认线程池大小
|
|
||||||
ThreadFactoryBuilder.create().setNamePrefix("Huool-socket-").build()//
|
|
||||||
);
|
|
||||||
channel = AsynchronousSocketChannel.open(group);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IORuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
channel.connect(address).get();
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
IoUtil.close(channel);
|
|
||||||
throw new SocketRuntimeException(e);
|
|
||||||
}
|
|
||||||
return channel;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------- Private method end
|
// ------------------------------------------------------------------------------------- Private method end
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
package cn.hutool.socket.aio;
|
package cn.hutool.socket.aio;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Console;
|
import cn.hutool.core.lang.Console;
|
||||||
|
import cn.hutool.core.thread.ThreadFactoryBuilder;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.AsynchronousChannelGroup;
|
||||||
|
|
||||||
public class AioClientTest {
|
public class AioClientTest {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) throws IOException {
|
||||||
|
final AsynchronousChannelGroup GROUP = AsynchronousChannelGroup.withFixedThreadPool(//
|
||||||
|
Runtime.getRuntime().availableProcessors(), // 默认线程池大小
|
||||||
|
ThreadFactoryBuilder.create().setNamePrefix("Huool-socket-").build()//
|
||||||
|
);
|
||||||
|
|
||||||
AioClient client = new AioClient(new InetSocketAddress("localhost", 8899), new SimpleIoAction() {
|
AioClient client = new AioClient(new InetSocketAddress("localhost", 8899), new SimpleIoAction() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-system</artifactId>
|
<artifactId>hutool-system</artifactId>
|
||||||
|
2
pom.xml
2
pom.xml
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.8.1</version>
|
<version>5.8.2</version>
|
||||||
<name>hutool</name>
|
<name>hutool</name>
|
||||||
<description>Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。</description>
|
<description>Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。</description>
|
||||||
<url>https://github.com/dromara/hutool</url>
|
<url>https://github.com/dromara/hutool</url>
|
||||||
|
Loading…
Reference in New Issue
Block a user