Merge branch 'v5-dev' of gitee.com:dromara/hutool into v5-dev

This commit is contained in:
Looly 2022-09-05 10:36:17 +08:00
commit d141efea62
11 changed files with 43 additions and 70 deletions

View File

@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
# 5.8.6.M1 (2022-09-04)
# 5.8.6.M1 (2022-09-05)
### ❌不兼容特性
* 【json 】 由于设计缺陷导致JSONObject#write方法中Filter中key的泛型不得已变动为Object以解决无法递归的bugissue#I5OMSC@Gitee
@ -24,6 +24,7 @@
* 【core 】 添加ObjectUtil的别名工具类ObjUtil
* 【core 】 扩展LocalDateTimeUtil.isIn方法使用场景pr#2589@Github
* 【core 】 MapUtil增加根据entry分组pr#2591@Github
* 【core 】 优化 getProcessorCount 潜在的获取不到的问题pr#792@Gitee
*
### 🐞Bug修复
* 【http 】 修复https下可能的Patch、Get请求失效问题issue#I3Z3DH@Gitee

View File

@ -285,8 +285,8 @@ public class ConverterRegistry implements Serializable {
final Class<?> clazz = ClassLoaderUtil.loadClass("cn.hutool.json.BeanConverterForJSON");
return ((Converter<T>)ReflectUtil.newInstance(clazz, type)).convert(value, defaultValue);
}catch (final Throwable ignore){
return new BeanConverter<T>(type).convert(value, defaultValue);
}
return new BeanConverter<T>(type).convert(value, defaultValue);
}
// 无法转换

View File

@ -31,7 +31,7 @@ public class BeanConverter<T> extends AbstractConverter<T> {
private final Type beanType;
private final Class<T> beanClass;
protected CopyOptions copyOptions;
private final CopyOptions copyOptions;
/**
* 构造默认转换选项注入失败的字段忽略

View File

@ -1,6 +1,8 @@
package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
@ -23,6 +25,7 @@ import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
/**
@ -109,6 +112,17 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
} else if (value instanceof Calendar) {
final Calendar calendar = (Calendar) value;
return parseFromInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
} else if (value instanceof Map) {
final Map<?, ?> map = (Map<?, ?>) value;
if (LocalDate.class.equals(this.targetType)) {
return LocalDate.of(Convert.toInt(map.get("year")), Convert.toInt(map.get("month")), Convert.toInt(map.get("day")));
} else if (LocalDateTime.class.equals(this.targetType)) {
return LocalDateTime.of(Convert.toInt(map.get("year")), Convert.toInt(map.get("month")), Convert.toInt(map.get("day")),
Convert.toInt(map.get("hour")), Convert.toInt(map.get("minute")), Convert.toInt(map.get("second")), Convert.toInt(map.get("second")));
} else if (LocalTime.class.equals(this.targetType)) {
return LocalTime.of(Convert.toInt(map.get("hour")), Convert.toInt(map.get("minute")), Convert.toInt(map.get("second")), Convert.toInt(map.get("nano")));
}
throw new ConvertException("Unsupported type: [{}] from map: [{}]", this.targetType, map);
} else {
return parseFromCharSequence(convertToStr(value));
}

View File

@ -1,5 +1,7 @@
package cn.hutool.core.thread;
import cn.hutool.core.util.RuntimeUtil;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
@ -126,7 +128,7 @@ public class ThreadUtil {
}
// 最佳的线程数 = CPU可用核心数 / (1 - 阻塞系数)
int poolSize = (int) (Runtime.getRuntime().availableProcessors() / (1 - blockingCoefficient));
int poolSize = (int) (RuntimeUtil.getProcessorCount() / (1 - blockingCoefficient));
return ExecutorBuilder.create().setCorePoolSize(poolSize).setMaxPoolSize(poolSize).setKeepAliveTime(0L).build();
}

View File

@ -13,6 +13,7 @@ import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 系统运行时工具类用于执行系统命令的工具
@ -234,11 +235,21 @@ public class RuntimeUtil {
/**
* 获得JVM可用的处理器数量一般为CPU核心数
*
* <p>
* 这里做一个特殊的处理,在特殊的CPU上面会有获取不到CPU数量的情况所以这里做一个保护;
* 默认给一个7真实的CPU基本都是偶数方便区分
* 如果不做处理会出现创建线程池时{@link ThreadPoolExecutor}抛出异常{@link IllegalArgumentException}
* </p>
*
* @return 可用的处理器数量
* @since 5.3.0
*/
public static int getProcessorCount() {
return Runtime.getRuntime().availableProcessors();
int cpu = Runtime.getRuntime().availableProcessors();
if (cpu <= 0) {
cpu = 7;
}
return cpu;
}
/**

View File

@ -43,4 +43,11 @@ public class RuntimeUtilTest {
int pid = RuntimeUtil.getPid();
Assert.assertTrue(pid > 0);
}
@Test
public void getProcessorCountTest(){
int cpu = RuntimeUtil.getProcessorCount();
Console.log("cpu个数{}", cpu);
Assert.assertTrue(cpu > 0);
}
}

View File

@ -1,43 +0,0 @@
package cn.hutool.json;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.impl.BeanConverter;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONDeserializer;
import java.lang.reflect.Type;
/**
* 针对JSON的Bean转换封装<br>
* 此类时针对5.x中设计缺陷设计的类在ConverterRegistry中通过反射调用
*
* @param <T> Bean类型
* @since 5.8.6
*/
public class BeanConverterForJSON<T> extends BeanConverter<T> {
public BeanConverterForJSON(Type beanType) {
super(beanType);
}
@Override
protected T convertInternal(final Object value) {
final Class<T> targetType = getTargetType();
if (value instanceof JSON) {
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
if (null != deserializer) {
//noinspection unchecked
return (T) deserializer.deserialize((JSON) value);
}
// issue#2212@Github
// 在JSONObject转Bean时读取JSONObject本身的配置文件
if (value instanceof JSONGetter && BeanUtil.hasSetter(targetType)) {
final JSONConfig config = ((JSONGetter<?>) value).getConfig();
this.copyOptions.setIgnoreError(config.isIgnoreError());
}
}
return super.convertInternal(value);
}
}

View File

@ -9,12 +9,10 @@ import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONArraySerializer;
import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONObjectSerializer;
import cn.hutool.json.serialize.JSONSerializer;
import java.io.File;
import java.io.IOException;
@ -763,24 +761,6 @@ public class JSONUtil {
return object;
}
// 自定义序列化
final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(object.getClass());
if (null != serializer) {
final Type jsonType = TypeUtil.getTypeArgument(serializer.getClass());
if (null != jsonType) {
final JSON json;
if (serializer instanceof JSONObjectSerializer) {
json = new JSONObject(jsonConfig);
} else if (serializer instanceof JSONArraySerializer) {
json = new JSONArray(jsonConfig);
} else{
throw new JSONException("Unsupported JSONSerializer type: " + serializer.getClass());
}
serializer.serialize(json, object);
return json;
}
}
try {
// fix issue#1399@Github
if(object instanceof SQLException){

View File

@ -12,7 +12,7 @@ public class Issue2447Test {
Time time = new Time();
time.setTime(LocalDateTime.of(1970, 1, 2, 10, 0, 1, 0));
String timeStr = JSONUtil.toJsonStr(time);
Assert.assertEquals(timeStr, "{\"time\":93601000}");
Assert.assertEquals("{\"time\":93601000}", timeStr);
Assert.assertEquals(JSONUtil.toBean(timeStr, Time.class).getTime(), time.getTime());
}

View File

@ -2,6 +2,7 @@ package cn.hutool.socket.aio;
import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import java.io.IOException;
@ -12,7 +13,7 @@ import java.nio.channels.AsynchronousChannelGroup;
public class AioClientTest {
public static void main(String[] args) throws IOException {
final AsynchronousChannelGroup GROUP = AsynchronousChannelGroup.withFixedThreadPool(//
Runtime.getRuntime().availableProcessors(), // 默认线程池大小
RuntimeUtil.getProcessorCount(), // 默认线程池大小
ThreadFactoryBuilder.create().setNamePrefix("Huool-socket-").build()//
);