change line sep

This commit is contained in:
Looly
2021-01-20 17:10:45 +08:00
parent 720d24566b
commit 4e38adb32d
1450 changed files with 183940 additions and 183940 deletions

View File

@@ -1,266 +1,266 @@
package cn.hutool.json;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
/**
* 内部JSON工具类仅用于JSON内部使用
*
* @author Looly
*/
final class InternalJSONUtil {
private InternalJSONUtil() {
}
/**
* 写入值到Writer
*
* @param writer Writer
* @param value 值
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
* @param indent 缩进空格数
* @param config 配置项
* @return Writer
* @throws JSONException JSON异常
* @throws IOException IO异常
*/
protected static Writer writeValue(Writer writer, Object value, int indentFactor, int indent, JSONConfig config) throws JSONException, IOException {
if (value == null || value instanceof JSONNull) {
writer.write(JSONNull.NULL.toString());
} else if (value instanceof JSON) {
((JSON) value).write(writer, indentFactor, indent);
} else if (value instanceof Map) {
new JSONObject(value).write(writer, indentFactor, indent);
} else if (value instanceof Iterable || value instanceof Iterator || value.getClass().isArray()) {
new JSONArray(value).write(writer, indentFactor, indent);
} else if (value instanceof Number) {
writer.write(NumberUtil.toStr((Number) value));
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
final String format = (null == config) ? null : config.getDateFormat();
writer.write(formatDate(value, format));
} else if (value instanceof Boolean) {
writer.write(value.toString());
} else if (value instanceof JSONString) {
String valueStr;
try {
valueStr = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
writer.write(valueStr != null ? valueStr : JSONUtil.quote(value.toString()));
} else {
JSONUtil.quote(value.toString(), writer);
}
return writer;
}
/**
* 缩进,使用空格符
*
* @param writer writer
* @param indent 缩进空格数
* @throws IOException IO异常
*/
protected static void indent(Writer writer, int indent) throws IOException {
for (int i = 0; i < indent; i += 1) {
writer.write(CharUtil.SPACE);
}
}
/**
* 如果对象是Number 且是 NaN or infinite将抛出异常
*
* @param obj 被检查的对象
* @throws JSONException If o is a non-finite number.
*/
protected static void testValidity(Object obj) throws JSONException {
if (false == ObjectUtil.isValidIfNumber(obj)) {
throw new JSONException("JSON does not allow non-finite numbers.");
}
}
/**
* 值转为String用于JSON中。 If the object has an value.toJSONString() method, then that method will be used to produce the JSON text. <br>
* The method is required to produce a strictly conforming text. <br>
* If the object does not contain a toJSONString method (which is the most common case), then a text will be produced by other means. <br>
* If the value is an array or Collection, then a JSONArray will be made from it and its toJSONString method will be called. <br>
* If the value is a MAP, then a JSONObject will be made from it and its toJSONString method will be called. <br>
* Otherwise, the value's toString method will be called, and the result will be quoted.<br>
*
* @param value 需要转为字符串的对象
* @return 字符串
* @throws JSONException If the value is or contains an invalid number.
*/
protected static String valueToString(Object value) throws JSONException {
if (value == null || value instanceof JSONNull) {
return "null";
}
if (value instanceof JSONString) {
try {
return ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
} else 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) {
Map<?, ?> map = (Map<?, ?>) value;
return new JSONObject(map).toString();
} else if (value instanceof Collection) {
Collection<?> coll = (Collection<?>) value;
return new JSONArray(coll).toString();
} else if (value.getClass().isArray()) {
return new JSONArray(value).toString();
} else {
return JSONUtil.quote(value.toString());
}
}
/**
* 尝试转换字符串为number, boolean, or null无法转换返回String
*
* @param string A String.
* @return A simple JSON value.
*/
protected static Object stringToValue(String string) {
// null处理
if (null == string || "null".equalsIgnoreCase(string)) {
return JSONNull.NULL;
}
// boolean处理
if (0 == string.length()) {
return StrUtil.EMPTY;
}
if ("true".equalsIgnoreCase(string)) {
return Boolean.TRUE;
}
if ("false".equalsIgnoreCase(string)) {
return Boolean.FALSE;
}
// Number处理
char b = string.charAt(0);
if ((b >= '0' && b <= '9') || b == '-') {
try {
if (StrUtil.containsAnyIgnoreCase(string, ".", "e")) {
// pr#192@GiteeDouble会出现小数精度丢失问题此处使用BigDecimal
//double d = Double.parseDouble(string);
//if (false == Double.isInfinite(d) && false == Double.isNaN(d)) {
// return d;
//}
return new BigDecimal(string);
} else {
final long myLong = Long.parseLong(string);
if (string.equals(Long.toString(myLong))) {
if (myLong == (int) myLong) {
return (int) myLong;
} else {
return myLong;
}
}
}
} catch (Exception ignore) {
}
}
// 其它情况返回原String值下
return string;
}
/**
* 将Property的键转化为JSON形式<br>
* 用于识别类似于com.luxiaolei.package.hutool这类用点隔开的键
*
* @param jsonObject JSONObject
* @param key 键
* @param value 值
* @return JSONObject
*/
protected static JSONObject propertyPut(JSONObject jsonObject, Object key, Object value) {
final String[] path = StrUtil.split(Convert.toStr(key), StrUtil.DOT);
int last = path.length - 1;
JSONObject target = jsonObject;
for (int i = 0; i < last; i += 1) {
String segment = path[i];
JSONObject nextTarget = target.getJSONObject(segment);
if (nextTarget == null) {
nextTarget = new JSONObject(target.getConfig());
target.set(segment, nextTarget);
}
target = nextTarget;
}
target.set(path[last], value);
return jsonObject;
}
/**
* 默认情况下是否忽略null值的策略选择以下对象不忽略null值其它对象忽略
*
* <pre>
* 1. CharSequence
* 2. JSONTokener
* 3. Map
* </pre>
*
* @param obj 需要检查的对象
* @return 是否忽略null值
* @since 4.3.1
*/
protected static boolean defaultIgnoreNullValue(Object obj) {
return (false == (obj instanceof CharSequence))//
&& (false == (obj instanceof JSONTokener))//
&& (false == (obj instanceof Map));
}
/**
* 按照给定格式格式化日期,格式为空时返回时间戳字符串
*
* @param dateObj Date或者Calendar对象
* @param format 格式
* @return 日期字符串
*/
private static String formatDate(Object dateObj, String format) {
if (StrUtil.isNotBlank(format)) {
final String dateStr;
if(dateObj instanceof TemporalAccessor){
dateStr = TemporalAccessorUtil.format((TemporalAccessor) dateObj, format);
} else{
dateStr = DateUtil.format(Convert.toDate(dateObj), format);
}
//用户定义了日期格式
return JSONUtil.quote(dateStr);
}
//默认使用时间戳
long timeMillis;
if (dateObj instanceof TemporalAccessor) {
timeMillis = TemporalAccessorUtil.toEpochMilli((TemporalAccessor) dateObj);
} else if (dateObj instanceof Date) {
timeMillis = ((Date) dateObj).getTime();
} else if (dateObj instanceof Calendar) {
timeMillis = ((Calendar) dateObj).getTimeInMillis();
} else {
throw new UnsupportedOperationException("Unsupported Date type: " + dateObj.getClass());
}
return String.valueOf(timeMillis);
}
}
package cn.hutool.json;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
/**
* 内部JSON工具类仅用于JSON内部使用
*
* @author Looly
*/
final class InternalJSONUtil {
private InternalJSONUtil() {
}
/**
* 写入值到Writer
*
* @param writer Writer
* @param value 值
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
* @param indent 缩进空格数
* @param config 配置项
* @return Writer
* @throws JSONException JSON异常
* @throws IOException IO异常
*/
protected static Writer writeValue(Writer writer, Object value, int indentFactor, int indent, JSONConfig config) throws JSONException, IOException {
if (value == null || value instanceof JSONNull) {
writer.write(JSONNull.NULL.toString());
} else if (value instanceof JSON) {
((JSON) value).write(writer, indentFactor, indent);
} else if (value instanceof Map) {
new JSONObject(value).write(writer, indentFactor, indent);
} else if (value instanceof Iterable || value instanceof Iterator || value.getClass().isArray()) {
new JSONArray(value).write(writer, indentFactor, indent);
} else if (value instanceof Number) {
writer.write(NumberUtil.toStr((Number) value));
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
final String format = (null == config) ? null : config.getDateFormat();
writer.write(formatDate(value, format));
} else if (value instanceof Boolean) {
writer.write(value.toString());
} else if (value instanceof JSONString) {
String valueStr;
try {
valueStr = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
writer.write(valueStr != null ? valueStr : JSONUtil.quote(value.toString()));
} else {
JSONUtil.quote(value.toString(), writer);
}
return writer;
}
/**
* 缩进,使用空格符
*
* @param writer writer
* @param indent 缩进空格数
* @throws IOException IO异常
*/
protected static void indent(Writer writer, int indent) throws IOException {
for (int i = 0; i < indent; i += 1) {
writer.write(CharUtil.SPACE);
}
}
/**
* 如果对象是Number 且是 NaN or infinite将抛出异常
*
* @param obj 被检查的对象
* @throws JSONException If o is a non-finite number.
*/
protected static void testValidity(Object obj) throws JSONException {
if (false == ObjectUtil.isValidIfNumber(obj)) {
throw new JSONException("JSON does not allow non-finite numbers.");
}
}
/**
* 值转为String用于JSON中。 If the object has an value.toJSONString() method, then that method will be used to produce the JSON text. <br>
* The method is required to produce a strictly conforming text. <br>
* If the object does not contain a toJSONString method (which is the most common case), then a text will be produced by other means. <br>
* If the value is an array or Collection, then a JSONArray will be made from it and its toJSONString method will be called. <br>
* If the value is a MAP, then a JSONObject will be made from it and its toJSONString method will be called. <br>
* Otherwise, the value's toString method will be called, and the result will be quoted.<br>
*
* @param value 需要转为字符串的对象
* @return 字符串
* @throws JSONException If the value is or contains an invalid number.
*/
protected static String valueToString(Object value) throws JSONException {
if (value == null || value instanceof JSONNull) {
return "null";
}
if (value instanceof JSONString) {
try {
return ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
} else 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) {
Map<?, ?> map = (Map<?, ?>) value;
return new JSONObject(map).toString();
} else if (value instanceof Collection) {
Collection<?> coll = (Collection<?>) value;
return new JSONArray(coll).toString();
} else if (value.getClass().isArray()) {
return new JSONArray(value).toString();
} else {
return JSONUtil.quote(value.toString());
}
}
/**
* 尝试转换字符串为number, boolean, or null无法转换返回String
*
* @param string A String.
* @return A simple JSON value.
*/
protected static Object stringToValue(String string) {
// null处理
if (null == string || "null".equalsIgnoreCase(string)) {
return JSONNull.NULL;
}
// boolean处理
if (0 == string.length()) {
return StrUtil.EMPTY;
}
if ("true".equalsIgnoreCase(string)) {
return Boolean.TRUE;
}
if ("false".equalsIgnoreCase(string)) {
return Boolean.FALSE;
}
// Number处理
char b = string.charAt(0);
if ((b >= '0' && b <= '9') || b == '-') {
try {
if (StrUtil.containsAnyIgnoreCase(string, ".", "e")) {
// pr#192@GiteeDouble会出现小数精度丢失问题此处使用BigDecimal
//double d = Double.parseDouble(string);
//if (false == Double.isInfinite(d) && false == Double.isNaN(d)) {
// return d;
//}
return new BigDecimal(string);
} else {
final long myLong = Long.parseLong(string);
if (string.equals(Long.toString(myLong))) {
if (myLong == (int) myLong) {
return (int) myLong;
} else {
return myLong;
}
}
}
} catch (Exception ignore) {
}
}
// 其它情况返回原String值下
return string;
}
/**
* 将Property的键转化为JSON形式<br>
* 用于识别类似于com.luxiaolei.package.hutool这类用点隔开的键
*
* @param jsonObject JSONObject
* @param key 键
* @param value 值
* @return JSONObject
*/
protected static JSONObject propertyPut(JSONObject jsonObject, Object key, Object value) {
final String[] path = StrUtil.split(Convert.toStr(key), StrUtil.DOT);
int last = path.length - 1;
JSONObject target = jsonObject;
for (int i = 0; i < last; i += 1) {
String segment = path[i];
JSONObject nextTarget = target.getJSONObject(segment);
if (nextTarget == null) {
nextTarget = new JSONObject(target.getConfig());
target.set(segment, nextTarget);
}
target = nextTarget;
}
target.set(path[last], value);
return jsonObject;
}
/**
* 默认情况下是否忽略null值的策略选择以下对象不忽略null值其它对象忽略
*
* <pre>
* 1. CharSequence
* 2. JSONTokener
* 3. Map
* </pre>
*
* @param obj 需要检查的对象
* @return 是否忽略null值
* @since 4.3.1
*/
protected static boolean defaultIgnoreNullValue(Object obj) {
return (false == (obj instanceof CharSequence))//
&& (false == (obj instanceof JSONTokener))//
&& (false == (obj instanceof Map));
}
/**
* 按照给定格式格式化日期,格式为空时返回时间戳字符串
*
* @param dateObj Date或者Calendar对象
* @param format 格式
* @return 日期字符串
*/
private static String formatDate(Object dateObj, String format) {
if (StrUtil.isNotBlank(format)) {
final String dateStr;
if(dateObj instanceof TemporalAccessor){
dateStr = TemporalAccessorUtil.format((TemporalAccessor) dateObj, format);
} else{
dateStr = DateUtil.format(Convert.toDate(dateObj), format);
}
//用户定义了日期格式
return JSONUtil.quote(dateStr);
}
//默认使用时间戳
long timeMillis;
if (dateObj instanceof TemporalAccessor) {
timeMillis = TemporalAccessorUtil.toEpochMilli((TemporalAccessor) dateObj);
} else if (dateObj instanceof Date) {
timeMillis = ((Date) dateObj).getTime();
} else if (dateObj instanceof Calendar) {
timeMillis = ((Calendar) dateObj).getTimeInMillis();
} else {
throw new UnsupportedOperationException("Unsupported Date type: " + dateObj.getClass());
}
return String.valueOf(timeMillis);
}
}

View File

@@ -1,187 +1,187 @@
package cn.hutool.json;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.lang.TypeReference;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
/**
* JSON接口
*
* @author Looly
*/
public interface JSON extends Cloneable, Serializable {
/**
* 通过表达式获取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 对象
* @see BeanPath#get(Object)
* @since 4.0.6
*/
Object getByPath(String expression);
/**
* 设置表达式指定位置或filed对应的值<br>
* 若表达式指向一个JSONArray则设置其坐标对应位置的值若指向JSONObject则put对应key的值<br>
* 注意如果为JSONArray设置值下标小于其长度将替换原有值否则追加新值<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 表达式
* @param value 值
*/
void putByPath(String expression, Object 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#get(Object)
* @since 4.0.6
*/
<T> T getByPath(String expression, Class<T> resultType);
/**
* 格式化打印JSON缩进为4个空格
*
* @return 格式化后的JSON字符串
* @throws JSONException 包含非法数抛出此异常
* @since 3.0.9
*/
default String toStringPretty() throws JSONException {
return this.toJSONString(4);
}
/**
* 格式化输出JSON字符串
*
* @param indentFactor 每层缩进空格数
* @return JSON字符串
* @throws JSONException 包含非法数抛出此异常
*/
default String toJSONString(int indentFactor) throws JSONException {
final StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) {
return this.write(sw, indentFactor, 0).toString();
}
}
/**
* 将JSON内容写入Writer无缩进<br>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer Writer
* @return Writer
* @throws JSONException JSON相关异常
*/
default Writer write(Writer writer) throws JSONException {
return this.write(writer, 0, 0);
}
/**
* 将JSON内容写入Writer<br>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer writer
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @return Writer
* @throws JSONException JSON相关异常
*/
Writer write(Writer writer, int indentFactor, int indent) throws JSONException;
/**
* 转为实体类对象,转换异常将被抛出
*
* @param <T> Bean类型
* @param clazz 实体类
* @return 实体类对象
*/
default <T> T toBean(Class<T> clazz) {
return toBean((Type) clazz);
}
/**
* 转为实体类对象,转换异常将被抛出
*
* @param <T> Bean类型
* @param reference {@link TypeReference}类型参考子类可以获取其泛型参数中的Type类型
* @return 实体类对象
* @since 4.2.2
*/
default <T> T toBean(TypeReference<T> reference) {
return toBean(reference.getType());
}
/**
* 转为实体类对象
*
* @param <T> Bean类型
* @param type {@link Type}
* @return 实体类对象
* @since 3.0.8
*/
default <T> T toBean(Type type) {
return toBean(type, false);
}
/**
* 转为实体类对象
*
* @param <T> Bean类型
* @param type {@link Type}
* @param ignoreError 是否忽略转换错误
* @return 实体类对象
* @since 4.3.2
*/
default <T> T toBean(Type type, boolean ignoreError) {
return JSONConverter.jsonConvert(type, this, ignoreError);
}
}
package cn.hutool.json;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.lang.TypeReference;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
/**
* JSON接口
*
* @author Looly
*/
public interface JSON extends Cloneable, Serializable {
/**
* 通过表达式获取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 对象
* @see BeanPath#get(Object)
* @since 4.0.6
*/
Object getByPath(String expression);
/**
* 设置表达式指定位置或filed对应的值<br>
* 若表达式指向一个JSONArray则设置其坐标对应位置的值若指向JSONObject则put对应key的值<br>
* 注意如果为JSONArray设置值下标小于其长度将替换原有值否则追加新值<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 表达式
* @param value 值
*/
void putByPath(String expression, Object 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#get(Object)
* @since 4.0.6
*/
<T> T getByPath(String expression, Class<T> resultType);
/**
* 格式化打印JSON缩进为4个空格
*
* @return 格式化后的JSON字符串
* @throws JSONException 包含非法数抛出此异常
* @since 3.0.9
*/
default String toStringPretty() throws JSONException {
return this.toJSONString(4);
}
/**
* 格式化输出JSON字符串
*
* @param indentFactor 每层缩进空格数
* @return JSON字符串
* @throws JSONException 包含非法数抛出此异常
*/
default String toJSONString(int indentFactor) throws JSONException {
final StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) {
return this.write(sw, indentFactor, 0).toString();
}
}
/**
* 将JSON内容写入Writer无缩进<br>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer Writer
* @return Writer
* @throws JSONException JSON相关异常
*/
default Writer write(Writer writer) throws JSONException {
return this.write(writer, 0, 0);
}
/**
* 将JSON内容写入Writer<br>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer writer
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @return Writer
* @throws JSONException JSON相关异常
*/
Writer write(Writer writer, int indentFactor, int indent) throws JSONException;
/**
* 转为实体类对象,转换异常将被抛出
*
* @param <T> Bean类型
* @param clazz 实体类
* @return 实体类对象
*/
default <T> T toBean(Class<T> clazz) {
return toBean((Type) clazz);
}
/**
* 转为实体类对象,转换异常将被抛出
*
* @param <T> Bean类型
* @param reference {@link TypeReference}类型参考子类可以获取其泛型参数中的Type类型
* @return 实体类对象
* @since 4.2.2
*/
default <T> T toBean(TypeReference<T> reference) {
return toBean(reference.getType());
}
/**
* 转为实体类对象
*
* @param <T> Bean类型
* @param type {@link Type}
* @return 实体类对象
* @since 3.0.8
*/
default <T> T toBean(Type type) {
return toBean(type, false);
}
/**
* 转为实体类对象
*
* @param <T> Bean类型
* @param type {@link Type}
* @param ignoreError 是否忽略转换错误
* @return 实体类对象
* @since 4.3.2
*/
default <T> T toBean(Type type, boolean ignoreError) {
return JSONConverter.jsonConvert(type, this, ignoreError);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +1,195 @@
package cn.hutool.json;
import java.io.Serializable;
/**
* JSON配置项
*
* @author looly
* @since 4.1.19
*/
public class JSONConfig implements Serializable {
private static final long serialVersionUID = 119730355204738278L;
/**
* 是否有序,顺序按照加入顺序排序
*/
private boolean order;
/**
* 是否忽略转换过程中的异常
*/
private boolean ignoreError;
/**
* 是否忽略键的大小写
*/
private boolean ignoreCase;
/**
* 日期格式null表示默认的时间戳
*/
private String dateFormat;
/**
* 是否忽略null值
*/
private boolean ignoreNullValue = true;
/**
* 是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
*/
private boolean transientSupport = true;
/**
* 创建默认的配置项
*
* @return JSONConfig
*/
public static JSONConfig create() {
return new JSONConfig();
}
/**
* 是否有序,顺序按照加入顺序排序
*
* @return 是否有序
*/
public boolean isOrder() {
return order;
}
/**
* 设置是否有序,顺序按照加入顺序排序
*
* @param order 是否有序
* @return this
*/
public JSONConfig setOrder(boolean order) {
this.order = order;
return this;
}
/**
* 是否忽略转换过程中的异常
*
* @return 是否忽略转换过程中的异常
*/
public boolean isIgnoreError() {
return ignoreError;
}
/**
* 设置是否忽略转换过程中的异常
*
* @param ignoreError 是否忽略转换过程中的异常
* @return this
*/
public JSONConfig setIgnoreError(boolean ignoreError) {
this.ignoreError = ignoreError;
return this;
}
/**
* 是否忽略键的大小写
*
* @return 是否忽略键的大小写
*/
public boolean isIgnoreCase() {
return ignoreCase;
}
/**
* 设置是否忽略键的大小写
*
* @param ignoreCase 是否忽略键的大小写
* @return this
*/
public JSONConfig setIgnoreCase(boolean ignoreCase) {
this.ignoreCase = ignoreCase;
return this;
}
/**
* 日期格式null表示默认的时间戳
*
* @return 日期格式null表示默认的时间戳
*/
public String getDateFormat() {
return dateFormat;
}
/**
* 设置日期格式null表示默认的时间戳<br>
* 此方法设置的日期格式仅对转换为JSON字符串有效对解析JSON为bean无效。
*
* @param dateFormat 日期格式null表示默认的时间戳
* @return this
*/
public JSONConfig setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
return this;
}
/**
* 是否忽略null值
*
* @return 是否忽略null值
*/
public boolean isIgnoreNullValue() {
return this.ignoreNullValue;
}
/**
* 设置是否忽略null值
*
* @param ignoreNullValue 是否忽略null值
* @return this
*/
public JSONConfig setIgnoreNullValue(boolean ignoreNullValue) {
this.ignoreNullValue = ignoreNullValue;
return this;
}
/**
* 是否忽略transient关键字修饰的字段
*
* @return 是否忽略transient关键字修饰的字段
* @since 5.3.11
* @deprecated 此方法名称有二义性,请使用{@link #isTransientSupport()}
*/
@Deprecated
public boolean isIgnoreTransient() {
return isTransientSupport();
}
/**
* 设置是否忽略transient关键字修饰的字段
*
* @param ignoreTransient 是否忽略transient关键字修饰的字段
* @return this
* @since 5.3.11
* @deprecated 此方法名称有二义性,请使用{@link #setTransientSupport(boolean)}
*/
@Deprecated
public JSONConfig setIgnoreTransient(boolean ignoreTransient) {
return setTransientSupport(ignoreTransient);
}
/**
* 是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
*
* @return 是否支持
* @since 5.4.2
*/
public boolean isTransientSupport() {
return this.transientSupport;
}
/**
* 设置是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
*
* @param transientSupport 是否支持
* @return this
* @since 5.4.2
*/
public JSONConfig setTransientSupport(boolean transientSupport) {
this.transientSupport = transientSupport;
return this;
}
}
package cn.hutool.json;
import java.io.Serializable;
/**
* JSON配置项
*
* @author looly
* @since 4.1.19
*/
public class JSONConfig implements Serializable {
private static final long serialVersionUID = 119730355204738278L;
/**
* 是否有序,顺序按照加入顺序排序
*/
private boolean order;
/**
* 是否忽略转换过程中的异常
*/
private boolean ignoreError;
/**
* 是否忽略键的大小写
*/
private boolean ignoreCase;
/**
* 日期格式null表示默认的时间戳
*/
private String dateFormat;
/**
* 是否忽略null值
*/
private boolean ignoreNullValue = true;
/**
* 是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
*/
private boolean transientSupport = true;
/**
* 创建默认的配置项
*
* @return JSONConfig
*/
public static JSONConfig create() {
return new JSONConfig();
}
/**
* 是否有序,顺序按照加入顺序排序
*
* @return 是否有序
*/
public boolean isOrder() {
return order;
}
/**
* 设置是否有序,顺序按照加入顺序排序
*
* @param order 是否有序
* @return this
*/
public JSONConfig setOrder(boolean order) {
this.order = order;
return this;
}
/**
* 是否忽略转换过程中的异常
*
* @return 是否忽略转换过程中的异常
*/
public boolean isIgnoreError() {
return ignoreError;
}
/**
* 设置是否忽略转换过程中的异常
*
* @param ignoreError 是否忽略转换过程中的异常
* @return this
*/
public JSONConfig setIgnoreError(boolean ignoreError) {
this.ignoreError = ignoreError;
return this;
}
/**
* 是否忽略键的大小写
*
* @return 是否忽略键的大小写
*/
public boolean isIgnoreCase() {
return ignoreCase;
}
/**
* 设置是否忽略键的大小写
*
* @param ignoreCase 是否忽略键的大小写
* @return this
*/
public JSONConfig setIgnoreCase(boolean ignoreCase) {
this.ignoreCase = ignoreCase;
return this;
}
/**
* 日期格式null表示默认的时间戳
*
* @return 日期格式null表示默认的时间戳
*/
public String getDateFormat() {
return dateFormat;
}
/**
* 设置日期格式null表示默认的时间戳<br>
* 此方法设置的日期格式仅对转换为JSON字符串有效对解析JSON为bean无效。
*
* @param dateFormat 日期格式null表示默认的时间戳
* @return this
*/
public JSONConfig setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
return this;
}
/**
* 是否忽略null值
*
* @return 是否忽略null值
*/
public boolean isIgnoreNullValue() {
return this.ignoreNullValue;
}
/**
* 设置是否忽略null值
*
* @param ignoreNullValue 是否忽略null值
* @return this
*/
public JSONConfig setIgnoreNullValue(boolean ignoreNullValue) {
this.ignoreNullValue = ignoreNullValue;
return this;
}
/**
* 是否忽略transient关键字修饰的字段
*
* @return 是否忽略transient关键字修饰的字段
* @since 5.3.11
* @deprecated 此方法名称有二义性,请使用{@link #isTransientSupport()}
*/
@Deprecated
public boolean isIgnoreTransient() {
return isTransientSupport();
}
/**
* 设置是否忽略transient关键字修饰的字段
*
* @param ignoreTransient 是否忽略transient关键字修饰的字段
* @return this
* @since 5.3.11
* @deprecated 此方法名称有二义性,请使用{@link #setTransientSupport(boolean)}
*/
@Deprecated
public JSONConfig setIgnoreTransient(boolean ignoreTransient) {
return setTransientSupport(ignoreTransient);
}
/**
* 是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
*
* @return 是否支持
* @since 5.4.2
*/
public boolean isTransientSupport() {
return this.transientSupport;
}
/**
* 设置是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
*
* @param transientSupport 是否支持
* @return this
* @since 5.4.2
*/
public JSONConfig setTransientSupport(boolean transientSupport) {
this.transientSupport = transientSupport;
return this;
}
}

View File

@@ -1,100 +1,100 @@
package cn.hutool.json;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.ConvertException;
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.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONDeserializer;
import java.lang.reflect.Type;
import java.util.List;
/**
* JSON转换器
*
* @author looly
* @since 4.2.2
*/
public class JSONConverter implements Converter<JSON> {
static {
// 注册到转换中心
ConverterRegistry registry = ConverterRegistry.getInstance();
registry.putCustom(JSON.class, JSONConverter.class);
registry.putCustom(JSONObject.class, JSONConverter.class);
registry.putCustom(JSONArray.class, JSONConverter.class);
}
/**
* JSONArray转数组
*
* @param jsonArray JSONArray
* @param arrayClass 数组元素类型
* @return 数组对象
*/
protected static Object toArray(JSONArray jsonArray, Class<?> arrayClass) {
return new ArrayConverter(arrayClass).convert(jsonArray, null);
}
/**
* 将JSONArray转换为指定类型的对量列表
*
* @param <T> 元素类型
* @param jsonArray JSONArray
* @param elementType 对象元素类型
* @return 对象列表
*/
protected static <T> List<T> toList(JSONArray jsonArray, Class<T> elementType) {
return Convert.toList(elementType, jsonArray);
}
/**
* JSON递归转换<br>
* 首先尝试JDK类型转换如果失败尝试JSON转Bean
*
* @param <T> 转换后的对象类型
* @param targetType 目标类型
* @param value 值
* @param ignoreError 是否忽略转换错误
* @return 目标类型的值
* @throws ConvertException 转换失败
*/
@SuppressWarnings("unchecked")
protected static <T> T jsonConvert(Type targetType, Object value, boolean ignoreError) throws ConvertException {
if (JSONUtil.isNull(value)) {
return null;
}
if(value instanceof JSON) {
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
if(null != deserializer) {
return (T) deserializer.deserialize((JSON)value);
}
}
final T targetValue = Convert.convertWithCheck(targetType, value, null, ignoreError);
if (null == targetValue && false == ignoreError) {
if (StrUtil.isBlankIfStr(value)) {
// 对于传入空字符串的情况如果转换的目标对象是非字符串或非原始类型转换器会返回false。
// 此处特殊处理认为返回null属于正常情况
return null;
}
throw new ConvertException("Can not convert {} to type {}", value, ObjectUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType));
}
return targetValue;
}
@Override
public JSON convert(Object value, JSON defaultValue) throws IllegalArgumentException {
return JSONUtil.parse(value);
}
}
package cn.hutool.json;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.ConvertException;
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.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONDeserializer;
import java.lang.reflect.Type;
import java.util.List;
/**
* JSON转换器
*
* @author looly
* @since 4.2.2
*/
public class JSONConverter implements Converter<JSON> {
static {
// 注册到转换中心
ConverterRegistry registry = ConverterRegistry.getInstance();
registry.putCustom(JSON.class, JSONConverter.class);
registry.putCustom(JSONObject.class, JSONConverter.class);
registry.putCustom(JSONArray.class, JSONConverter.class);
}
/**
* JSONArray转数组
*
* @param jsonArray JSONArray
* @param arrayClass 数组元素类型
* @return 数组对象
*/
protected static Object toArray(JSONArray jsonArray, Class<?> arrayClass) {
return new ArrayConverter(arrayClass).convert(jsonArray, null);
}
/**
* 将JSONArray转换为指定类型的对量列表
*
* @param <T> 元素类型
* @param jsonArray JSONArray
* @param elementType 对象元素类型
* @return 对象列表
*/
protected static <T> List<T> toList(JSONArray jsonArray, Class<T> elementType) {
return Convert.toList(elementType, jsonArray);
}
/**
* JSON递归转换<br>
* 首先尝试JDK类型转换如果失败尝试JSON转Bean
*
* @param <T> 转换后的对象类型
* @param targetType 目标类型
* @param value 值
* @param ignoreError 是否忽略转换错误
* @return 目标类型的值
* @throws ConvertException 转换失败
*/
@SuppressWarnings("unchecked")
protected static <T> T jsonConvert(Type targetType, Object value, boolean ignoreError) throws ConvertException {
if (JSONUtil.isNull(value)) {
return null;
}
if(value instanceof JSON) {
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
if(null != deserializer) {
return (T) deserializer.deserialize((JSON)value);
}
}
final T targetValue = Convert.convertWithCheck(targetType, value, null, ignoreError);
if (null == targetValue && false == ignoreError) {
if (StrUtil.isBlankIfStr(value)) {
// 对于传入空字符串的情况如果转换的目标对象是非字符串或非原始类型转换器会返回false。
// 此处特殊处理认为返回null属于正常情况
return null;
}
throw new ConvertException("Can not convert {} to type {}", value, ObjectUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType));
}
return targetValue;
}
@Override
public JSON convert(Object value, JSON defaultValue) throws IllegalArgumentException {
return JSONUtil.parse(value);
}
}

View File

@@ -1,141 +1,141 @@
package cn.hutool.json;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.getter.OptNullBasicTypeFromObjectGetter;
/**
* 用于JSON的Getter类提供各种类型的Getter方法
*
* @param <K> Key类型
* @author Looly
*/
public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
/**
* 获取JSON配置
*
* @return {@link JSONConfig}
* @since 5.3.0
*/
JSONConfig getConfig();
/**
* key对应值是否为{@code null}或无此key
*
* @param key 键
* @return true 无此key或值为{@code null}或{@link JSONNull#NULL}返回{@code false},其它返回{@code true}
*/
default boolean isNull(K key) {
return JSONNull.NULL.equals(this.getObj(key));
}
/**
* 获取字符串类型值,并转义不可见字符,如'\n'换行符会被转义为字符串"\n"
*
* @param key 键
* @return 字符串类型值
* @since 4.2.2
*/
default String getStrEscaped(K key) {
return getStrEscaped(key, null);
}
/**
* 获取字符串类型值,并转义不可见字符,如'\n'换行符会被转义为字符串"\n"
*
* @param key 键
* @param defaultValue 默认值
* @return 字符串类型值
* @since 4.2.2
*/
default String getStrEscaped(K key, String defaultValue) {
return JSONUtil.escape(getStr(key, defaultValue));
}
/**
* 获得JSONArray对象<br>
* 如果值为其它类型对象,尝试转换为{@link JSONArray}返回,否则抛出异常
*
* @param key KEY
* @return JSONArray对象如果值为null或者非JSONArray类型返回null
*/
default JSONArray getJSONArray(K key) {
final Object object = this.getObj(key);
if (null == object) {
return null;
}
if (object instanceof JSON) {
return (JSONArray) object;
}
return new JSONArray(object, getConfig());
}
/**
* 获得JSONObject对象<br>
* 如果值为其它类型对象,尝试转换为{@link JSONObject}返回,否则抛出异常
*
* @param key KEY
* @return JSONArray对象如果值为null或者非JSONObject类型返回null
*/
default JSONObject getJSONObject(K key) {
final Object object = this.getObj(key);
if (null == object) {
return null;
}
if (object instanceof JSON) {
return (JSONObject) object;
}
return new JSONObject(object, getConfig());
}
/**
* 从JSON中直接获取Bean对象<br>
* 先获取JSONObject对象然后转为Bean对象
*
* @param <T> Bean类型
* @param key KEY
* @param beanType Bean类型
* @return Bean对象如果值为null或者非JSONObject类型返回null
* @since 3.1.1
*/
default <T> T getBean(K key, Class<T> beanType) {
final JSONObject obj = getJSONObject(key);
return (null == obj) ? null : obj.toBean(beanType);
}
/**
* 获取指定类型的对象<br>
* 转换失败或抛出异常
*
* @param <T> 获取的对象类型
* @param key 键
* @param type 获取对象类型
* @return 对象
* @throws ConvertException 转换异常
* @since 3.0.8
*/
default <T> T get(K key, Class<T> type) throws ConvertException {
return get(key, type, false);
}
/**
* 获取指定类型的对象
*
* @param <T> 获取的对象类型
* @param key 键
* @param type 获取对象类型
* @param ignoreError 是否跳过转换失败的对象或值
* @return 对象
* @throws ConvertException 转换异常
* @since 3.0.8
*/
default <T> T get(K key, Class<T> type, boolean ignoreError) throws ConvertException {
final Object value = this.getObj(key);
if (null == value) {
return null;
}
return JSONConverter.jsonConvert(type, value, ignoreError);
}
}
package cn.hutool.json;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.getter.OptNullBasicTypeFromObjectGetter;
/**
* 用于JSON的Getter类提供各种类型的Getter方法
*
* @param <K> Key类型
* @author Looly
*/
public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
/**
* 获取JSON配置
*
* @return {@link JSONConfig}
* @since 5.3.0
*/
JSONConfig getConfig();
/**
* key对应值是否为{@code null}或无此key
*
* @param key 键
* @return true 无此key或值为{@code null}或{@link JSONNull#NULL}返回{@code false},其它返回{@code true}
*/
default boolean isNull(K key) {
return JSONNull.NULL.equals(this.getObj(key));
}
/**
* 获取字符串类型值,并转义不可见字符,如'\n'换行符会被转义为字符串"\n"
*
* @param key 键
* @return 字符串类型值
* @since 4.2.2
*/
default String getStrEscaped(K key) {
return getStrEscaped(key, null);
}
/**
* 获取字符串类型值,并转义不可见字符,如'\n'换行符会被转义为字符串"\n"
*
* @param key 键
* @param defaultValue 默认值
* @return 字符串类型值
* @since 4.2.2
*/
default String getStrEscaped(K key, String defaultValue) {
return JSONUtil.escape(getStr(key, defaultValue));
}
/**
* 获得JSONArray对象<br>
* 如果值为其它类型对象,尝试转换为{@link JSONArray}返回,否则抛出异常
*
* @param key KEY
* @return JSONArray对象如果值为null或者非JSONArray类型返回null
*/
default JSONArray getJSONArray(K key) {
final Object object = this.getObj(key);
if (null == object) {
return null;
}
if (object instanceof JSON) {
return (JSONArray) object;
}
return new JSONArray(object, getConfig());
}
/**
* 获得JSONObject对象<br>
* 如果值为其它类型对象,尝试转换为{@link JSONObject}返回,否则抛出异常
*
* @param key KEY
* @return JSONArray对象如果值为null或者非JSONObject类型返回null
*/
default JSONObject getJSONObject(K key) {
final Object object = this.getObj(key);
if (null == object) {
return null;
}
if (object instanceof JSON) {
return (JSONObject) object;
}
return new JSONObject(object, getConfig());
}
/**
* 从JSON中直接获取Bean对象<br>
* 先获取JSONObject对象然后转为Bean对象
*
* @param <T> Bean类型
* @param key KEY
* @param beanType Bean类型
* @return Bean对象如果值为null或者非JSONObject类型返回null
* @since 3.1.1
*/
default <T> T getBean(K key, Class<T> beanType) {
final JSONObject obj = getJSONObject(key);
return (null == obj) ? null : obj.toBean(beanType);
}
/**
* 获取指定类型的对象<br>
* 转换失败或抛出异常
*
* @param <T> 获取的对象类型
* @param key 键
* @param type 获取对象类型
* @return 对象
* @throws ConvertException 转换异常
* @since 3.0.8
*/
default <T> T get(K key, Class<T> type) throws ConvertException {
return get(key, type, false);
}
/**
* 获取指定类型的对象
*
* @param <T> 获取的对象类型
* @param key 键
* @param type 获取对象类型
* @param ignoreError 是否跳过转换失败的对象或值
* @return 对象
* @throws ConvertException 转换异常
* @since 3.0.8
*/
default <T> T get(K key, Class<T> type, boolean ignoreError) throws ConvertException {
final Object value = this.getObj(key);
if (null == value) {
return null;
}
return JSONConverter.jsonConvert(type, value, ignoreError);
}
}

View File

@@ -1,46 +1,46 @@
package cn.hutool.json;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
/**
* 用于定义<code>null</code>与Javascript中null相对应<br>
* Java中的<code>null</code>值在js中表示为undefined。
* @author Looly
*
*/
public class JSONNull implements Serializable{
private static final long serialVersionUID = 2633815155870764938L;
/**
* <code>NULL</code> 对象用于减少歧义来表示Java 中的<code>null</code> <br>
* <code>NULL.equals(null)</code> 返回 <code>true</code>. <br>
* <code>NULL.toString()</code> 返回 <code>"null"</code>.
*/
public static final JSONNull NULL = new JSONNull();
/**
* A Null object is equal to the null value and to itself.
* 对象与其本身和<code>null</code>值相等
*
* @param object An object to test for nullness.
* @return true if the object parameter is the JSONObject.NULL object or null.
*/
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object object) {
return object == null || (object == this);
}
/**
* Get the "null" string value.
*获得“null”字符串
*
* @return The string "null".
*/
@Override
public String toString() {
return StrUtil.NULL;
}
package cn.hutool.json;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
/**
* 用于定义<code>null</code>与Javascript中null相对应<br>
* Java中的<code>null</code>值在js中表示为undefined。
* @author Looly
*
*/
public class JSONNull implements Serializable{
private static final long serialVersionUID = 2633815155870764938L;
/**
* <code>NULL</code> 对象用于减少歧义来表示Java 中的<code>null</code> <br>
* <code>NULL.equals(null)</code> 返回 <code>true</code>. <br>
* <code>NULL.toString()</code> 返回 <code>"null"</code>.
*/
public static final JSONNull NULL = new JSONNull();
/**
* A Null object is equal to the null value and to itself.
* 对象与其本身和<code>null</code>值相等
*
* @param object An object to test for nullness.
* @return true if the object parameter is the JSONObject.NULL object or null.
*/
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object object) {
return object == null || (object == this);
}
/**
* Get the "null" string value.
*获得“null”字符串
*
* @return The string "null".
*/
@Override
public String toString() {
return StrUtil.NULL;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +1,40 @@
package cn.hutool.json;
import java.util.Iterator;
/**
* 此类用于在JSONAray中便于遍历JSONObject而封装的Iterable可以借助foreach语法遍历
*
* @author looly
* @since 4.0.12
*/
public class JSONObjectIter implements Iterable<JSONObject> {
Iterator<Object> iterator;
public JSONObjectIter(Iterator<Object> iterator) {
this.iterator = iterator;
}
@Override
public Iterator<JSONObject> iterator() {
return new Iterator<JSONObject>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public JSONObject next() {
return (JSONObject) iterator.next();
}
@Override
public void remove() {
iterator.remove();
}
};
}
}
package cn.hutool.json;
import java.util.Iterator;
/**
* 此类用于在JSONAray中便于遍历JSONObject而封装的Iterable可以借助foreach语法遍历
*
* @author looly
* @since 4.0.12
*/
public class JSONObjectIter implements Iterable<JSONObject> {
Iterator<Object> iterator;
public JSONObjectIter(Iterator<Object> iterator) {
this.iterator = iterator;
}
@Override
public Iterator<JSONObject> iterator() {
return new Iterator<JSONObject>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public JSONObject next() {
return (JSONObject) iterator.next();
}
@Override
public void remove() {
iterator.remove();
}
};
}
}

View File

@@ -1,123 +1,123 @@
package cn.hutool.json;
import cn.hutool.core.util.StrUtil;
/**
* JSON字符串格式化工具用于简单格式化JSON字符串<br>
* from http://blog.csdn.net/lovelong8808/article/details/54580278
*
* @author looly
* @since 3.1.2
*/
public class JSONStrFormatter {
/** 单位缩进字符串。*/
private static final String SPACE = " ";
/** 换行符*/
private static final char NEW_LINE = StrUtil.C_LF;
/**
* 返回格式化JSON字符串。
*
* @param json 未格式化的JSON字符串。
* @return 格式化的JSON字符串。
*/
public static String format(String json) {
final StringBuilder result = new StringBuilder();
Character wrapChar = null;
boolean isEscapeMode = false;
int length = json.length();
int number = 0;
char key;
for (int i = 0; i < length; i++) {
key = json.charAt(i);
if('"' == key || '\'' == key) {
if(null == wrapChar) {
//字符串模式开始
wrapChar = key;
}else if(isEscapeMode) {
//在字符串模式下的转义
isEscapeMode = false;
}else if(wrapChar.equals(key)){
//字符串包装结束
wrapChar = null;
}
result.append(key);
continue;
}else if('\\' == key) {
if(null != wrapChar) {
//字符串模式下转义有效
isEscapeMode = !isEscapeMode;
result.append(key);
continue;
}else {
result.append(key);
}
}
if(null != wrapChar) {
//字符串模式
result.append(key);
continue;
}
//如果当前字符是前方括号、前花括号做如下处理:
if ((key == '[') || (key == '{')) {
//如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
if ((i - 1 > 0) && (json.charAt(i - 1) == ':')) {
result.append(NEW_LINE);
result.append(indent(number));
}
result.append(key);
//前方括号、前花括号,的后面必须换行。打印:换行。
result.append(NEW_LINE);
//每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
number++;
result.append(indent(number));
continue;
}
// 3、如果当前字符是后方括号、后花括号做如下处理
if ((key == ']') || (key == '}')) {
// 1后方括号、后花括号的前面必须换行。打印换行。
result.append(NEW_LINE);
// 2每出现一次后方括号、后花括号缩进次数减少一次。打印缩进。
number--;
result.append(indent(number));
// 3打印当前字符。
result.append(key);
// 4如果当前字符后面还有字符并且字符不为“打印换行。
if (((i + 1) < length) && (json.charAt(i + 1) != ',')) {
result.append(NEW_LINE);
}
// 5继续下一次循环。
continue;
}
// 4、如果当前字符是逗号。逗号后面换行并缩进不改变缩进次数。
if ((key == ',')) {
result.append(key);
result.append(NEW_LINE);
result.append(indent(number));
continue;
}
// 5、打印当前字符。
result.append(key);
}
return result.toString();
}
/**
* 返回指定次数的缩进字符串。每一次缩进4个空格即SPACE。
*
* @param number 缩进次数。
* @return 指定缩进次数的字符串。
*/
private static String indent(int number) {
return StrUtil.repeat(SPACE, number);
}
}
package cn.hutool.json;
import cn.hutool.core.util.StrUtil;
/**
* JSON字符串格式化工具用于简单格式化JSON字符串<br>
* from http://blog.csdn.net/lovelong8808/article/details/54580278
*
* @author looly
* @since 3.1.2
*/
public class JSONStrFormatter {
/** 单位缩进字符串。*/
private static final String SPACE = " ";
/** 换行符*/
private static final char NEW_LINE = StrUtil.C_LF;
/**
* 返回格式化JSON字符串。
*
* @param json 未格式化的JSON字符串。
* @return 格式化的JSON字符串。
*/
public static String format(String json) {
final StringBuilder result = new StringBuilder();
Character wrapChar = null;
boolean isEscapeMode = false;
int length = json.length();
int number = 0;
char key;
for (int i = 0; i < length; i++) {
key = json.charAt(i);
if('"' == key || '\'' == key) {
if(null == wrapChar) {
//字符串模式开始
wrapChar = key;
}else if(isEscapeMode) {
//在字符串模式下的转义
isEscapeMode = false;
}else if(wrapChar.equals(key)){
//字符串包装结束
wrapChar = null;
}
result.append(key);
continue;
}else if('\\' == key) {
if(null != wrapChar) {
//字符串模式下转义有效
isEscapeMode = !isEscapeMode;
result.append(key);
continue;
}else {
result.append(key);
}
}
if(null != wrapChar) {
//字符串模式
result.append(key);
continue;
}
//如果当前字符是前方括号、前花括号做如下处理:
if ((key == '[') || (key == '{')) {
//如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
if ((i - 1 > 0) && (json.charAt(i - 1) == ':')) {
result.append(NEW_LINE);
result.append(indent(number));
}
result.append(key);
//前方括号、前花括号,的后面必须换行。打印:换行。
result.append(NEW_LINE);
//每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
number++;
result.append(indent(number));
continue;
}
// 3、如果当前字符是后方括号、后花括号做如下处理
if ((key == ']') || (key == '}')) {
// 1后方括号、后花括号的前面必须换行。打印换行。
result.append(NEW_LINE);
// 2每出现一次后方括号、后花括号缩进次数减少一次。打印缩进。
number--;
result.append(indent(number));
// 3打印当前字符。
result.append(key);
// 4如果当前字符后面还有字符并且字符不为“打印换行。
if (((i + 1) < length) && (json.charAt(i + 1) != ',')) {
result.append(NEW_LINE);
}
// 5继续下一次循环。
continue;
}
// 4、如果当前字符是逗号。逗号后面换行并缩进不改变缩进次数。
if ((key == ',')) {
result.append(key);
result.append(NEW_LINE);
result.append(indent(number));
continue;
}
// 5、打印当前字符。
result.append(key);
}
return result.toString();
}
/**
* 返回指定次数的缩进字符串。每一次缩进4个空格即SPACE。
*
* @param number 缩进次数。
* @return 指定缩进次数的字符串。
*/
private static String indent(int number) {
return StrUtil.repeat(SPACE, number);
}
}

View File

@@ -1,45 +1,45 @@
package cn.hutool.json;
/**
* JSON支持<br>
* 继承此类实现实体类与JSON的相互转换
*
* @author Looly
*
*/
public class JSONSupport implements JSONString{
/**
* JSON String转Bean
* @param jsonString JSON String
*/
public void parse(String jsonString){
new JSONObject(jsonString).toBean(this.getClass());
}
/**
* @return JSON对象
*/
public JSONObject toJSON() {
return new JSONObject(this);
}
@Override
public String toJSONString() {
return toJSON().toString();
}
/**
* 美化的JSON使用回车缩进显示JSON用于打印输出debug
*
* @return 美化的JSON
*/
public String toPrettyString() {
return toJSON().toStringPretty();
}
@Override
public String toString() {
return toJSONString();
}
}
package cn.hutool.json;
/**
* JSON支持<br>
* 继承此类实现实体类与JSON的相互转换
*
* @author Looly
*
*/
public class JSONSupport implements JSONString{
/**
* JSON String转Bean
* @param jsonString JSON String
*/
public void parse(String jsonString){
new JSONObject(jsonString).toBean(this.getClass());
}
/**
* @return JSON对象
*/
public JSONObject toJSON() {
return new JSONObject(this);
}
@Override
public String toJSONString() {
return toJSON().toString();
}
/**
* 美化的JSON使用回车缩进显示JSON用于打印输出debug
*
* @return 美化的JSON
*/
public String toPrettyString() {
return toJSON().toStringPretty();
}
@Override
public String toString() {
return toJSONString();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/**
* JSON封装基于json.org官方库改造
*
* @author looly
*
*/
/**
* JSON封装基于json.org官方库改造
*
* @author looly
*
*/
package cn.hutool.json;

View File

@@ -1,90 +1,90 @@
package cn.hutool.json.serialize;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import cn.hutool.json.JSON;
/**
* 全局的序列化和反序列化器映射<br>
* 在JSON和Java对象转换过程中优先使用注册于此处的自定义转换
*
* @author Looly
*
*/
public class GlobalSerializeMapping {
private static Map<Type, JSONSerializer<? extends JSON, ?>> serializerMap;
private static Map<Type, JSONDeserializer<?>> deserializerMap;
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
public static void put(Type type, JSONArraySerializer<?> serializer) {
putInternal(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
public static void put(Type type, JSONObjectSerializer<?> serializer) {
putInternal(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
synchronized private static void putInternal(Type type, JSONSerializer<? extends JSON, ?> serializer) {
if(null == serializerMap) {
serializerMap = new ConcurrentHashMap<>();
}
serializerMap.put(type, serializer);
}
/**
* 加入自定义的反序列化器
*
* @param type 对象类型
* @param deserializer 反序列化器实现
*/
synchronized public static void put(Type type, JSONDeserializer<?> deserializer) {
if(null == deserializerMap) {
deserializerMap = new ConcurrentHashMap<>();
}
deserializerMap.put(type, deserializer);
}
/**
* 获取自定义的序列化器,如果未定义返回{@code null}
* @param type 类型
* @return 自定义的序列化器或者{@code null}
*/
public static JSONSerializer<? extends JSON, ?> getSerializer(Type type){
if(null == serializerMap) {
return null;
}
return serializerMap.get(type);
}
/**
* 获取自定义的反序列化器,如果未定义返回{@code null}
* @param type 类型
* @return 自定义的反序列化器或者{@code null}
*/
public static JSONDeserializer<?> getDeserializer(Type type){
if(null == deserializerMap) {
return null;
}
return deserializerMap.get(type);
}
}
package cn.hutool.json.serialize;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import cn.hutool.json.JSON;
/**
* 全局的序列化和反序列化器映射<br>
* 在JSON和Java对象转换过程中优先使用注册于此处的自定义转换
*
* @author Looly
*
*/
public class GlobalSerializeMapping {
private static Map<Type, JSONSerializer<? extends JSON, ?>> serializerMap;
private static Map<Type, JSONDeserializer<?>> deserializerMap;
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
public static void put(Type type, JSONArraySerializer<?> serializer) {
putInternal(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
public static void put(Type type, JSONObjectSerializer<?> serializer) {
putInternal(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
synchronized private static void putInternal(Type type, JSONSerializer<? extends JSON, ?> serializer) {
if(null == serializerMap) {
serializerMap = new ConcurrentHashMap<>();
}
serializerMap.put(type, serializer);
}
/**
* 加入自定义的反序列化器
*
* @param type 对象类型
* @param deserializer 反序列化器实现
*/
synchronized public static void put(Type type, JSONDeserializer<?> deserializer) {
if(null == deserializerMap) {
deserializerMap = new ConcurrentHashMap<>();
}
deserializerMap.put(type, deserializer);
}
/**
* 获取自定义的序列化器,如果未定义返回{@code null}
* @param type 类型
* @return 自定义的序列化器或者{@code null}
*/
public static JSONSerializer<? extends JSON, ?> getSerializer(Type type){
if(null == serializerMap) {
return null;
}
return serializerMap.get(type);
}
/**
* 获取自定义的反序列化器,如果未定义返回{@code null}
* @param type 类型
* @return 自定义的反序列化器或者{@code null}
*/
public static JSONDeserializer<?> getDeserializer(Type type){
if(null == deserializerMap) {
return null;
}
return deserializerMap.get(type);
}
}

View File

@@ -1,13 +1,13 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSONArray;
/**
* JSON列表的序列化接口用于将特定对象序列化为{@link JSONArray}
*
* @param <V> 对象类型
*
* @author Looly
*/
@FunctionalInterface
public interface JSONArraySerializer<V> extends JSONSerializer<JSONArray, V>{}
package cn.hutool.json.serialize;
import cn.hutool.json.JSONArray;
/**
* JSON列表的序列化接口用于将特定对象序列化为{@link JSONArray}
*
* @param <V> 对象类型
*
* @author Looly
*/
@FunctionalInterface
public interface JSONArraySerializer<V> extends JSONSerializer<JSONArray, V>{}

View File

@@ -1,22 +1,22 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSON;
/**
* JSON反序列话自定义实现类
*
* @author Looly
*
* @param <T> 反序列化后的类型
*/
@FunctionalInterface
public interface JSONDeserializer<T> {
/**
* 反序列化通过实现此方法自定义实现JSON转换为指定类型的逻辑
*
* @param json {@link JSON}
* @return 目标对象
*/
T deserialize(JSON json);
}
package cn.hutool.json.serialize;
import cn.hutool.json.JSON;
/**
* JSON反序列话自定义实现类
*
* @author Looly
*
* @param <T> 反序列化后的类型
*/
@FunctionalInterface
public interface JSONDeserializer<T> {
/**
* 反序列化通过实现此方法自定义实现JSON转换为指定类型的逻辑
*
* @param json {@link JSON}
* @return 目标对象
*/
T deserialize(JSON json);
}

View File

@@ -1,12 +1,12 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSONObject;
/**
* 对象的序列化接口,用于将特定对象序列化为{@link JSONObject}
* @param <V> 对象类型
*
* @author Looly
*/
@FunctionalInterface
public interface JSONObjectSerializer<V> extends JSONSerializer<JSONObject, V>{}
package cn.hutool.json.serialize;
import cn.hutool.json.JSONObject;
/**
* 对象的序列化接口,用于将特定对象序列化为{@link JSONObject}
* @param <V> 对象类型
*
* @author Looly
*/
@FunctionalInterface
public interface JSONObjectSerializer<V> extends JSONSerializer<JSONObject, V>{}

View File

@@ -1,23 +1,23 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSON;
/**
* 序列化接口通过实现此接口实现自定义的对象转换为JSON的操作
*
* @param <T> JSON类型可以是JSONObject或者JSONArray
* @param <V> 对象类型
* @author Looly
*/
@FunctionalInterface
public interface JSONSerializer<T extends JSON, V> {
/**
* 序列化实现,通过实现此方法,将指定类型的对象转换为{@link JSON}对象<br>
* 转换后的对象可以为JSONObject也可以为JSONArray首先new一个空的JSON然后将需要的数据字段put到JSON对象中去即可。
*
* @param json JSON可以为JSONObject或者JSONArray
* @param bean 指定类型对象
*/
void serialize(T json, V bean);
}
package cn.hutool.json.serialize;
import cn.hutool.json.JSON;
/**
* 序列化接口通过实现此接口实现自定义的对象转换为JSON的操作
*
* @param <T> JSON类型可以是JSONObject或者JSONArray
* @param <V> 对象类型
* @author Looly
*/
@FunctionalInterface
public interface JSONSerializer<T extends JSON, V> {
/**
* 序列化实现,通过实现此方法,将指定类型的对象转换为{@link JSON}对象<br>
* 转换后的对象可以为JSONObject也可以为JSONArray首先new一个空的JSON然后将需要的数据字段put到JSON对象中去即可。
*
* @param json JSON可以为JSONObject或者JSONArray
* @param bean 指定类型对象
*/
void serialize(T json, V bean);
}

View File

@@ -1,7 +1,7 @@
/**
* JSON自定义序列化和反序列化接口和默认实现
*
* @author Looly
*
*/
/**
* JSON自定义序列化和反序列化接口和默认实现
*
* @author Looly
*
*/
package cn.hutool.json.serialize;