mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix code
This commit is contained in:
@@ -16,24 +16,23 @@
|
||||
|
||||
package org.dromara.hutool.json;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.bean.copier.CopyOptions;
|
||||
import org.dromara.hutool.core.codec.binary.HexUtil;
|
||||
import org.dromara.hutool.core.convert.ConvertUtil;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.map.CaseInsensitiveLinkedMap;
|
||||
import org.dromara.hutool.core.map.CaseInsensitiveTreeMap;
|
||||
import org.dromara.hutool.core.math.NumberUtil;
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.text.split.SplitUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.mapper.JSONValueMapper;
|
||||
import org.dromara.hutool.json.serializer.JSONMapper;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* 内部JSON工具类,仅用于JSON内部使用
|
||||
@@ -88,65 +87,6 @@ public final class InternalJSONUtil {
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 值转为String,用于JSON中。规则为:
|
||||
* <ul>
|
||||
* <li>对象如果是数组或Collection,包装为{@link JSONArray}</li>
|
||||
* <li>对象如果是Map,包装为{@link JSONObject}</li>
|
||||
* <li>对象如果是数字,使用{@link NumberUtil#toStr(Number)}转换为字符串</li>
|
||||
* <li>其他情况调用toString并使用双引号包装</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param value 需要转为字符串的对象
|
||||
* @return 字符串
|
||||
* @throws JSONException If the value is or contains an invalid number.
|
||||
*/
|
||||
static String valueToString(final Object value) throws JSONException {
|
||||
if (value == null) {
|
||||
return StrUtil.NULL;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return NumberUtil.toStr((Number) value);
|
||||
} else if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) {
|
||||
return value.toString();
|
||||
} else if (value instanceof Map) {
|
||||
final Map<?, ?> map = (Map<?, ?>) value;
|
||||
return JSONUtil.parseObj(map).toString();
|
||||
} else if (value instanceof Collection) {
|
||||
final Collection<?> coll = (Collection<?>) value;
|
||||
return JSONUtil.parseArray(coll).toString();
|
||||
} else if (ArrayUtil.isArray(value)) {
|
||||
return JSONUtil.parseArray(value).toString();
|
||||
} else {
|
||||
return quote(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Property的键转化为JSON形式<br>
|
||||
* 用于识别类似于:org.dromara.hutool.json这类用点隔开的键<br>
|
||||
* 注意:不允许重复键
|
||||
*
|
||||
* @param jsonObject JSONObject
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public static void propertyPut(final JSONObject jsonObject, final Object key, final Object value) {
|
||||
final String[] path = SplitUtil.splitToArray(ConvertUtil.toStr(key), StrUtil.DOT);
|
||||
final int last = path.length - 1;
|
||||
JSONObject target = jsonObject;
|
||||
for (int i = 0; i < last; i += 1) {
|
||||
final String segment = path[i];
|
||||
JSONObject nextTarget = target.getJSONObject(segment);
|
||||
if (nextTarget == null) {
|
||||
nextTarget = new JSONObject(target.config());
|
||||
target.set(segment, nextTarget);
|
||||
}
|
||||
target = nextTarget;
|
||||
}
|
||||
target.set(path[last], value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认情况下是否忽略null值的策略选择,以下对象不忽略null值,其它对象忽略:
|
||||
*
|
||||
@@ -179,7 +119,7 @@ public final class InternalJSONUtil {
|
||||
.setIgnoreError(config.isIgnoreError())
|
||||
.setIgnoreNullValue(config.isIgnoreNullValue())
|
||||
.setTransientSupport(config.isTransientSupport())
|
||||
.setConverter((targetType, value) -> JSONValueMapper.of(config, null).map(value));
|
||||
.setConverter((targetType, value) -> JSONMapper.of(config, null).map(value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -18,9 +18,10 @@ 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.core.util.ObjUtil;
|
||||
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.JSONNodeBeanCreator;
|
||||
import org.dromara.hutool.json.writer.JSONWriter;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -138,7 +139,7 @@ public interface JSON extends Serializable {
|
||||
* @param value 值
|
||||
*/
|
||||
default void putByPath(final String expression, final Object value) {
|
||||
BeanPath.of(expression).setValue(this, value);
|
||||
BeanPath.of(expression).setBeanCreator(new JSONNodeBeanCreator(config())).setValue(this, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,33 +229,8 @@ public interface JSON extends Serializable {
|
||||
* @param <T> Bean类型
|
||||
* @param type {@link Type}
|
||||
* @return 实体类对象
|
||||
* @since 4.3.2
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default <T> T toBean(final Type type) {
|
||||
if(null == type || Object.class == type){
|
||||
if(this instanceof JSONPrimitive){
|
||||
return (T) ((JSONPrimitive) this).getValue();
|
||||
}
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
final JSONDeserializer<Object> deserializer = TypeAdapterManager.getInstance().getDeserializer(this, type);
|
||||
final boolean ignoreError = ObjUtil.defaultIfNull(config(), JSONConfig::isIgnoreError, false);
|
||||
if(null == deserializer){
|
||||
if(ignoreError){
|
||||
return null;
|
||||
}
|
||||
throw new JSONException("No deserializer for type: " + type);
|
||||
}
|
||||
|
||||
try{
|
||||
return (T) deserializer.deserialize(this, type);
|
||||
} catch (final Exception e){
|
||||
if(ignoreError){
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return JSONMapper.of(config(), null).toBean(this, type);
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ 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.mapper.JSONValueMapper;
|
||||
import org.dromara.hutool.json.serializer.JSONMapper;
|
||||
import org.dromara.hutool.json.writer.JSONWriter;
|
||||
|
||||
import java.util.*;
|
||||
@@ -52,7 +52,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
|
||||
* 配置项
|
||||
*/
|
||||
private final JSONConfig config;
|
||||
private final JSONValueMapper mapper;
|
||||
private final JSONMapper mapper;
|
||||
|
||||
// region ----- Constructors
|
||||
|
||||
@@ -97,7 +97,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
|
||||
public JSONArray(final int initialCapacity, final JSONConfig config) {
|
||||
super(new ArrayList<>(initialCapacity));
|
||||
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
|
||||
this.mapper = JSONValueMapper.of(config, null);
|
||||
this.mapper = JSONMapper.of(config, null);
|
||||
}
|
||||
// endregion
|
||||
|
||||
|
@@ -25,7 +25,7 @@ import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.map.MapWrapper;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.mapper.JSONValueMapper;
|
||||
import org.dromara.hutool.json.serializer.JSONMapper;
|
||||
import org.dromara.hutool.json.writer.JSONWriter;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -53,7 +53,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
|
||||
* 配置项
|
||||
*/
|
||||
private final JSONConfig config;
|
||||
private final JSONValueMapper mapper;
|
||||
private final JSONMapper mapper;
|
||||
|
||||
/**
|
||||
* 构造,初始容量为 {@link #DEFAULT_CAPACITY},KEY有序
|
||||
@@ -81,7 +81,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
|
||||
public JSONObject(final int capacity, final JSONConfig config) {
|
||||
super(InternalJSONUtil.createRawMap(capacity, config));
|
||||
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
|
||||
this.mapper = JSONValueMapper.of(config, null);
|
||||
this.mapper = JSONMapper.of(config, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -23,7 +23,8 @@ import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.core.reflect.TypeReference;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.mapper.JSONValueMapper;
|
||||
import org.dromara.hutool.json.serializer.JSONMapper;
|
||||
import org.dromara.hutool.json.support.JSONStrFormatter;
|
||||
import org.dromara.hutool.json.writer.JSONWriter;
|
||||
import org.dromara.hutool.json.xml.JSONXMLUtil;
|
||||
|
||||
@@ -160,8 +161,8 @@ public class JSONUtil {
|
||||
*/
|
||||
public static JSONArray parseArray(final Object arrayOrCollection, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
if(arrayOrCollection instanceof JSONObject){
|
||||
final JSONValueMapper jsonValueMapper = JSONValueMapper.of(config, predicate);
|
||||
return jsonValueMapper.mapFromJSONObject((JSONObject) arrayOrCollection);
|
||||
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
|
||||
return jsonMapper.mapFromJSONObject((JSONObject) arrayOrCollection);
|
||||
}
|
||||
return (JSONArray) parse(arrayOrCollection, config, predicate);
|
||||
}
|
||||
@@ -214,11 +215,11 @@ public class JSONUtil {
|
||||
* @return JSON(JSONObject or JSONArray)
|
||||
*/
|
||||
public static JSON parse(final Object obj, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
final JSONValueMapper jsonValueMapper = JSONValueMapper.of(config, predicate);
|
||||
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
|
||||
if (obj instanceof CharSequence) {
|
||||
return jsonValueMapper.map((CharSequence) obj);
|
||||
return jsonMapper.map((CharSequence) obj);
|
||||
}
|
||||
return jsonValueMapper.map(obj);
|
||||
return jsonMapper.map(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.mapper;
|
||||
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.json.JSONArray;
|
||||
import org.dromara.hutool.json.JSONConfig;
|
||||
import org.dromara.hutool.json.JSONException;
|
||||
import org.dromara.hutool.json.reader.JSONParser;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 对象和JSONArray映射器,用于转换对象为JSONArray,支持:
|
||||
* <ul>
|
||||
* <li>JSONTokener 转 JSONArray,直接解析</li>
|
||||
* <li>Iterable 转 JSONArray</li>
|
||||
* <li>Iterator 转 JSONArray</li>
|
||||
* <li>数组 转 JSONArray</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
class JSONArrayMapper {
|
||||
/**
|
||||
* 创建ArrayMapper
|
||||
*
|
||||
* @param source 来源对象
|
||||
* @param predicate 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
||||
* @return ObjectMapper
|
||||
*/
|
||||
public static JSONArrayMapper of(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
return new JSONArrayMapper(source, predicate);
|
||||
}
|
||||
|
||||
private final Object source;
|
||||
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param source 来源对象
|
||||
* @param predicate 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
||||
*/
|
||||
public JSONArrayMapper(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将给定对象转换为{@link JSONArray}
|
||||
*
|
||||
* @param jsonArray 目标{@link JSONArray}
|
||||
* @throws JSONException 非数组或集合
|
||||
*/
|
||||
public void mapTo(final JSONArray jsonArray) throws JSONException {
|
||||
final Object source = this.source;
|
||||
if (null == source) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source instanceof byte[]) {
|
||||
final byte[] bytesSource = (byte[]) source;
|
||||
if ('[' == bytesSource[0] && ']' == bytesSource[bytesSource.length - 1]) {
|
||||
mapFromTokener(new JSONTokener(IoUtil.toStream(bytesSource)), jsonArray.config(), jsonArray);
|
||||
} else {
|
||||
// https://github.com/dromara/hutool/issues/2369
|
||||
// 非标准的二进制流,则按照普通数组对待
|
||||
for (final byte b : bytesSource) {
|
||||
jsonArray.set(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new JSONException("Unsupported [{}] to JSONArray", source.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从JSONTokener中读取数据,并添加到JSONArray中
|
||||
*
|
||||
* @param x {@link JSONTokener}
|
||||
* @param jsonArray {@link JSONArray}
|
||||
*/
|
||||
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONArray jsonArray) {
|
||||
JSONParser.of(x, config).setPredicate(this.predicate).parseTo(jsonArray);
|
||||
}
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.mapper;
|
||||
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.json.InternalJSONUtil;
|
||||
import org.dromara.hutool.json.JSONConfig;
|
||||
import org.dromara.hutool.json.JSONException;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
import org.dromara.hutool.json.reader.JSONParser;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 对象和JSONObject映射器,用于转换对象为JSONObject,支持:
|
||||
* <ul>
|
||||
* <li>Map 转 JSONObject,将键值对加入JSON对象</li>
|
||||
* <li>Map.Entry 转 JSONObject</li>
|
||||
* <li>JSONTokener 转 JSONObject,直接解析</li>
|
||||
* <li>ResourceBundle 转 JSONObject</li>
|
||||
* <li>Bean 转 JSONObject,调用其getters方法(getXXX或者isXXX)获得值,加入到JSON对象。例如:如果JavaBean对象中有个方法getName(),值为"张三",获得的键值对为:name: "张三"</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
class JSONObjectMapper {
|
||||
|
||||
/**
|
||||
* 创建ObjectMapper
|
||||
*
|
||||
* @param source 来源对象
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||
* @return ObjectMapper
|
||||
*/
|
||||
public static JSONObjectMapper of(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
return new JSONObjectMapper(source, predicate);
|
||||
}
|
||||
|
||||
private final Object source;
|
||||
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param source 来源对象
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||
*/
|
||||
public JSONObjectMapper(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将给定对象转换为{@link JSONObject}
|
||||
*
|
||||
* @param jsonObject 目标{@link JSONObject}
|
||||
*/
|
||||
public void mapTo(final JSONObject jsonObject) {
|
||||
final Object source = this.source;
|
||||
if (null == source) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source instanceof byte[]) {
|
||||
mapFromTokener(new JSONTokener(IoUtil.toStream((byte[]) source)), jsonObject.config(), jsonObject);
|
||||
} else if (source instanceof ResourceBundle) {
|
||||
// ResourceBundle
|
||||
mapFromResourceBundle((ResourceBundle) source, jsonObject);
|
||||
} else {
|
||||
if (!jsonObject.config().isIgnoreError()) {
|
||||
// 不支持对象类型转换为JSONObject
|
||||
throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass());
|
||||
}
|
||||
}
|
||||
// 如果用户选择跳过异常,则跳过此值转换
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link ResourceBundle}转换
|
||||
*
|
||||
* @param bundle ResourceBundle
|
||||
* @param jsonObject {@link JSONObject}
|
||||
*/
|
||||
private void mapFromResourceBundle(final ResourceBundle bundle, final JSONObject jsonObject) {
|
||||
final Enumeration<String> keys = bundle.getKeys();
|
||||
while (keys.hasMoreElements()) {
|
||||
final String key = keys.nextElement();
|
||||
if (key != null) {
|
||||
InternalJSONUtil.propertyPut(jsonObject, key, bundle.getString(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link JSONTokener}转换
|
||||
*
|
||||
* @param x JSONTokener
|
||||
* @param config JSON配置
|
||||
* @param jsonObject {@link JSONObject}
|
||||
*/
|
||||
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONObject jsonObject) {
|
||||
JSONParser.of(x, config).setPredicate(this.predicate).parseTo(jsonObject);
|
||||
}
|
||||
}
|
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.mapper;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.lang.Opt;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.core.map.MapWrapper;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.*;
|
||||
import org.dromara.hutool.json.reader.JSONParser;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
import org.dromara.hutool.json.serializer.JSONSerializer;
|
||||
import org.dromara.hutool.json.serializer.SimpleJSONContext;
|
||||
import org.dromara.hutool.json.serializer.TypeAdapterManager;
|
||||
import org.dromara.hutool.json.xml.JSONXMLParser;
|
||||
import org.dromara.hutool.json.xml.ParseConfig;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 对象和JSON值映射器,用于转换对象为JSON对象中的值<br>
|
||||
* 有效的JSON值包括:
|
||||
* <ul>
|
||||
* <li>JSONObject</li>
|
||||
* <li>JSONArray</li>
|
||||
* <li>String</li>
|
||||
* <li>数字(int、long等)</li>
|
||||
* <li>Boolean值,如true或false</li>
|
||||
* <li>{@code null}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JSONValueMapper implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6714488573738940582L;
|
||||
|
||||
/**
|
||||
* 创建ObjectMapper
|
||||
*
|
||||
* @param jsonConfig 来源对象
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||
* @return ObjectMapper
|
||||
*/
|
||||
public static JSONValueMapper of(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
return new JSONValueMapper(jsonConfig, predicate);
|
||||
}
|
||||
|
||||
private final JSONConfig jsonConfig;
|
||||
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param jsonConfig JSON配置
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||
*/
|
||||
public JSONValueMapper(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
this.jsonConfig = ObjUtil.defaultIfNull(jsonConfig, JSONConfig::of);
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSONObject转换为JSONArray
|
||||
*
|
||||
* @param jsonObject JSONObject
|
||||
* @return JSONArray
|
||||
*/
|
||||
public JSONArray mapFromJSONObject(final JSONObject jsonObject){
|
||||
final JSONArray array = new JSONArray(jsonConfig);
|
||||
JSONArrayMapper.of(jsonObject, this.predicate)
|
||||
.mapTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析JSON字符串或XML字符串为JSON结构
|
||||
*
|
||||
* @param source JSON字符串或XML字符串
|
||||
* @return JSON对象
|
||||
*/
|
||||
public JSON map(final CharSequence source) {
|
||||
final String jsonStr = StrUtil.trim(source);
|
||||
if (StrUtil.startWith(jsonStr, '<')) {
|
||||
// 可能为XML
|
||||
final JSONObject jsonObject = new JSONObject(jsonConfig);
|
||||
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
return mapFromTokener(new JSONTokener(source));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在需要的时候转换映射对象<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>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 被映射的对象
|
||||
* @return 映射后的值,null表示此值需被忽略
|
||||
*/
|
||||
public JSON map(Object obj) {
|
||||
if (null == obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (obj instanceof Optional) {
|
||||
obj = ((Optional<?>) obj).orElse(null);
|
||||
} else if (obj instanceof Opt) {
|
||||
obj = ((Opt<?>) obj).getOrNull();
|
||||
}
|
||||
|
||||
if (obj instanceof JSON) {
|
||||
return (JSON) obj;
|
||||
}
|
||||
|
||||
// 读取JSON流
|
||||
if(obj instanceof JSONTokener){
|
||||
return mapFromTokener((JSONTokener) obj);
|
||||
}else if(obj instanceof JSONParser){
|
||||
return ((JSONParser)obj).parse();
|
||||
} else if (obj instanceof Reader) {
|
||||
return mapFromTokener(new JSONTokener((Reader) obj));
|
||||
} else if (obj instanceof InputStream) {
|
||||
return mapFromTokener(new JSONTokener((InputStream) obj));
|
||||
}
|
||||
|
||||
// 自定义序列化
|
||||
final JSONSerializer<Object> serializer = TypeAdapterManager.getInstance()
|
||||
.getSerializer(obj, obj.getClass());
|
||||
if (null != serializer) {
|
||||
return serializer.serialize(obj, new SimpleJSONContext(null, this.jsonConfig));
|
||||
}
|
||||
|
||||
// 原始类型
|
||||
if (JSONPrimitive.isTypeForJSONPrimitive(obj)) {
|
||||
return new JSONPrimitive(obj, jsonConfig);
|
||||
}
|
||||
|
||||
// 特定对象转换
|
||||
try {
|
||||
// JSONArray
|
||||
if (// MapWrapper实现了Iterable会被当作JSONArray,此处做修正
|
||||
!(obj instanceof MapWrapper) &&
|
||||
(obj instanceof Iterable || ArrayUtil.isArray(obj))) {
|
||||
final JSONArray jsonArray = new JSONArray(jsonConfig);
|
||||
JSONArrayMapper.of(obj, predicate).mapTo(jsonArray);
|
||||
return jsonArray;
|
||||
}
|
||||
|
||||
// 默认按照JSONObject对待
|
||||
final JSONObject jsonObject = new JSONObject(jsonConfig);
|
||||
JSONObjectMapper.of(obj, predicate).mapTo(jsonObject);
|
||||
return jsonObject;
|
||||
} catch (final Exception exception) {
|
||||
if (jsonConfig.isIgnoreError()) {
|
||||
return null;
|
||||
}
|
||||
throw exception instanceof JSONException ? (JSONException) exception : new JSONException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link JSONTokener} 中读取JSON字符串,并转换为JSON
|
||||
*
|
||||
* @param tokener {@link JSONTokener}
|
||||
* @return JSON
|
||||
*/
|
||||
private JSON mapFromTokener(final JSONTokener tokener) {
|
||||
return JSONParser.of(tokener, jsonConfig).setPredicate(this.predicate).parse();
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bean和JSON之间的映射封装,包括:
|
||||
* <ul>
|
||||
* <li>JSONObjectMapper: 转换对象为JSONObject</li>
|
||||
* <li>JSONArrayMapper: 转换对象为JSONArray</li>
|
||||
* <li>JSONValueMapper: 转换对象为JSON值</li>
|
||||
* </ul>
|
||||
*/
|
||||
package org.dromara.hutool.json.mapper;
|
@@ -26,9 +26,9 @@
|
||||
* JSON封装主要包括JSON表示和JSON转换:
|
||||
*
|
||||
* <pre>{@code
|
||||
* <--JSONConverter-- <---JSONParser----
|
||||
* Java对象 <=================> JSON对象 <=================> JSON字符串
|
||||
* ------mapper-----> ---JSONWriter---->
|
||||
* <-----JSONMapper----- <---JSONParser----
|
||||
* Java对象 <====================> JSON对象 <=================> JSON字符串
|
||||
* -----JSONMapper-----> ---JSONWriter---->
|
||||
* }</pre>
|
||||
*
|
||||
* 当然,为了高效转换,如果没有自定义需求,Java对象可以不通过JSON对象与JSON字符串转换:
|
||||
|
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.serializer;
|
||||
|
||||
import org.dromara.hutool.core.lang.Opt;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.*;
|
||||
import org.dromara.hutool.json.reader.JSONParser;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
import org.dromara.hutool.json.xml.JSONXMLParser;
|
||||
import org.dromara.hutool.json.xml.ParseConfig;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 对象和JSON值映射器,用于Java对象和JSON对象互转<br>
|
||||
* <ul>
|
||||
* <li>Java对象转JSON:{@link #map(Object)}</li>
|
||||
* <li>JSON转Java对象:{@link #toBean(JSON, Type)}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 转换依赖于{@link JSONSerializer}和{@link JSONDeserializer}的实现,通过{@link TypeAdapterManager}统一管理<br>
|
||||
* 序列化和反序列化定义于两个作用域,首先查找本类中定义的,如果没有,使用{@link TypeAdapterManager#getInstance()} 查找全局定义的。
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JSONMapper implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6714488573738940582L;
|
||||
|
||||
/**
|
||||
* 创建ObjectMapper
|
||||
*
|
||||
* @param jsonConfig 来源对象
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||
* @return ObjectMapper
|
||||
*/
|
||||
public static JSONMapper of(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
return new JSONMapper(jsonConfig, predicate);
|
||||
}
|
||||
|
||||
private final JSONConfig jsonConfig;
|
||||
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||
private TypeAdapterManager typeAdapterManager;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param jsonConfig JSON配置
|
||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||
*/
|
||||
public JSONMapper(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
this.jsonConfig = ObjUtil.defaultIfNull(jsonConfig, JSONConfig::of);
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自定义类型转换器,用于将自定义类型转换为JSONObject
|
||||
*
|
||||
* @return 类型转换器管理器
|
||||
*/
|
||||
public TypeAdapterManager getTypeAdapterManager() {
|
||||
return this.typeAdapterManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自定义类型转换器,用于将自定义类型转换为JSONObject
|
||||
*
|
||||
* @param typeAdapterManager 类型转换器管理器
|
||||
* @return this
|
||||
*/
|
||||
public JSONMapper setTypeAdapterManager(final TypeAdapterManager typeAdapterManager) {
|
||||
this.typeAdapterManager = typeAdapterManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为实体类对象
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param json JSON
|
||||
* @param type {@link Type}
|
||||
* @return 实体类对象
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T toBean(final JSON json, final Type type) {
|
||||
if (null == type || Object.class == type) {
|
||||
if (json instanceof JSONPrimitive) {
|
||||
return (T) ((JSONPrimitive) json).getValue();
|
||||
}
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
JSONDeserializer<Object> deserializer = null;
|
||||
// 自定义反序列化
|
||||
if (null != this.typeAdapterManager) {
|
||||
deserializer = this.typeAdapterManager.getDeserializer(json, type);
|
||||
}
|
||||
// 全局自定义反序列化
|
||||
if (null == deserializer) {
|
||||
deserializer = TypeAdapterManager.getInstance().getDeserializer(json, type);
|
||||
}
|
||||
final boolean ignoreError = ObjUtil.defaultIfNull(this.jsonConfig, JSONConfig::isIgnoreError, false);
|
||||
if (null == deserializer) {
|
||||
if (ignoreError) {
|
||||
return null;
|
||||
}
|
||||
throw new JSONException("No deserializer for type: " + type);
|
||||
}
|
||||
|
||||
try {
|
||||
return (T) deserializer.deserialize(json, type);
|
||||
} catch (final Exception e) {
|
||||
if (ignoreError) {
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSONObject转换为JSONArrayM<br>
|
||||
* 在普通的Serializer中,JSONObject会被直接返回,如果想转为JSONArray,
|
||||
*
|
||||
* @param jsonObject JSONObject
|
||||
* @return JSONArray
|
||||
*/
|
||||
public JSONArray mapFromJSONObject(final JSONObject jsonObject) {
|
||||
final JSONArray array = JSONUtil.ofArray(jsonConfig);
|
||||
for (final Map.Entry<String, JSON> entry : jsonObject) {
|
||||
array.add(entry.getValue());
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析JSON字符串或XML字符串为JSON结构<br>
|
||||
* 在普通的Serializer中,字符串会被作为普通字符串转为{@link JSONPrimitive},此处做区分
|
||||
*
|
||||
* @param source JSON字符串或XML字符串
|
||||
* @return JSON对象
|
||||
*/
|
||||
public JSON map(final CharSequence source) {
|
||||
final String jsonStr = StrUtil.trim(source);
|
||||
if (StrUtil.startWith(jsonStr, '<')) {
|
||||
// 可能为XML
|
||||
final JSONObject jsonObject = JSONUtil.ofObj(jsonConfig);
|
||||
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
return mapFromTokener(new JSONTokener(source));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在需要的时候转换映射对象<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>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 被映射的对象
|
||||
* @return 映射后的值,null表示此值需被忽略
|
||||
*/
|
||||
public JSON map(Object obj) {
|
||||
if (null == obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (obj instanceof Optional) {
|
||||
obj = ((Optional<?>) obj).orElse(null);
|
||||
if (null == obj) {
|
||||
return null;
|
||||
}
|
||||
} else if (obj instanceof Opt) {
|
||||
obj = ((Opt<?>) obj).getOrNull();
|
||||
if (null == obj) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj instanceof JSON) {
|
||||
return (JSON) obj;
|
||||
}
|
||||
|
||||
final Class<?> clazz = obj.getClass();
|
||||
JSONSerializer<Object> serializer = null;
|
||||
// 自定义序列化
|
||||
if (null != this.typeAdapterManager) {
|
||||
serializer = this.typeAdapterManager.getSerializer(obj, clazz);
|
||||
}
|
||||
// 全局自定义序列化
|
||||
if (null == serializer) {
|
||||
serializer = TypeAdapterManager.getInstance().getSerializer(obj, clazz);
|
||||
}
|
||||
final boolean ignoreError = ObjUtil.defaultIfNull(this.jsonConfig, JSONConfig::isIgnoreError, false);
|
||||
if (null == serializer) {
|
||||
if (ignoreError) {
|
||||
return null;
|
||||
}
|
||||
throw new JSONException("No deserializer for type: " + obj.getClass());
|
||||
}
|
||||
|
||||
try {
|
||||
return serializer.serialize(obj, new SimpleJSONContext(null, this.jsonConfig));
|
||||
} catch (final Exception e) {
|
||||
if (ignoreError) {
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link JSONTokener} 中读取JSON字符串,并转换为JSON
|
||||
*
|
||||
* @param tokener {@link JSONTokener}
|
||||
* @return JSON
|
||||
*/
|
||||
private JSON mapFromTokener(final JSONTokener tokener) {
|
||||
return JSONParser.of(tokener, jsonConfig).setPredicate(this.predicate).parse();
|
||||
}
|
||||
}
|
@@ -284,6 +284,8 @@ public class TypeAdapterManager {
|
||||
private static TypeAdapterManager registerDefault(final TypeAdapterManager manager) {
|
||||
|
||||
// 自定义序列化器
|
||||
manager.register(ResourceBundleSerializer.INSTANCE);
|
||||
manager.register(TokenerSerializer.INSTANCE);
|
||||
|
||||
// 自定义反序列化器
|
||||
manager.register(KBeanDeserializer.INSTANCE);
|
||||
|
@@ -18,10 +18,11 @@ package org.dromara.hutool.json.serializer.impl;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.reflect.TypeUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONArray;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
import org.dromara.hutool.json.*;
|
||||
import org.dromara.hutool.json.reader.JSONParser;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
import org.dromara.hutool.json.serializer.JSONContext;
|
||||
import org.dromara.hutool.json.serializer.MatcherJSONDeserializer;
|
||||
import org.dromara.hutool.json.serializer.MatcherJSONSerializer;
|
||||
@@ -58,6 +59,9 @@ public class ArrayTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJ
|
||||
|
||||
@Override
|
||||
public JSON serialize(final Object bean, final JSONContext context) {
|
||||
if (bean instanceof byte[]) {
|
||||
return serializeBytes((byte[]) bean, context);
|
||||
}
|
||||
return IterTypeAdapter.INSTANCE.serialize(new ArrayIter<>(bean), context);
|
||||
}
|
||||
|
||||
@@ -74,6 +78,36 @@ public class ArrayTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJ
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化二进制流为JSON
|
||||
*
|
||||
* @param bytes 二进制流
|
||||
* @param context JSON上下文
|
||||
* @return JSONArray
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
// https://github.com/dromara/hutool/issues/2369
|
||||
// 非标准的二进制流,则按照普通数组对待
|
||||
final JSONArray result;
|
||||
final JSON contextJson = context.getContextJson();
|
||||
if (contextJson instanceof JSONArray) {
|
||||
result = (JSONArray) contextJson;
|
||||
} else {
|
||||
result = JSONUtil.ofArray(config);
|
||||
}
|
||||
for (final byte b : bytes) {
|
||||
result.set(b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSONObject填充到数组
|
||||
*
|
||||
|
@@ -26,7 +26,7 @@ import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.InternalJSONUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
import org.dromara.hutool.json.convert.JSONObjectValueProvider;
|
||||
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;
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package org.dromara.hutool.json.serializer.impl;
|
||||
|
||||
import org.dromara.hutool.core.collection.CollUtil;
|
||||
import org.dromara.hutool.core.map.MapWrapper;
|
||||
import org.dromara.hutool.core.reflect.TypeUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
@@ -46,6 +47,9 @@ public class IterTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJS
|
||||
|
||||
@Override
|
||||
public boolean match(final Object bean, final JSONContext context) {
|
||||
if(bean instanceof MapWrapper){
|
||||
return false;
|
||||
}
|
||||
return bean instanceof Iterable || bean instanceof Iterator;
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import org.dromara.hutool.core.reflect.kotlin.KClassUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONGetter;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
import org.dromara.hutool.json.convert.JSONObjectValueProvider;
|
||||
import org.dromara.hutool.json.support.JSONObjectValueProvider;
|
||||
import org.dromara.hutool.json.serializer.MatcherJSONDeserializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
@@ -20,7 +20,7 @@ import org.dromara.hutool.core.bean.RecordUtil;
|
||||
import org.dromara.hutool.core.reflect.TypeUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
import org.dromara.hutool.json.convert.JSONObjectValueProvider;
|
||||
import org.dromara.hutool.json.support.JSONObjectValueProvider;
|
||||
import org.dromara.hutool.json.serializer.MatcherJSONDeserializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.serializer.impl;
|
||||
|
||||
import org.dromara.hutool.core.convert.ConvertUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.text.split.SplitUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
import org.dromara.hutool.json.JSONUtil;
|
||||
import org.dromara.hutool.json.serializer.JSONContext;
|
||||
import org.dromara.hutool.json.serializer.MatcherJSONSerializer;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* {@link ResourceBundle}序列化器
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class ResourceBundleSerializer implements MatcherJSONSerializer<ResourceBundle> {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static final ResourceBundleSerializer INSTANCE = new ResourceBundleSerializer();
|
||||
|
||||
@Override
|
||||
public boolean match(final Object bean, final JSONContext context) {
|
||||
return bean instanceof ResourceBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSON serialize(final ResourceBundle bean, final JSONContext context) {
|
||||
final JSONObject result;
|
||||
|
||||
final JSON json = context.getContextJson();
|
||||
if (json instanceof JSONObject) {
|
||||
result = (JSONObject) json;
|
||||
} else {
|
||||
result = JSONUtil.ofObj(context.config());
|
||||
}
|
||||
|
||||
mapFromResourceBundle(bean, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link ResourceBundle}转换
|
||||
*
|
||||
* @param bundle ResourceBundle
|
||||
* @param jsonObject {@link JSONObject}
|
||||
*/
|
||||
private void mapFromResourceBundle(final ResourceBundle bundle, final JSONObject jsonObject) {
|
||||
final Enumeration<String> keys = bundle.getKeys();
|
||||
while (keys.hasMoreElements()) {
|
||||
final String key = keys.nextElement();
|
||||
if (key != null) {
|
||||
propertyPut(jsonObject, key, bundle.getString(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Property的键转化为JSON形式<br>
|
||||
* 用于识别类似于:org.dromara.hutool.json这类用点隔开的键<br>
|
||||
* 注意:不允许重复键
|
||||
*
|
||||
* @param jsonObject JSONObject
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
private static void propertyPut(final JSONObject jsonObject, final Object key, final Object value) {
|
||||
final String[] path = SplitUtil.splitToArray(ConvertUtil.toStr(key), StrUtil.DOT);
|
||||
final int last = path.length - 1;
|
||||
JSONObject target = jsonObject;
|
||||
for (int i = 0; i < last; i += 1) {
|
||||
final String segment = path[i];
|
||||
JSONObject nextTarget = target.getJSONObject(segment);
|
||||
if (nextTarget == null) {
|
||||
nextTarget = JSONUtil.ofObj(target.config());
|
||||
target.set(segment, nextTarget);
|
||||
}
|
||||
target = nextTarget;
|
||||
}
|
||||
target.set(path[last], value);
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.serializer.impl;
|
||||
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONConfig;
|
||||
import org.dromara.hutool.json.reader.JSONParser;
|
||||
import org.dromara.hutool.json.reader.JSONTokener;
|
||||
import org.dromara.hutool.json.serializer.JSONContext;
|
||||
import org.dromara.hutool.json.serializer.MatcherJSONSerializer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* JSONTokener及其读取流的JSON序列化器实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class TokenerSerializer implements MatcherJSONSerializer<Object> {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static final TokenerSerializer INSTANCE = new TokenerSerializer();
|
||||
|
||||
@Override
|
||||
public boolean match(final Object bean, final JSONContext context) {
|
||||
return bean instanceof Reader
|
||||
|| bean instanceof InputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSON serialize(final Object bean, final JSONContext context) {
|
||||
// 读取JSON流
|
||||
if (bean instanceof JSONTokener) {
|
||||
return mapFromTokener((JSONTokener) bean, context.config());
|
||||
} else if (bean instanceof JSONParser) {
|
||||
return ((JSONParser) bean).parse();
|
||||
} else if (bean instanceof Reader) {
|
||||
return mapFromTokener(new JSONTokener((Reader) bean), context.config());
|
||||
} else if (bean instanceof InputStream) {
|
||||
return mapFromTokener(new JSONTokener((InputStream) bean), context.config());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported source: " + bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link JSONTokener} 中读取JSON字符串,并转换为JSON
|
||||
*
|
||||
* @param tokener {@link JSONTokener}
|
||||
* @return JSON
|
||||
*/
|
||||
private JSON mapFromTokener(final JSONTokener tokener, final JSONConfig config) {
|
||||
return JSONParser.of(tokener, config).setPredicate(null).parse();
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.support;
|
||||
|
||||
import org.dromara.hutool.core.bean.path.BeanPath;
|
||||
import org.dromara.hutool.core.bean.path.NodeBeanCreator;
|
||||
import org.dromara.hutool.core.bean.path.node.NameNode;
|
||||
import org.dromara.hutool.core.bean.path.node.Node;
|
||||
import org.dromara.hutool.json.JSONConfig;
|
||||
import org.dromara.hutool.json.JSONUtil;
|
||||
|
||||
/**
|
||||
* JSON节点Bean创建器
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JSONNodeBeanCreator implements NodeBeanCreator {
|
||||
|
||||
private final JSONConfig config;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config JSON配置
|
||||
*/
|
||||
public JSONNodeBeanCreator(final JSONConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object create(final Object parent, final BeanPath beanPath) {
|
||||
final BeanPath next = beanPath.next();
|
||||
if (null != next) {
|
||||
final Node node = next.getNode();
|
||||
if (node instanceof NameNode) {
|
||||
final NameNode nameNode = (NameNode) node;
|
||||
if (nameNode.isNumber()) {
|
||||
return JSONUtil.ofArray(config);
|
||||
}
|
||||
return JSONUtil.ofObj(config);
|
||||
}
|
||||
}
|
||||
return JSONUtil.ofObj(config);
|
||||
}
|
||||
}
|
@@ -14,16 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json.convert;
|
||||
package org.dromara.hutool.json.support;
|
||||
|
||||
import org.dromara.hutool.core.bean.copier.ValueProvider;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONObject;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* JSONObject值提供者,用于将JSONObject中的值注入Bean
|
||||
* JSONObject值提供者,用于将JSONObject中的值注入Bean<br>
|
||||
* 兼容下划线模式的JSON转换为驼峰模式
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
@@ -42,16 +44,19 @@ public class JSONObjectValueProvider implements ValueProvider<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object value(final String key, final Type valueType) {
|
||||
final JSON value = jsonObject.get(key);
|
||||
if (null == value) {
|
||||
return null;
|
||||
}
|
||||
return value.toBean(valueType);
|
||||
public boolean containsKey(final String key) {
|
||||
return jsonObject.containsKey(key) || jsonObject.containsKey(StrUtil.toUnderlineCase(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(final String key) {
|
||||
return jsonObject.containsKey(key);
|
||||
public Object value(final String key, final Type valueType) {
|
||||
JSON value = jsonObject.get(key);
|
||||
if (null == value) {
|
||||
value = jsonObject.get(StrUtil.toUnderlineCase(key));
|
||||
if(null == value){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return value.toBean(valueType);
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.json;
|
||||
package org.dromara.hutool.json.support;
|
||||
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* JSON中对象、值类型转换封装
|
||||
* JSON的支持类,如用于转换和BeanPath操作的对象,还有用于格式化的对象等
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
package org.dromara.hutool.json.convert;
|
||||
package org.dromara.hutool.json.support;
|
Reference in New Issue
Block a user