This commit is contained in:
Looly 2021-06-26 23:49:43 +08:00
parent d9a218f02c
commit 8e82919464
4 changed files with 48 additions and 129 deletions

View File

@ -1,22 +1,13 @@
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.date.format.GlobalCustomFormat;
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.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;
@ -31,63 +22,6 @@ 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) {
// since 5.6.2可配置是否去除末尾多余0例如如果为true,5.0返回5
final boolean isStripTrailingZeros = null == config || config.isStripTrailingZeros();
writer.write(NumberUtil.toStr((Number) value, isStripTrailingZeros));
} 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 appendable writer
* @param indent 缩进空格数
* @throws IOException IO异常
*/
protected static void indent(Appendable appendable, int indent) throws IOException {
for (int i = 0; i < indent; i += 1) {
appendable.append(CharUtil.SPACE);
}
}
/**
* 如果对象是Number 且是 NaN or infinite将抛出异常
*
@ -256,43 +190,4 @@ final class InternalJSONUtil {
return false;
}
/**
* 按照给定格式格式化日期格式为空时返回时间戳字符串
*
* @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);
}
if(GlobalCustomFormat.FORMAT_SECONDS.equals(format)
|| GlobalCustomFormat.FORMAT_MILLISECONDS.equals(format)){
// Hutool自定义的秒和毫秒表示默认不包装双引号
return dateStr;
}
//用户定义了日期格式
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

@ -3,6 +3,7 @@ package cn.hutool.json;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.collection.ArrayIter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrJoiner;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
@ -220,16 +221,8 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @throws JSONException If the array contains an invalid number.
*/
public String join(String separator) throws JSONException {
int len = this.rawList.size();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i += 1) {
if (i > 0) {
sb.append(separator);
}
sb.append(InternalJSONUtil.valueToString(this.rawList.get(i)));
}
return sb.toString();
return StrJoiner.of(separator)
.append(this, InternalJSONUtil::valueToString).toString();
}
@Override
@ -537,10 +530,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
@Override
public Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
final JSONWriter jsonWriter = new JSONWriter(writer, indentFactor, indent, config);
jsonWriter.beginArray();
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
.beginArray();
this.forEach(jsonWriter::writeValue);
jsonWriter.end();
// 此处不关闭Writer考虑writer后续还需要填内容
return writer;
}

View File

@ -554,8 +554,8 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
@Override
public Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
final JSONWriter jsonWriter = new JSONWriter(writer, indentFactor, indent, this.config);
jsonWriter.beginObj();
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
.beginObj();
this.forEach((key, value)-> jsonWriter.writeKey(key).writeValue(value));
jsonWriter.end();

View File

@ -33,7 +33,7 @@ import java.util.Map;
* @author looly
* @since 5.7.3
*/
public class JSONWriter {
public class JSONWriter extends Writer {
/**
* 缩进因子定义每一级别增加的缩进量
@ -62,11 +62,24 @@ public class JSONWriter {
private boolean arrayMode;
/**
* 构造
* @param writer {@link Writer}
* 创建{@link JSONWriter}
*
* @param writer {@link Writer}
* @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @param config JSON选项
* @param indent 本级别缩进量
* @param config JSON选项
*/
public static JSONWriter of(Writer writer, int indentFactor, int indent, JSONConfig config) {
return new JSONWriter(writer, indentFactor, indent, config);
}
/**
* 构造
*
* @param writer {@link Writer}
* @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @param config JSON选项
*/
public JSONWriter(Writer writer, int indentFactor, int indent, JSONConfig config) {
this.writer = writer;
@ -105,11 +118,7 @@ public class JSONWriter {
// 换行缩进
writeLF().writeSpace(indent);
writeRaw(arrayMode ? CharUtil.BRACKET_END : CharUtil.DELIM_END);
try {
writer.flush();
} catch (IOException e) {
throw new IORuntimeException(e);
}
flush();
arrayMode = false;
// 当前对象或数组结束当新的
needSeparator = true;
@ -118,6 +127,7 @@ public class JSONWriter {
/**
* 写出键自动处理分隔符和缩进并包装键名
*
* @param key 键名
* @return this
*/
@ -150,7 +160,27 @@ public class JSONWriter {
return writeObjValue(value);
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
this.writer.write(cbuf, off, len);
}
@Override
public void flush() {
try {
this.writer.flush();
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
@Override
public void close() throws IOException {
this.writer.close();
}
// ------------------------------------------------------------------------------ Private methods
/**
* 写出JSON的值根据值类型不同输出不同内容
*