add writer

This commit is contained in:
Looly 2022-09-30 23:36:55 +08:00
parent 6e71c52351
commit 609162e030
6 changed files with 225 additions and 124 deletions

View File

@ -0,0 +1,19 @@
package cn.hutool.json.writer;
/**
* Boolean类型的值写出器
*
* @author looly
* @since 6.0.0
*/
public class BooleanValueWriter implements JSONValueWriter<Boolean> {
/**
* 单例对象
*/
public static final BooleanValueWriter INSTANCE = new BooleanValueWriter();
@Override
public void write(final JSONWriter writer, final Boolean bool) {
writer.writeRaw(bool.toString());
}
}

View File

@ -0,0 +1,26 @@
package cn.hutool.json.writer;
import cn.hutool.json.serialize.DateJSONString;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
/**
* 日期类型的值写出器<br>
* 支持包括{@link Date}{@link Calendar}{@link TemporalAccessor}
*
* @author looly
* @since 6.0.0
*/
public class DateValueWriter implements JSONValueWriter<Object> {
/**
* 单例对象
*/
public static final DateValueWriter INSTANCE = new DateValueWriter();
@Override
public void write(final JSONWriter writer, final Object value) {
writer.writeRaw(new DateJSONString(value, writer.getConfig()).toJSONString());
}
}

View File

@ -0,0 +1,45 @@
package cn.hutool.json.writer;
import cn.hutool.json.JSONException;
import cn.hutool.json.serialize.JSONString;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
/**
* 日期类型的值写出器<br>
* 支持包括{@link Date}{@link Calendar}{@link TemporalAccessor}
*
* @author looly
* @since 6.0.0
*/
public class JSONStringValueWriter implements JSONValueWriter<JSONString> {
/**
* 单例对象
*/
public static final JSONStringValueWriter INSTANCE = new JSONStringValueWriter();
/**
* 输出实现了{@link JSONString}接口的对象通过调用{@link JSONString#toJSONString()}获取JSON字符串<br>
* {@link JSONString}按照JSON对象对待此方法输出的JSON字符串不包装引号<br>
* 如果toJSONString()返回null调用toString()方法并使用双引号包装
*
* @param writer {@link JSONWriter}
* @param jsonString {@link JSONString}
*/
@Override
public void write(final JSONWriter writer, final JSONString jsonString) {
final String valueStr;
try {
valueStr = jsonString.toJSONString();
} catch (final Exception e) {
throw new JSONException(e);
}
if (null != valueStr) {
writer.writeRaw(valueStr);
} else {
writer.writeQuoteStrValue(jsonString.toString());
}
}
}

View File

@ -0,0 +1,19 @@
package cn.hutool.json.writer;
/**
* JSON的值自定义写出
*
* @param <T> 写出的对象类型
* @author looly
* @since 6.0.0
*/
public interface JSONValueWriter<T> {
/**
* 使用{@link JSONWriter} 写出对象
*
* @param writer {@link JSONWriter}
* @param value 被写出的值
*/
void write(JSONWriter writer, T value);
}

View File

@ -2,14 +2,11 @@ package cn.hutool.json.writer;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.lang.mutable.MutableEntry;
import cn.hutool.core.math.NumberUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.json.InternalJSONUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONException;
import cn.hutool.json.serialize.DateJSONString;
import cn.hutool.json.serialize.JSONString;
import java.io.IOException;
@ -82,6 +79,15 @@ public class JSONWriter extends Writer {
this.config = config;
}
/**
* 获取JSON配置
*
* @return {@link JSONConfig}
*/
public JSONConfig getConfig() {
return this.config;
}
/**
* JSONObject写出开始默认写出"{"
*
@ -145,7 +151,7 @@ public class JSONWriter extends Writer {
}
}
if(false == arrayMode){
if (false == arrayMode) {
// JSONObject模式写出键否则只输出值
writeKey(StrUtil.toString(pair.getKey()));
}
@ -190,6 +196,75 @@ public class JSONWriter extends Writer {
this.writer.close();
}
/**
* 写出字符串值并包装引号并转义字符<br>
* 对所有双引号做转义处理使用双反斜杠做转义<br>
* 为了能在HTML中较好的显示会将&lt;/转义为&lt;\/<br>
* JSON字符串中不能包含控制字符和未经转义的引号和反斜杠
*
* @param csq 字符串
*/
public void writeQuoteStrValue(final String csq) {
InternalJSONUtil.quote(csq, writer);
}
/**
* 写出空格
*
* @param count 空格数
*/
public void writeSpace(final int count) {
if (indentFactor > 0) {
for (int i = 0; i < count; i++) {
//noinspection resource
writeRaw(CharUtil.SPACE);
}
}
}
/**
* 写出换换行符
*
* @return this
*/
public JSONWriter writeLF() {
if (indentFactor > 0) {
//noinspection resource
writeRaw(CharUtil.LF);
}
return this;
}
/**
* 写入原始字符串值不做任何处理
*
* @param csq 字符串
* @return this
*/
public JSONWriter writeRaw(final String csq) {
try {
writer.append(csq);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
return this;
}
/**
* 写入原始字符值不做任何处理
*
* @param c 字符串
* @return this
*/
public JSONWriter writeRaw(final char c) {
try {
writer.write(c);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
return this;
}
// ------------------------------------------------------------------------------ Private methods
/**
@ -231,133 +306,17 @@ public class JSONWriter extends Writer {
} else if (value instanceof JSON) {
((JSON) value).write(writer, indentFactor, indent, predicate);
} else if (value instanceof Number) {
writeNumberValue((Number) value);
NumberValueWriter.INSTANCE.write(this, (Number) value);
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
//noinspection resource
writeRaw(new DateJSONString(value, config).toJSONString());
DateValueWriter.INSTANCE.write(this, value);
} else if (value instanceof Boolean) {
writeBooleanValue((Boolean) value);
BooleanValueWriter.INSTANCE.write(this, (Boolean) value);
} else if (value instanceof JSONString) {
writeJSONStringValue((JSONString) value);
JSONStringValueWriter.INSTANCE.write(this, (JSONString) value);
} else {
writeQuoteStrValue(value.toString());
}
return this;
}
/**
* 写出数字根据{@link JSONConfig#isStripTrailingZeros()} 配置不同写出不同数字<br>
* 主要针对Double型是否去掉小数点后多余的0<br>
* 此方法输出的值不包装引号
*
* @param number 数字
*/
private void writeNumberValue(final Number number) {
// since 5.6.2可配置是否去除末尾多余0例如如果为true,5.0返回5
final boolean isStripTrailingZeros = null == config || config.isStripTrailingZeros();
//noinspection resource
writeRaw(NumberUtil.toStr(number, isStripTrailingZeros));
}
/**
* 写出Boolean值直接写出true或false,不适用引号包装
*
* @param value Boolean值
*/
private void writeBooleanValue(final Boolean value) {
//noinspection resource
writeRaw(value.toString());
}
/**
* 输出实现了{@link JSONString}接口的对象通过调用{@link JSONString#toJSONString()}获取JSON字符串<br>
* {@link JSONString}按照JSON对象对待此方法输出的JSON字符串不包装引号<br>
* 如果toJSONString()返回null调用toString()方法并使用双引号包装
*
* @param jsonString {@link JSONString}
*/
private void writeJSONStringValue(final JSONString jsonString) {
final String valueStr;
try {
valueStr = jsonString.toJSONString();
} catch (final Exception e) {
throw new JSONException(e);
}
if (null != valueStr) {
//noinspection resource
writeRaw(valueStr);
} else {
writeQuoteStrValue(jsonString.toString());
}
}
/**
* 写出字符串值并包装引号并转义字符<br>
* 对所有双引号做转义处理使用双反斜杠做转义<br>
* 为了能在HTML中较好的显示会将&lt;/转义为&lt;\/<br>
* JSON字符串中不能包含控制字符和未经转义的引号和反斜杠
*
* @param csq 字符串
*/
private void writeQuoteStrValue(final String csq) {
InternalJSONUtil.quote(csq, writer);
}
/**
* 写出空格
*
* @param count 空格数
*/
private void writeSpace(final int count) {
if (indentFactor > 0) {
for (int i = 0; i < count; i++) {
//noinspection resource
writeRaw(CharUtil.SPACE);
}
}
}
/**
* 写出换换行符
*
* @return this
*/
private JSONWriter writeLF() {
if (indentFactor > 0) {
//noinspection resource
writeRaw(CharUtil.LF);
}
return this;
}
/**
* 写入原始字符串值不做任何处理
*
* @param csq 字符串
* @return this
*/
private JSONWriter writeRaw(final String csq) {
try {
writer.append(csq);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
return this;
}
/**
* 写入原始字符值不做任何处理
*
* @param c 字符串
* @return this
*/
private JSONWriter writeRaw(final char c) {
try {
writer.write(c);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
return this;
}
}

View File

@ -0,0 +1,33 @@
package cn.hutool.json.writer;
import cn.hutool.core.math.NumberUtil;
import cn.hutool.json.JSONConfig;
/**
* 数字类型的值写出器
*
* @author looly
* @since 6.0.0
*/
public class NumberValueWriter implements JSONValueWriter<Number> {
/**
* 单例对象
*/
public static final NumberValueWriter INSTANCE = new NumberValueWriter();
/**
* 写出数字根据{@link JSONConfig#isStripTrailingZeros()} 配置不同写出不同数字<br>
* 主要针对Double型是否去掉小数点后多余的0<br>
* 此方法输出的值不包装引号
*
* @param writer {@link JSONWriter}
* @param number 数字
*/
@Override
public void write(final JSONWriter writer, final Number number) {
final JSONConfig config = writer.getConfig();
// since 5.6.2可配置是否去除末尾多余0例如如果为true,5.0返回5
final boolean isStripTrailingZeros = null == config || config.isStripTrailingZeros();
writer.writeRaw(NumberUtil.toStr(number, isStripTrailingZeros));
}
}