mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fic null point bug
This commit is contained in:
parent
2b9fb67cd0
commit
9f40666c95
@ -13,7 +13,8 @@
|
|||||||
### Bug修复
|
### Bug修复
|
||||||
* 【db 】 修复PageResult.isLast计算问题
|
* 【db 】 修复PageResult.isLast计算问题
|
||||||
* 【cron 】 修复更改系统时间后CronTimer被阻塞的问题(issue#838@Github)
|
* 【cron 】 修复更改系统时间后CronTimer被阻塞的问题(issue#838@Github)
|
||||||
* 【db 】 修复Page.addOrder无效问题(issue#838@Github)
|
* 【db 】 修复Page.addOrder无效问题(issue#I1F9MZ@Gitee)
|
||||||
|
* 【json 】 修复JSONConvert转换日期空指针问题(issue#I1F8M2@Gitee)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
## 5.3.1 (2020-04-17)
|
## 5.3.1 (2020-04-17)
|
||||||
|
@ -130,7 +130,10 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
|
|||||||
* @param bean Bean
|
* @param bean Bean
|
||||||
*/
|
*/
|
||||||
private void mapToBean(Map<?, ?> map, Object bean) {
|
private void mapToBean(Map<?, ?> map, Object bean) {
|
||||||
valueProviderToBean(new MapValueProvider(map, this.copyOptions.ignoreCase), bean);
|
valueProviderToBean(
|
||||||
|
new MapValueProvider(map, this.copyOptions.ignoreCase, this.copyOptions.ignoreError),
|
||||||
|
bean
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +18,7 @@ public interface ValueProvider<T>{
|
|||||||
* 返回值一般需要匹配被注入类型,如果不匹配会调用默认转换 Convert#convert(Type, Object)实现转换
|
* 返回值一般需要匹配被注入类型,如果不匹配会调用默认转换 Convert#convert(Type, Object)实现转换
|
||||||
*
|
*
|
||||||
* @param key Bean对象中参数名
|
* @param key Bean对象中参数名
|
||||||
* @param valueType 被注入的值得类型
|
* @param valueType 被注入的值的类型
|
||||||
* @return 对应参数名的值
|
* @return 对应参数名的值
|
||||||
*/
|
*/
|
||||||
Object value(T key, Type valueType);
|
Object value(T key, Type valueType);
|
||||||
|
@ -3,6 +3,7 @@ package cn.hutool.core.bean.copier.provider;
|
|||||||
import cn.hutool.core.bean.BeanDesc.PropDesc;
|
import cn.hutool.core.bean.BeanDesc.PropDesc;
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.bean.copier.ValueProvider;
|
import cn.hutool.core.bean.copier.ValueProvider;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.exceptions.UtilException;
|
import cn.hutool.core.exceptions.UtilException;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
@ -43,19 +44,22 @@ public class BeanValueProvider implements ValueProvider<String> {
|
|||||||
sourcePd = sourcePdMap.get(StrUtil.upperFirstAndAddPre(key, "is"));
|
sourcePd = sourcePdMap.get(StrUtil.upperFirstAndAddPre(key, "is"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object result = null;
|
||||||
if (null != sourcePd) {
|
if (null != sourcePd) {
|
||||||
final Method getter = sourcePd.getGetter();
|
final Method getter = sourcePd.getGetter();
|
||||||
if (null != getter) {
|
if (null != getter) {
|
||||||
try {
|
try {
|
||||||
return getter.invoke(source);
|
result = getter.invoke(source);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (false == ignoreError) {
|
if (false == ignoreError) {
|
||||||
throw new UtilException(e, "Inject [{}] error!", key);
|
throw new UtilException(e, "Inject [{}] error!", key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = Convert.convertWithCheck(valueType,result, null, ignoreError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,6 +17,7 @@ import java.util.Map;
|
|||||||
public class MapValueProvider implements ValueProvider<String> {
|
public class MapValueProvider implements ValueProvider<String> {
|
||||||
|
|
||||||
private final Map<?, ?> map;
|
private final Map<?, ?> map;
|
||||||
|
private final boolean ignoreError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
@ -25,6 +26,17 @@ public class MapValueProvider implements ValueProvider<String> {
|
|||||||
* @param ignoreCase 是否忽略key的大小写
|
* @param ignoreCase 是否忽略key的大小写
|
||||||
*/
|
*/
|
||||||
public MapValueProvider(Map<?, ?> map, boolean ignoreCase) {
|
public MapValueProvider(Map<?, ?> map, boolean ignoreCase) {
|
||||||
|
this(map, ignoreCase, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param map Map
|
||||||
|
* @param ignoreCase 是否忽略key的大小写
|
||||||
|
* @since 5.3.2
|
||||||
|
*/
|
||||||
|
public MapValueProvider(Map<?, ?> map, boolean ignoreCase, boolean ignoreError) {
|
||||||
if(false == ignoreCase || map instanceof CaseInsensitiveMap) {
|
if(false == ignoreCase || map instanceof CaseInsensitiveMap) {
|
||||||
//不忽略大小写或者提供的Map本身为CaseInsensitiveMap则无需转换
|
//不忽略大小写或者提供的Map本身为CaseInsensitiveMap则无需转换
|
||||||
this.map = map;
|
this.map = map;
|
||||||
@ -32,6 +44,7 @@ public class MapValueProvider implements ValueProvider<String> {
|
|||||||
//转换为大小写不敏感的Map
|
//转换为大小写不敏感的Map
|
||||||
this.map = new CaseInsensitiveMap<>(map);
|
this.map = new CaseInsensitiveMap<>(map);
|
||||||
}
|
}
|
||||||
|
this.ignoreError = ignoreError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -42,7 +55,7 @@ public class MapValueProvider implements ValueProvider<String> {
|
|||||||
value = map.get(StrUtil.toUnderlineCase(key));
|
value = map.get(StrUtil.toUnderlineCase(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Convert.convert(valueType, value);
|
return Convert.convertWithCheck(valueType, value, null, this.ignoreError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
package cn.hutool.core.convert;
|
package cn.hutool.core.convert;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import cn.hutool.core.convert.impl.CollectionConverter;
|
import cn.hutool.core.convert.impl.CollectionConverter;
|
||||||
import cn.hutool.core.convert.impl.EnumConverter;
|
import cn.hutool.core.convert.impl.EnumConverter;
|
||||||
import cn.hutool.core.convert.impl.MapConverter;
|
import cn.hutool.core.convert.impl.MapConverter;
|
||||||
@ -20,6 +11,21 @@ import cn.hutool.core.util.ClassUtil;
|
|||||||
import cn.hutool.core.util.HexUtil;
|
import cn.hutool.core.util.HexUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型转换器
|
* 类型转换器
|
||||||
*
|
*
|
||||||
@ -674,7 +680,7 @@ public class Convert {
|
|||||||
* @throws ConvertException 转换器不存在
|
* @throws ConvertException 转换器不存在
|
||||||
*/
|
*/
|
||||||
public static <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
|
public static <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
|
||||||
return ConverterRegistry.getInstance().convert(type, value, defaultValue);
|
return convertWithCheck(type, value, defaultValue, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -703,10 +709,30 @@ public class Convert {
|
|||||||
* @since 4.5.10
|
* @since 4.5.10
|
||||||
*/
|
*/
|
||||||
public static <T> T convertQuietly(Type type, Object value, T defaultValue) {
|
public static <T> T convertQuietly(Type type, Object value, T defaultValue) {
|
||||||
|
return convertWithCheck(type, value, defaultValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换值为指定类型,可选是否不抛异常转换<br>
|
||||||
|
* 当转换失败时返回默认值
|
||||||
|
*
|
||||||
|
* @param <T> 目标类型
|
||||||
|
* @param type 目标类型
|
||||||
|
* @param value 值
|
||||||
|
* @param defaultValue 默认值
|
||||||
|
* @param quietly 是否静默转换,true不抛异常
|
||||||
|
* @return 转换后的值
|
||||||
|
* @since 5.3.2
|
||||||
|
*/
|
||||||
|
public static <T> T convertWithCheck(Type type, Object value, T defaultValue, boolean quietly) {
|
||||||
|
final ConverterRegistry registry = ConverterRegistry.getInstance();
|
||||||
try {
|
try {
|
||||||
return convert(type, value, defaultValue);
|
return registry.convert(type, value, defaultValue);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
if(quietly){
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.convert.AbstractConverter;
|
|||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@ -107,6 +108,10 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
* @return 日期对象
|
* @return 日期对象
|
||||||
*/
|
*/
|
||||||
private TemporalAccessor parseFromCharSequence(CharSequence value) {
|
private TemporalAccessor parseFromCharSequence(CharSequence value) {
|
||||||
|
if(StrUtil.isBlank(value)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final Instant instant;
|
final Instant instant;
|
||||||
ZoneId zoneId;
|
ZoneId zoneId;
|
||||||
if (null != this.format) {
|
if (null != this.format) {
|
||||||
|
@ -71,21 +71,15 @@ public class JSONConverter implements Converter<JSON> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(value instanceof JSON) {
|
if(value instanceof JSON) {
|
||||||
JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
|
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
|
||||||
if(null != deserializer) {
|
if(null != deserializer) {
|
||||||
return (T) deserializer.deserialize((JSON)value);
|
return (T) deserializer.deserialize((JSON)value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object targetValue;
|
final T targetValue = ignoreError ?
|
||||||
try {
|
Convert.convertQuietly(targetType, value):
|
||||||
targetValue = Convert.convert(targetType, value);
|
Convert.convert(targetType, value);
|
||||||
} catch (ConvertException e) {
|
|
||||||
if (ignoreError) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null == targetValue && false == ignoreError) {
|
if (null == targetValue && false == ignoreError) {
|
||||||
if (StrUtil.isBlankIfStr(value)) {
|
if (StrUtil.isBlankIfStr(value)) {
|
||||||
@ -97,7 +91,7 @@ public class JSONConverter implements Converter<JSON> {
|
|||||||
throw new ConvertException("Can not convert {} to type {}", value, ObjectUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType));
|
throw new ConvertException("Can not convert {} to type {}", value, ObjectUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (T) targetValue;
|
return targetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
38
hutool-json/src/test/java/cn/hutool/json/IssueI1F8M2.java
Normal file
38
hutool-json/src/test/java/cn/hutool/json/IssueI1F8M2.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package cn.hutool.json;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://gitee.com/loolly/dashboard/issues?id=I1F8M2
|
||||||
|
*/
|
||||||
|
public class IssueI1F8M2 {
|
||||||
|
@Test
|
||||||
|
public void toBeanTest() {
|
||||||
|
String jsonStr = "{\"eventType\":\"fee\",\"fwdAlertingTime\":\"2020-04-22 16:34:13\",\"fwdAnswerTime\":\"\"}";
|
||||||
|
Param param = JSONUtil.toBean(jsonStr, Param.class);
|
||||||
|
Assert.assertEquals("2020-04-22T16:34:13", param.getFwdAlertingTime().toString());
|
||||||
|
Assert.assertNull(param.getFwdAnswerTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param类的字段
|
||||||
|
@Data
|
||||||
|
static class Param {
|
||||||
|
/**
|
||||||
|
* fee表示话单事件
|
||||||
|
*/
|
||||||
|
private String eventType;
|
||||||
|
/**
|
||||||
|
* 转接呼叫后振铃时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime fwdAlertingTime;
|
||||||
|
/**
|
||||||
|
* 转接呼叫后应答时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime fwdAnswerTime;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user