mirror of
				https://gitee.com/dromara/hutool.git
				synced 2025-10-31 16:36:56 +08:00 
			
		
		
		
	Merge pull request #3814 from TomShiDi/json-getbypath-type-improve
feature: JSON的getByPath方法新增更为通用的指定出参类型重载
This commit is contained in:
		| @@ -97,6 +97,32 @@ public interface JSON extends Cloneable, Serializable, IJSONTypeConverter { | |||||||
| 	 */ | 	 */ | ||||||
| 	<T> T getByPath(String expression, Class<T> resultType); | 	<T> T getByPath(String expression, Class<T> resultType); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * 通过表达式获取JSON中嵌套的对象<br> | ||||||
|  | 	 * <ol> | ||||||
|  | 	 * <li>.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值</li> | ||||||
|  | 	 * <li>[]表达式,可以获取集合等对象中对应index的值</li> | ||||||
|  | 	 * </ol> | ||||||
|  | 	 * <p> | ||||||
|  | 	 * 表达式栗子: | ||||||
|  | 	 * | ||||||
|  | 	 * <pre> | ||||||
|  | 	 * persion | ||||||
|  | 	 * persion.name | ||||||
|  | 	 * persons[3] | ||||||
|  | 	 * person.friends[5].name | ||||||
|  | 	 * </pre> | ||||||
|  | 	 * <p> | ||||||
|  | 	 * 获取表达式对应值后转换为对应类型的值 | ||||||
|  | 	 * | ||||||
|  | 	 * @param expression 表达式 | ||||||
|  | 	 * @param targetType 返回值类型 | ||||||
|  | 	 * @return 对象 | ||||||
|  | 	 * @see BeanPath#get(Object) | ||||||
|  | 	 * @since 5.8.34 | ||||||
|  | 	 */ | ||||||
|  | 	<T> T getByPath(String expression, TypeReference<T> targetType); | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * 格式化打印JSON,缩进为4个空格 | 	 * 格式化打印JSON,缩进为4个空格 | ||||||
| 	 * | 	 * | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package cn.hutool.json; | |||||||
| import cn.hutool.core.bean.BeanPath; | import cn.hutool.core.bean.BeanPath; | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.lang.Filter; | import cn.hutool.core.lang.Filter; | ||||||
|  | import cn.hutool.core.lang.TypeReference; | ||||||
| import cn.hutool.core.lang.Validator; | import cn.hutool.core.lang.Validator; | ||||||
| import cn.hutool.core.lang.mutable.Mutable; | import cn.hutool.core.lang.mutable.Mutable; | ||||||
| import cn.hutool.core.lang.mutable.MutableObj; | import cn.hutool.core.lang.mutable.MutableObj; | ||||||
| @@ -13,6 +14,7 @@ import cn.hutool.json.serialize.JSONWriter; | |||||||
|  |  | ||||||
| import java.io.StringWriter; | import java.io.StringWriter; | ||||||
| import java.io.Writer; | import java.io.Writer; | ||||||
|  | import java.lang.reflect.Type; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| @@ -195,7 +197,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando | |||||||
| 	 */ | 	 */ | ||||||
| 	public String join(String separator) throws JSONException { | 	public String join(String separator) throws JSONException { | ||||||
| 		return StrJoiner.of(separator) | 		return StrJoiner.of(separator) | ||||||
| 				.append(this, InternalJSONUtil::valueToString).toString(); | 			.append(this, InternalJSONUtil::valueToString).toString(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| @@ -218,6 +220,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando | |||||||
| 		return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); | 		return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T> T getByPath(String expression, TypeReference<T> targetType) { | ||||||
|  | 		return JSONConverter.jsonConvert(targetType, getByPath(expression), getConfig()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public void putByPath(String expression, Object value) { | 	public void putByPath(String expression, Object value) { | ||||||
| 		BeanPath.create(expression).set(this, value); | 		BeanPath.create(expression).set(this, value); | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package cn.hutool.json; | |||||||
| import cn.hutool.core.bean.BeanPath; | import cn.hutool.core.bean.BeanPath; | ||||||
| import cn.hutool.core.collection.CollectionUtil; | import cn.hutool.core.collection.CollectionUtil; | ||||||
| import cn.hutool.core.lang.Filter; | import cn.hutool.core.lang.Filter; | ||||||
|  | import cn.hutool.core.lang.TypeReference; | ||||||
| import cn.hutool.core.lang.mutable.MutablePair; | import cn.hutool.core.lang.mutable.MutablePair; | ||||||
| import cn.hutool.core.map.CaseInsensitiveMap; | import cn.hutool.core.map.CaseInsensitiveMap; | ||||||
| import cn.hutool.core.map.MapUtil; | import cn.hutool.core.map.MapUtil; | ||||||
| @@ -14,6 +15,7 @@ import cn.hutool.json.serialize.JSONWriter; | |||||||
|  |  | ||||||
| import java.io.StringWriter; | import java.io.StringWriter; | ||||||
| import java.io.Writer; | import java.io.Writer; | ||||||
|  | import java.lang.reflect.Type; | ||||||
| import java.math.BigDecimal; | import java.math.BigDecimal; | ||||||
| import java.math.BigInteger; | import java.math.BigInteger; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| @@ -161,8 +163,8 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON | |||||||
| 	@Deprecated | 	@Deprecated | ||||||
| 	public JSONObject(Object source, boolean ignoreNullValue, boolean isOrder) { | 	public JSONObject(Object source, boolean ignoreNullValue, boolean isOrder) { | ||||||
| 		this(source, JSONConfig.create()// | 		this(source, JSONConfig.create()// | ||||||
| 				.setIgnoreCase((source instanceof CaseInsensitiveMap))// | 			.setIgnoreCase((source instanceof CaseInsensitiveMap))// | ||||||
| 				.setIgnoreNullValue(ignoreNullValue) | 			.setIgnoreNullValue(ignoreNullValue) | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -320,6 +322,11 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON | |||||||
| 		return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); | 		return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T> T getByPath(String expression, TypeReference<T> targetType) { | ||||||
|  | 		return JSONConverter.jsonConvert(targetType, getByPath(expression), getConfig()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public void putByPath(String expression, Object value) { | 	public void putByPath(String expression, Object value) { | ||||||
| 		BeanPath.create(expression).set(this, value); | 		BeanPath.create(expression).set(this, value); | ||||||
| @@ -561,7 +568,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON | |||||||
| 	 */ | 	 */ | ||||||
| 	public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Object, Object>> filter) throws JSONException { | 	public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Object, Object>> filter) throws JSONException { | ||||||
| 		final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config) | 		final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config) | ||||||
| 				.beginObj(); | 			.beginObj(); | ||||||
| 		this.forEach((key, value) -> jsonWriter.writeField(new MutablePair<>(key, value), filter)); | 		this.forEach((key, value) -> jsonWriter.writeField(new MutablePair<>(key, value), filter)); | ||||||
| 		jsonWriter.end(); | 		jsonWriter.end(); | ||||||
| 		// 此处不关闭Writer,考虑writer后续还需要填内容 | 		// 此处不关闭Writer,考虑writer后续还需要填内容 | ||||||
|   | |||||||
| @@ -1,8 +1,12 @@ | |||||||
| package cn.hutool.json; | package cn.hutool.json; | ||||||
|  |  | ||||||
| import static org.junit.jupiter.api.Assertions.*; | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.lang.TypeReference; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * JSON路径单元测试 |  * JSON路径单元测试 | ||||||
|  * |  * | ||||||
| @@ -27,4 +31,23 @@ public class JSONPathTest { | |||||||
| 		Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L); | 		Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L); | ||||||
| 		assertEquals(111L, accountId.longValue()); | 		assertEquals(111L, accountId.longValue()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	@Test | ||||||
|  | 	public void getByPathTest3(){ | ||||||
|  | 		String str = "[{'accountId':1},{'accountId':2},{'accountId':3}]"; | ||||||
|  | 		JSON json = JSONUtil.parse(str); | ||||||
|  | 		// 返回指定泛型的对象 List<Long> | ||||||
|  | 		List<Long> accountIds = json.getByPath("$.accountId", new TypeReference<List<Long>>() { | ||||||
|  | 		}); | ||||||
|  | 		assertNotNull(accountIds); | ||||||
|  | 		assertArrayEquals(new Long[]{1L, 2L, 3L}, accountIds.toArray()); | ||||||
|  |  | ||||||
|  | 		str = "{\"accountInfos\": [{\"accountId\":1},{\"accountId\":2},{\"accountId\":3}]}"; | ||||||
|  | 		json = JSONUtil.parse(str); | ||||||
|  | 		// 返回指定泛型的对象 List<Long> | ||||||
|  | 		accountIds = json.getByPath("$.accountInfos.accountId", new TypeReference<List<Long>>() { | ||||||
|  | 		}); | ||||||
|  | 		assertNotNull(accountIds); | ||||||
|  | 		assertArrayEquals(new Long[]{1L, 2L, 3L}, accountIds.toArray()); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Golden Looly
					Golden Looly