This commit is contained in:
Looly
2024-09-24 03:52:10 +08:00
parent 1b92f58bae
commit d8a7b9b440
23 changed files with 477 additions and 134 deletions

View File

@@ -18,9 +18,7 @@ package org.dromara.hutool.json;
import org.dromara.hutool.core.bean.path.BeanPath;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.json.serializer.JSONDeserializer;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.serializer.TypeAdapterManager;
import org.dromara.hutool.json.support.JSONNodeBeanFactory;
import org.dromara.hutool.json.writer.JSONWriter;
@@ -107,11 +105,70 @@ public interface JSON extends Serializable {
* persons[3]
* person.friends[5].name
* </pre>
* <p>
* 获取表达式对应值后转换为对应类型的值
*
* @param <T> 返回值类型
* @param expression 表达式
* @return 对象
* @see BeanPath#getValue(Object)
* @since 4.0.6
*/
default <T> T getObjByPath(final String expression) {
return getByPath(expression, Object.class);
}
/**
* 通过表达式获取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 <T> 返回值类型
* @param expression 表达式
* @param resultType 返回值类型
* @return 对象
* @see BeanPath#getValue(Object)
*/
default <T> T getByPath(final String expression, final Type resultType) {
final JSON json = getByPath(expression);
if (null == json) {
return null;
}
return JSONMapper.of(config(), null).toBean(json, resultType);
}
/**
* 通过表达式获取JSON中嵌套的JSON对象<br>
* <ol>
* <li>.表达式可以获取Bean对象中的属性字段值或者Map中key对应的值</li>
* <li>[]表达式可以获取集合等对象中对应index的值</li>
* </ol>
* <p>
* 表达式栗子:
*
* <pre>
* persion
* persion.name
* persons[3]
* person.friends[5].name
* </pre>
*
* @param expression 表达式
* @return JSON对象
* @see BeanPath#getValue(Object)
*/
default JSON getByPath(final String expression) {
return (JSON) BeanPath.of(expression).getValue(this);
@@ -142,42 +199,6 @@ public interface JSON extends Serializable {
BeanPath.of(expression, new JSONNodeBeanFactory(config())).setValue(this, value);
}
/**
* 通过表达式获取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 <T> 返回值类型
* @param expression 表达式
* @param resultType 返回值类型
* @return 对象
* @see BeanPath#getValue(Object)
* @since 4.0.6
*/
@SuppressWarnings("unchecked")
default <T> T getByPath(final String expression, final Type resultType) {
final JSON json = getByPath(expression);
if (null == json) {
return null;
}
final JSONDeserializer<Object> deserializer = TypeAdapterManager.getInstance().getDeserializer(json, resultType);
return (T) deserializer.deserialize(json, resultType);
}
/**
* 格式化打印JSON缩进为4个空格
*

View File

@@ -18,12 +18,12 @@ package org.dromara.hutool.json;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListWrapper;
import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.convert.impl.ArrayConverter;
import org.dromara.hutool.core.lang.Validator;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.serializer.impl.ArrayTypeAdapter;
import org.dromara.hutool.json.serializer.impl.IterTypeAdapter;
import org.dromara.hutool.json.writer.JSONWriter;
import java.util.*;
@@ -222,7 +222,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
@Override
@SuppressWarnings({"unchecked"})
public <T> T[] toArray(final T[] a) {
return (T[]) ArrayConverter.INSTANCE.convert(a.getClass().getComponentType(), this);
return (T[]) ArrayTypeAdapter.INSTANCE.deserialize(this, a.getClass().getComponentType());
}
/**
@@ -232,7 +232,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @return 实体类对象
*/
public Object toArray(final Class<?> arrayClass) {
return ArrayConverter.INSTANCE.convert(arrayClass, this);
return ArrayTypeAdapter.INSTANCE.deserialize(this, arrayClass.getComponentType());
}
/**
@@ -243,8 +243,9 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @return {@link ArrayList}
* @since 3.0.8
*/
@SuppressWarnings("unchecked")
public <T> List<T> toList(final Class<T> elementType) {
return ConvertUtil.toList(elementType, this);
return (List<T>) IterTypeAdapter.INSTANCE.deserialize(this, ArrayList.class, elementType);
}
/**

View File

@@ -161,47 +161,57 @@ public class JSONUtil {
if (obj instanceof byte[]) {
obj = new ByteArrayInputStream((byte[]) obj);
}
return (JSONObject) parse(obj, config, predicate);
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
if (obj instanceof CharSequence) {
return (JSONObject) jsonMapper.map((CharSequence) obj);
}
return jsonMapper.mapObj(obj);
}
/**
* JSON字符串转JSONArray
*
* @param arrayOrCollection 数组或集合对象
* @param obj 数组或集合对象或字符串等
* @return JSONArray
* @since 3.0.8
*/
public static JSONArray parseArray(final Object arrayOrCollection) {
return parseArray(arrayOrCollection, null);
public static JSONArray parseArray(final Object obj) {
return parseArray(obj, null);
}
/**
* JSON字符串转JSONArray
*
* @param arrayOrCollection 数组或集合对象
* @param obj 数组或集合对象
* @param config JSON配置
* @return JSONArray
* @since 5.3.1
*/
public static JSONArray parseArray(final Object arrayOrCollection, final JSONConfig config) {
return parseArray(arrayOrCollection, config, null);
public static JSONArray parseArray(final Object obj, final JSONConfig config) {
return parseArray(obj, config, null);
}
/**
* JSON字符串转JSONArray
*
* @param arrayOrCollection 数组或集合对象
* @param obj 数组或集合对象
* @param config JSON配置
* @param predicate index和值对过滤编辑器可以通过实现此接口完成解析前对键值对的过滤和修改操作{@link Predicate#test(Object)}为{@code true}保留
* @return JSONArray
* @since 5.3.1
*/
public static JSONArray parseArray(final Object arrayOrCollection, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
if (arrayOrCollection instanceof JSONObject) {
public static JSONArray parseArray(final Object obj, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
if (obj instanceof JSONObject) {
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
return jsonMapper.mapFromJSONObject((JSONObject) arrayOrCollection);
return jsonMapper.mapFromJSONObject((JSONObject) obj);
}
return (JSONArray) parse(arrayOrCollection, config, predicate);
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
if (obj instanceof CharSequence) {
return (JSONArray) jsonMapper.map((CharSequence) obj);
}
return jsonMapper.mapArray(obj);
}
/**
@@ -270,7 +280,7 @@ public class JSONUtil {
}
// endregion
// -------------------------------------------------------------------- Read start
// region ----- read
/**
* 读取JSON
@@ -307,9 +317,9 @@ public class JSONUtil {
public static JSONArray readJSONArray(final File file, final Charset charset) throws IORuntimeException {
return FileUtil.read(file, charset, JSONUtil::parseArray);
}
// -------------------------------------------------------------------- Read end
// endregion
// -------------------------------------------------------------------- toString start
// region ----- toJsonStr
/**
* 转换为格式化后的JSON字符串
@@ -380,9 +390,9 @@ public class JSONUtil {
public static JSONObject xmlToJson(final String xml) {
return JSONXMLUtil.toJSONObject(xml);
}
// -------------------------------------------------------------------- toString end
// endregion
// -------------------------------------------------------------------- toBean start
// region ----- toBean
/**
* 转为实体类对象
@@ -398,20 +408,6 @@ public class JSONUtil {
return toBean(json, (Type) clazz);
}
/**
* 转为实体类对象
*
* @param <T> Bean类型
* @param json JSONObject
* @param typeReference {@link TypeReference}类型参考子类可以获取其泛型参数中的Type类型
* @return 实体类对象
* @since 4.6.2
*/
public static <T> T toBean(final Object json, final TypeReference<T> typeReference) {
Assert.notNull(typeReference);
return toBean(json, typeReference.getType());
}
/**
* 转为实体类对象
*
@@ -445,8 +441,9 @@ public class JSONUtil {
}
return json.toBean(type);
}
// -------------------------------------------------------------------- toBean end
// endregion
// region ----- toList
/**
* 将JSONArray字符串转换为Bean的List默认为ArrayList
*
@@ -472,6 +469,9 @@ public class JSONUtil {
public static <T> List<T> toList(final JSONArray jsonArray, final Class<T> elementType) {
return null == jsonArray ? null : jsonArray.toList(elementType);
}
// endregion
// region ----- getByPath
/**
* 通过表达式获取JSON中嵌套的对象<br>
@@ -489,17 +489,45 @@ public class JSONUtil {
* person.friends[5].name
* </pre>
*
* @param <T> 值类型
* @param json {@link JSON}
* @param expression 表达式
* @return 对象
* @see JSON#getByPath(String)
*/
public static JSON getByPath(final JSON json, final String expression) {
public static <T> T getObjByPath(final JSON json, final String expression) {
return getByPath(json, expression, Object.class);
}
/**
* 通过表达式获取JSON中嵌套的对象<br>
* <ol>
* <li>.表达式可以获取Bean对象中的属性字段值或者Map中key对应的值</li>
* <li>[]表达式可以获取集合等对象中对应index的值</li>
* </ol>
* <p>
* 表达式栗子:
*
* <pre>
* persion
* persion.name
* persons[3]
* person.friends[5].name
* </pre>
*
* @param <T> 值类型
* @param json {@link JSON}
* @param expression 表达式
* @param type 结果类型
* @return 对象
* @see JSON#getByPath(String)
*/
public static <T> T getByPath(final JSON json, final String expression, final Type type) {
if ((null == json || StrUtil.isBlank(expression))) {
return null;
}
return json.getByPath(expression);
return json.getByPath(expression, type);
}
/**
@@ -539,6 +567,36 @@ public class JSONUtil {
return (T) json.getByPath(expression);
}
/**
* 通过表达式获取JSON中嵌套的对象<br>
* <ol>
* <li>.表达式可以获取Bean对象中的属性字段值或者Map中key对应的值</li>
* <li>[]表达式可以获取集合等对象中对应index的值</li>
* </ol>
* <p>
* 表达式栗子:
*
* <pre>
* persion
* persion.name
* persons[3]
* person.friends[5].name
* </pre>
*
* @param json {@link JSON}
* @param expression 表达式
* @return 对象
* @see JSON#getByPath(String)
*/
public static JSON getByPath(final JSON json, final String expression) {
if ((null == json || StrUtil.isBlank(expression))) {
return null;
}
return json.getByPath(expression);
}
// endregion
/**
* 格式化JSON字符串此方法并不严格检查JSON的格式正确与否
*
@@ -567,6 +625,7 @@ public class JSONUtil {
return json.isEmpty();
}
// region ----- isType
/**
* 是否为JSON类型字符串首尾都为大括号或中括号判定为JSON字符串
*
@@ -605,4 +664,5 @@ public class JSONUtil {
}
return StrUtil.isWrap(StrUtil.trim(str), '[', ']');
}
// endregion
}

View File

@@ -116,6 +116,9 @@ public class JacksonEngine extends AbstractJSONEngine implements Wrapper<ObjectM
// 允许没有引号的字段名(非标准)
JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES
);
mapper.disable(
// 空Bean默认转为{}
SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 支持Java8+日期格式
registerModule(mapper, "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");

View File

@@ -28,7 +28,8 @@ import org.dromara.hutool.json.*;
public interface JSONContext {
/**
* 获取当前JSON对象
* 获取当前JSON对象<br>
* 此对象为在Mapper时预定义的对象用于指定序列化的JSON类型
*
* @return JSON对象
*/

View File

@@ -109,7 +109,7 @@ public class JSONMapper implements Serializable {
if (json instanceof JSONPrimitive) {
return (T) ((JSONPrimitive) json).getValue();
}
return (T) this;
return (T) json;
}
JSONDeserializer<Object> deserializer = null;
@@ -149,7 +149,7 @@ public class JSONMapper implements Serializable {
public JSONArray mapFromJSONObject(final JSONObject jsonObject) {
final JSONArray array = JSONUtil.ofArray(jsonConfig);
for (final Map.Entry<String, JSON> entry : jsonObject) {
array.add(entry.getValue());
array.set(entry);
}
return array;
}
@@ -163,6 +163,11 @@ public class JSONMapper implements Serializable {
*/
public JSON map(final CharSequence source) {
final String jsonStr = StrUtil.trim(source);
if(StrUtil.isEmpty(jsonStr)){
// https://www.rfc-editor.org/rfc/rfc8259#section-7
// 未被包装的空串理解为null
return null;
}
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
final JSONObject jsonObject = JSONUtil.ofObj(jsonConfig);
@@ -177,17 +182,65 @@ public class JSONMapper implements Serializable {
* 在需要的时候转换映射对象<br>
* 包装包括:
* <ul>
* <li>array or collection =》 JSONArray</li>
* <li>map =》 JSONObject</li>
* <li>standard property (Double, String, et al) =》 原对象</li>
* <li>来自于java包 =》 字符串</li>
* <li>其它 =》 尝试包装为JSONObject否则返回{@code null}</li>
* <li>array or collection =》 JSONArray</li>
* <li>map =》 JSONObject</li>
* <li>standard property (Double, String, et al) =》 原对象</li>
* <li>其它 =》 尝试包装为JSONObject否则返回{@code null}</li>
* </ul>
*
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSON map(Object obj) {
public JSON map(final Object obj) {
return mapTo(obj, null);
}
/**
* 在需要的时候转换映射对象<br>
* 包装包括:
* <ul>
* <li>map =》 JSONObject</li>
* <li>其它 =》 尝试包装为JSONObject否则返回{@code null}</li>
* </ul>
*
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSONObject mapObj(final Object obj) {
return mapTo(obj, JSONUtil.ofObj(jsonConfig));
}
/**
* 在需要的时候转换映射对象<br>
* 包装包括:
* <ul>
* <li>array or collection =》 JSONArray</li>
* </ul>
*
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSONArray mapArray(final Object obj) {
return mapTo(obj, JSONUtil.ofArray(jsonConfig));
}
/**
* 在需要的时候转换映射对象<br>
* 包装包括:
* <ul>
* <li>array or collection =》 JSONArray</li>
* <li>map =》 JSONObject</li>
* <li>standard property (Double, String, et al) =》 原对象</li>
* <li>其它 =》 尝试包装为JSONObject否则返回{@code null}</li>
* </ul>
*
* @param obj 被映射的对象
* @param json 被映射的到的对象,{@code null}表示自动识别
* @param <T> JSON类型
* @return 映射后的值null表示此值需被忽略
*/
@SuppressWarnings({"ReassignedVariable", "unchecked"})
private <T extends JSON> T mapTo(Object obj, final T json) {
if (null == obj) {
return null;
}
@@ -204,8 +257,15 @@ public class JSONMapper implements Serializable {
}
}
// JSON对象如果与预期结果类型一致则直接返回
if (obj instanceof JSON) {
return (JSON) obj;
if (null != json) {
if (obj.getClass() == json.getClass()) {
return (T) obj;
}
} else {
return (T) obj;
}
}
final Class<?> clazz = obj.getClass();
@@ -226,14 +286,25 @@ public class JSONMapper implements Serializable {
throw new JSONException("No deserializer for type: " + obj.getClass());
}
final JSON result;
try {
return serializer.serialize(obj, new SimpleJSONContext(null, this.jsonConfig));
result = serializer.serialize(obj, new SimpleJSONContext(json, this.jsonConfig));
} catch (final Exception e) {
if (ignoreError) {
return null;
}
throw e;
}
if(null == json || result.getClass() == json.getClass()){
return (T) result;
}
if(ignoreError){
return null;
}
throw new JSONException("JSON type not match, expect: {}, actual: {}",
json.getClass().getName(), result.getClass().getName());
}
/**

View File

@@ -189,7 +189,8 @@ public class TypeAdapterManager {
}
}
throw new JSONException("No serializer for type: " + type);
// 此处返回null错误处理在mapper中
return null;
}
/**

View File

@@ -67,9 +67,19 @@ public class ArrayTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJ
@Override
public Object deserialize(final JSON json, final Type deserializeType) {
final int size = json.size();
final Class<?> componentType = TypeUtil.getClass(deserializeType).getComponentType();
final Object result = Array.newInstance(componentType, size);
return deserialize(json, componentType);
}
/**
* 反序列化
*
* @param json JSON对象
* @param componentType 组件类型
* @return 数组
*/
public Object deserialize(final JSON json, final Class<?> componentType) {
final Object result = Array.newInstance(componentType, json.size());
if (json instanceof JSONObject) {
fill((JSONObject) json, result, componentType);
} else {
@@ -87,10 +97,12 @@ public class ArrayTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJ
*/
private JSON serializeBytes(final byte[] bytes, final JSONContext context) {
final JSONConfig config = context.config();
switch (bytes[0]) {
case '{':
case '[':
return JSONParser.of(new JSONTokener(IoUtil.toStream(bytes)), config).parse();
if(ArrayUtil.isNotEmpty(bytes)){
switch (bytes[0]) {
case '{':
case '[':
return JSONParser.of(new JSONTokener(IoUtil.toStream(bytes)), config).parse();
}
}
// https://github.com/dromara/hutool/issues/2369

View File

@@ -16,6 +16,7 @@
package org.dromara.hutool.json.serializer.impl;
import org.dromara.hutool.core.bean.BeanDesc;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.bean.copier.BeanToMapCopier;
import org.dromara.hutool.core.bean.copier.ValueProviderToBeanCopier;
@@ -25,11 +26,12 @@ import org.dromara.hutool.core.reflect.TypeUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.InternalJSONUtil;
import org.dromara.hutool.json.JSON;
import org.dromara.hutool.json.JSONConfig;
import org.dromara.hutool.json.JSONObject;
import org.dromara.hutool.json.support.JSONObjectValueProvider;
import org.dromara.hutool.json.serializer.JSONContext;
import org.dromara.hutool.json.serializer.MatcherJSONDeserializer;
import org.dromara.hutool.json.serializer.MatcherJSONSerializer;
import org.dromara.hutool.json.support.JSONObjectValueProvider;
import java.lang.reflect.Type;
@@ -49,13 +51,23 @@ public class BeanTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
@Override
public boolean match(final Object bean, final JSONContext context) {
final JSON contextJson = ObjUtil.apply(context, JSONContext::getContextJson);
return BeanUtil.isReadableBean(bean.getClass())
final BeanDesc beanDesc = BeanUtil.getBeanDesc(bean.getClass());
if(beanDesc.isEmpty()){
// 空Bean按照Bean对待
return true;
}
final boolean isTransparent = ObjUtil.defaultIfNull(
ObjUtil.apply(contextJson, JSON::config), JSONConfig::isTransientSupport, true);
return beanDesc.isReadable(isTransparent)
&& (null == contextJson || contextJson instanceof JSONObject);
}
@Override
public boolean match(final JSON json, final Type deserializeType) {
return json instanceof JSONObject && BeanUtil.isWritableBean(TypeUtil.getClass(deserializeType));
return json instanceof JSONObject &&
// 空对象转目标对象不限制目标是否可写
(json.isEmpty() || BeanUtil.isWritableBean(TypeUtil.getClass(deserializeType)));
}
@Override
@@ -72,9 +84,14 @@ public class BeanTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
@Override
public Object deserialize(final JSON json, final Type deserializeType) {
final Object target = ConstructorUtil.newInstanceIfPossible(TypeUtil.getClass(deserializeType));
if(json.isEmpty()){
//issue#3649对于空对象转目标对象直接实例化一个空对象
return target;
}
final Copier<Object> copier = new ValueProviderToBeanCopier<>(
new JSONObjectValueProvider((JSONObject) json),
ConstructorUtil.newInstanceIfPossible(TypeUtil.getClass(deserializeType)),
target,
deserializeType,
InternalJSONUtil.toCopyOptions(json.config())
);

View File

@@ -29,7 +29,6 @@ import org.dromara.hutool.json.serializer.MatcherJSONSerializer;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
/**
* Iterator序列化器将{@link Iterable}或{@link Iterator}转换为JSONArray
@@ -45,7 +44,7 @@ public class IterTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
@Override
public boolean match(final Object bean, final JSONContext context) {
if(bean instanceof MapWrapper){
if (bean instanceof MapWrapper) {
return false;
}
return bean instanceof Iterable || bean instanceof Iterator;
@@ -77,10 +76,21 @@ public class IterTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
@Override
public Object deserialize(final JSON json, final Type deserializeType) {
final Class<?> rawType = TypeUtil.getClass(deserializeType);
final Class<?> collectionClass = TypeUtil.getClass(deserializeType);
final Type elementType = TypeUtil.getTypeArgument(deserializeType);
final Collection<?> result = CollUtil.create(rawType, TypeUtil.getClass(elementType));
return deserialize(json, collectionClass, elementType);
}
/**
* 反序列化
*
* @param json JSON
* @param collectionClass 集合类型
* @param elementType 元素类型
* @return 反序列化后的集合对象
*/
public Object deserialize(final JSON json, final Class<?> collectionClass, final Type elementType) {
final Collection<?> result = CollUtil.create(collectionClass, TypeUtil.getClass(elementType));
if (json instanceof JSONObject) {
fill((JSONObject) json, result, elementType);
@@ -116,9 +126,9 @@ public class IterTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
* @param elementType 元素类型
*/
private void fill(final JSONObject json, final Collection<?> result, final Type elementType) {
for (final Map.Entry<String, JSON> entry : json) {
result.add(entry.getValue().toBean(elementType));
}
json.forEach((key, value)->{
result.add(null == value ? null : value.toBean(elementType));
});
}
/**
@@ -129,8 +139,8 @@ public class IterTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
* @param elementType 元素类型
*/
private void fill(final JSONArray json, final Collection<?> result, final Type elementType) {
for (final JSON element : json) {
result.add(element.toBean(elementType));
}
json.forEach((element)->{
result.add(null == element ? null : element.toBean(elementType));
});
}
}

View File

@@ -73,6 +73,7 @@ public class TemporalTypeAdapter implements MatcherJSONSerializer<TemporalAccess
// 如果上下文为JSONObject转为键值对形式
final JSON contextJson = context.getContextJson();
if (contextJson instanceof JSONObject) {
// 用户只有明确需要转为JSONObject时才进行转换
toJSONObject(bean, contextJson.asJSONObject());
return contextJson;
}
@@ -153,8 +154,9 @@ public class TemporalTypeAdapter implements MatcherJSONSerializer<TemporalAccess
json.set(MINUTE_KEY, localTime.getMinute());
json.set(SECOND_KEY, localTime.getSecond());
json.set(NANO_KEY, localTime.getNano());
} else{
throw new JSONException("Unsupported type: {}", bean.getClass().getName());
}
throw new JSONException("Unsupported type {}.", bean.getClass().getName());
}
/**