fic null point bug

This commit is contained in:
Looly 2020-04-23 10:07:56 +08:00
parent 2b9fb67cd0
commit 9f40666c95
9 changed files with 116 additions and 32 deletions

View File

@ -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)

View File

@ -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
);
} }
/** /**

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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) {

View File

@ -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

View 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;
}
}