mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add JSONBeanParser
This commit is contained in:
parent
a9282b9d7c
commit
df726654af
@ -9,6 +9,7 @@
|
||||
* 【core 】 MapProxy支持return this的setter方法(pr#392@Gitee)
|
||||
* 【core 】 BeeDSFactory移除sqlite事务修复代码,新版本BeeCP已修复
|
||||
* 【core 】 增加compress包,扩充Zip操作灵活性
|
||||
* 【json 】 增加JSONBeanParser
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 改进NumberChineseFormatter算法,补充完整单元测试,解决零问题
|
||||
|
@ -20,7 +20,7 @@ public class DateRange extends Range<DateTime> {
|
||||
* @param end 结束日期时间(包括)
|
||||
* @param unit 步进单位
|
||||
*/
|
||||
public DateRange(Date start, Date end, final DateField unit) {
|
||||
public DateRange(Date start, Date end, DateField unit) {
|
||||
this(start, end, unit, 1);
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ public class DateRange extends Range<DateTime> {
|
||||
* @param unit 步进单位
|
||||
* @param step 步进数
|
||||
*/
|
||||
public DateRange(Date start, Date end, final DateField unit, final int step) {
|
||||
public DateRange(Date start, Date end, DateField unit, int step) {
|
||||
this(start, end, unit, step, true, true);
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ public class DateRange extends Range<DateTime> {
|
||||
* @param isIncludeStart 是否包含开始的时间
|
||||
* @param isIncludeEnd 是否包含结束的时间
|
||||
*/
|
||||
public DateRange(Date start, Date end, final DateField unit, final int step, boolean isIncludeStart, boolean isIncludeEnd) {
|
||||
public DateRange(Date start, Date end, DateField unit, int step, boolean isIncludeStart, boolean isIncludeEnd) {
|
||||
super(DateUtil.date(start), DateUtil.date(end), (current, end1, index) -> {
|
||||
final DateTime dt = DateUtil.date(start).offsetNew(unit, (index + 1) * step);
|
||||
if (dt.isAfter(end1)) {
|
||||
|
18
hutool-json/src/main/java/cn/hutool/json/JSONBeanParser.java
Executable file
18
hutool-json/src/main/java/cn/hutool/json/JSONBeanParser.java
Executable file
@ -0,0 +1,18 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
/**
|
||||
* 实现此接口的类可以通过实现{@code parse(value)}方法来将JSON中的值解析为此对象的值
|
||||
*
|
||||
* @author Looly
|
||||
* @since 5.7.8
|
||||
*/
|
||||
public interface JSONBeanParser<T> {
|
||||
|
||||
/**
|
||||
* value转Bean<br>
|
||||
* 通过实现此接口,将JSON中的值填充到当前对象的字段值中,即对象自行实现JSON反序列化逻辑
|
||||
*
|
||||
* @param value 被解析的对象类型,可能为JSON或者普通String、Number等
|
||||
*/
|
||||
void parse(T value);
|
||||
}
|
@ -6,6 +6,7 @@ import cn.hutool.core.convert.Converter;
|
||||
import cn.hutool.core.convert.ConverterRegistry;
|
||||
import cn.hutool.core.convert.impl.ArrayConverter;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.TypeUtil;
|
||||
import cn.hutool.json.serialize.GlobalSerializeMapping;
|
||||
@ -16,7 +17,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* JSON转换器
|
||||
*
|
||||
*
|
||||
* @author looly
|
||||
* @since 4.2.2
|
||||
*/
|
||||
@ -32,7 +33,7 @@ public class JSONConverter implements Converter<JSON> {
|
||||
|
||||
/**
|
||||
* JSONArray转数组
|
||||
*
|
||||
*
|
||||
* @param jsonArray JSONArray
|
||||
* @param arrayClass 数组元素类型
|
||||
* @return 数组对象
|
||||
@ -43,7 +44,7 @@ public class JSONConverter implements Converter<JSON> {
|
||||
|
||||
/**
|
||||
* 将JSONArray转换为指定类型的对量列表
|
||||
*
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param jsonArray JSONArray
|
||||
* @param elementType 对象元素类型
|
||||
@ -69,7 +70,21 @@ public class JSONConverter implements Converter<JSON> {
|
||||
if (JSONUtil.isNull(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// since 5.7.8,增加自定义Bean反序列化接口
|
||||
if(targetType instanceof Class){
|
||||
final Class<?> clazz = (Class<?>) targetType;
|
||||
if (JSONBeanParser.class.isAssignableFrom(clazz)){
|
||||
@SuppressWarnings("rawtypes")
|
||||
JSONBeanParser target = (JSONBeanParser) ReflectUtil.newInstanceIfPossible(clazz);
|
||||
if(null == target){
|
||||
throw new ConvertException("Can not instance [{}]", targetType);
|
||||
}
|
||||
target.parse(value);
|
||||
return (T) target;
|
||||
}
|
||||
}
|
||||
|
||||
if(value instanceof JSON) {
|
||||
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
|
||||
if(null != deserializer) {
|
||||
@ -85,7 +100,7 @@ public class JSONConverter implements Converter<JSON> {
|
||||
// 此处特殊处理,认为返回null属于正常情况
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
throw new ConvertException("Can not convert {} to type {}", value, ObjectUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType));
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package cn.hutool.json;
|
||||
/**
|
||||
* {@code JSONString}接口定义了一个{@code toJSONString()}<br>
|
||||
* 实现此接口的类可以通过实现{@code toJSONString()}方法来改变转JSON字符串的方式。
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
@ -11,7 +11,7 @@ public interface JSONString {
|
||||
|
||||
/**
|
||||
* 自定义转JSON字符串的方法
|
||||
*
|
||||
*
|
||||
* @return JSON字符串
|
||||
*/
|
||||
String toJSONString();
|
||||
|
@ -1,20 +1,33 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
|
||||
/**
|
||||
* JSON支持<br>
|
||||
* 继承此类实现实体类与JSON的相互转换
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class JSONSupport implements JSONString{
|
||||
|
||||
public class JSONSupport implements JSONString, JSONBeanParser<JSON> {
|
||||
|
||||
/**
|
||||
* JSON String转Bean
|
||||
*
|
||||
* @param jsonString JSON String
|
||||
*/
|
||||
public void parse(String jsonString){
|
||||
new JSONObject(jsonString).toBean(this.getClass());
|
||||
public void parse(String jsonString) {
|
||||
parse(new JSONObject(jsonString));
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON String转Bean
|
||||
*
|
||||
* @param json JSON String
|
||||
*/
|
||||
@Override
|
||||
public void parse(JSON json) {
|
||||
final JSONSupport support = json.toBean(this.getClass());
|
||||
BeanUtil.copyProperties(support, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,7 +36,7 @@ public class JSONSupport implements JSONString{
|
||||
public JSONObject toJSON() {
|
||||
return new JSONObject(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toJSONString() {
|
||||
return toJSON().toString();
|
||||
@ -31,7 +44,7 @@ public class JSONSupport implements JSONString{
|
||||
|
||||
/**
|
||||
* 美化的JSON(使用回车缩进显示JSON),用于打印输出debug
|
||||
*
|
||||
*
|
||||
* @return 美化的JSON
|
||||
*/
|
||||
public String toPrettyString() {
|
||||
|
48
hutool-json/src/test/java/cn/hutool/json/IssuesI44E4HTest.java
Executable file
48
hutool-json/src/test/java/cn/hutool/json/IssuesI44E4HTest.java
Executable file
@ -0,0 +1,48 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.json.serialize.GlobalSerializeMapping;
|
||||
import cn.hutool.json.serialize.JSONDeserializer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* 测试自定义反序列化
|
||||
*/
|
||||
public class IssuesI44E4HTest {
|
||||
|
||||
@Test
|
||||
public void deserializerTest(){
|
||||
GlobalSerializeMapping.put(TestDto.class, (JSONDeserializer<TestDto>) json -> {
|
||||
final TestDto testDto = new TestDto();
|
||||
testDto.setMd(new AcBizModuleMd("name1", ((JSONObject)json).getStr("md")));
|
||||
return testDto;
|
||||
});
|
||||
|
||||
String jsonStr = "{\"md\":\"value1\"}";
|
||||
final TestDto testDto = JSONUtil.toBean(jsonStr, TestDto.class);
|
||||
Assert.assertEquals("value1", testDto.getMd().getValue());
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public static class AcBizModuleMd {
|
||||
private String name;
|
||||
private String value;
|
||||
// 值列表
|
||||
public static final AcBizModuleMd Value1 = new AcBizModuleMd("value1", "name1");
|
||||
public static final AcBizModuleMd Value2 = new AcBizModuleMd("value2", "name2");
|
||||
public static final AcBizModuleMd Value3 = new AcBizModuleMd("value3", "name3");
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class TestDto {
|
||||
private AcBizModuleMd md;
|
||||
}
|
||||
}
|
||||
|
||||
|
30
hutool-json/src/test/java/cn/hutool/json/JSONBeanParserTest.java
Executable file
30
hutool-json/src/test/java/cn/hutool/json/JSONBeanParserTest.java
Executable file
@ -0,0 +1,30 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import lombok.Data;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JSONBeanParserTest {
|
||||
|
||||
@Test
|
||||
public void parseTest(){
|
||||
String jsonStr = "{\"customName\": \"customValue\", \"customAddress\": \"customAddressValue\"}";
|
||||
final TestBean testBean = JSONUtil.toBean(jsonStr, TestBean.class);
|
||||
Assert.assertNotNull(testBean);
|
||||
Assert.assertEquals("customValue", testBean.getName());
|
||||
Assert.assertEquals("customAddressValue", testBean.getAddress());
|
||||
}
|
||||
|
||||
@Data
|
||||
static class TestBean implements JSONBeanParser<JSONObject>{
|
||||
|
||||
private String name;
|
||||
private String address;
|
||||
|
||||
@Override
|
||||
public void parse(JSONObject value) {
|
||||
this.name = value.getStr("customName");
|
||||
this.address = value.getStr("customAddress");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user