This commit is contained in:
Looly 2023-03-09 22:32:54 +08:00
parent 1a8a97e7b8
commit 0af9f4b5d8
16 changed files with 244 additions and 48 deletions

View File

@ -41,6 +41,12 @@
<version>${bouncycastle.version}</version> <version>${bouncycastle.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.24</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -17,7 +17,7 @@ import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping; import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONDeserializer; import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONString; import cn.hutool.json.serialize.JSONStringer;
import cn.hutool.json.writer.GlobalValueWriterMapping; import cn.hutool.json.writer.GlobalValueWriterMapping;
import cn.hutool.json.writer.JSONValueWriter; import cn.hutool.json.writer.JSONValueWriter;
@ -63,7 +63,7 @@ public final class InternalJSONUtil {
} }
if (object instanceof JSON // if (object instanceof JSON //
|| object instanceof JSONString // || object instanceof JSONStringer //
|| object instanceof CharSequence // || object instanceof CharSequence //
|| object instanceof Number // || object instanceof Number //
|| ObjUtil.isBasicType(object) // || ObjUtil.isBasicType(object) //
@ -117,8 +117,8 @@ public final class InternalJSONUtil {
/** /**
* 值转为String用于JSON中规则为 * 值转为String用于JSON中规则为
* <ul> * <ul>
* <li>对象如果实现了{@link JSONString}接口调用{@link JSONString#toJSONString()}方法</li> * <li>对象如果实现了{@link JSONStringer}接口调用{@link JSONStringer#toJSONString()}方法</li>
* <li>对象如果实现了{@link JSONString}接口调用{@link JSONString#toJSONString()}方法</li> * <li>对象如果实现了{@link JSONStringer}接口调用{@link JSONStringer#toJSONString()}方法</li>
* <li>对象如果是数组或Collection包装为{@link JSONArray}</li> * <li>对象如果是数组或Collection包装为{@link JSONArray}</li>
* <li>对象如果是Map包装为{@link JSONObject}</li> * <li>对象如果是Map包装为{@link JSONObject}</li>
* <li>对象如果是数字使用{@link NumberUtil#toStr(Number)}转换为字符串</li> * <li>对象如果是数字使用{@link NumberUtil#toStr(Number)}转换为字符串</li>
@ -133,9 +133,9 @@ public final class InternalJSONUtil {
if (value == null) { if (value == null) {
return StrUtil.NULL; return StrUtil.NULL;
} }
if (value instanceof JSONString) { if (value instanceof JSONStringer) {
try { try {
return ((JSONString) value).toJSONString(); return ((JSONStringer) value).toJSONString();
} catch (final Exception e) { } catch (final Exception e) {
throw new JSONException(e); throw new JSONException(e);
} }

View File

@ -0,0 +1,81 @@
package cn.hutool.json;
import cn.hutool.core.lang.mutable.MutableEntry;
import cn.hutool.core.math.NumberUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Predicate;
/**
* JSON数字表示
*
* @author looly
* @since 6.0.0
*/
public class JSONNumber extends Number implements JSON {
private static final long serialVersionUID = 1L;
private final Number value;
/**
* 配置项
*/
private final JSONConfig config;
/**
* 构造
*
* @param value
* @param config JSON配置
*/
public JSONNumber(final Number value, final JSONConfig config) {
this.value = value;
this.config = config;
}
@Override
public JSONConfig getConfig() {
return this.config;
}
@Override
public int size() {
return 1;
}
@Override
public Writer write(final Writer writer, final int indentFactor, final int indent,
final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
try {
writer.write(toString());
} catch (final IOException e) {
throw new RuntimeException(e);
}
return writer;
}
@Override
public int intValue() {
return this.value.intValue();
}
@Override
public long longValue() {
return this.value.longValue();
}
@Override
public float floatValue() {
return this.value.floatValue();
}
@Override
public double doubleValue() {
return this.value.doubleValue();
}
@Override
public String toString() {
return NumberUtil.toStr(this.value);
}
}

View File

@ -0,0 +1,76 @@
package cn.hutool.json;
import cn.hutool.core.lang.mutable.MutableEntry;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Predicate;
/**
* JSON字符串表示一个字符串
*
* @author looly
* @since 6.0.0
*/
public class JSONString implements JSON, CharSequence {
private static final long serialVersionUID = 1L;
private final char[] value;
/**
* 配置项
*/
private final JSONConfig config;
/**
* 构造
*
* @param value char数组
* @param config 配置项
*/
public JSONString(final char[] value, final JSONConfig config) {
this.value = value;
this.config = config;
}
@Override
public JSONConfig getConfig() {
return this.config;
}
@Override
public int size() {
return length();
}
@Override
public Writer write(final Writer writer, final int indentFactor, final int indent,
final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
try {
writer.write(this.value);
} catch (final IOException e) {
throw new RuntimeException(e);
}
return writer;
}
@Override
public int length() {
return this.value.length;
}
@Override
public char charAt(final int index) {
return this.value[index];
}
@Override
public CharSequence subSequence(final int start, final int end) {
return ((start == 0) && (end == this.value.length)) ? this
: new String(this.value, start, end);
}
@Override
public String toString() {
return String.valueOf(this.value);
}
}

View File

@ -2,7 +2,7 @@ package cn.hutool.json;
import cn.hutool.core.bean.copier.BeanCopier; import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.json.serialize.JSONDeserializer; import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONString; import cn.hutool.json.serialize.JSONStringer;
/** /**
* JSON支持<br> * JSON支持<br>
@ -10,7 +10,7 @@ import cn.hutool.json.serialize.JSONString;
* *
* @author Looly * @author Looly
*/ */
public class JSONSupport implements JSONString, JSONDeserializer<Object> { public class JSONSupport implements JSONStringer, JSONDeserializer<Object> {
/** /**
* JSON String转Bean * JSON String转Bean

View File

@ -12,20 +12,15 @@ import cn.hutool.core.convert.impl.DateConverter;
import cn.hutool.core.convert.impl.MapConverter; import cn.hutool.core.convert.impl.MapConverter;
import cn.hutool.core.convert.impl.TemporalAccessorConverter; import cn.hutool.core.convert.impl.TemporalAccessorConverter;
import cn.hutool.core.map.MapWrapper; import cn.hutool.core.map.MapWrapper;
import cn.hutool.core.math.NumberUtil;
import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.reflect.TypeUtil; import cn.hutool.core.reflect.TypeUtil;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.InternalJSONUtil; import cn.hutool.json.*;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.serialize.JSONDeserializer; import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONString; import cn.hutool.json.serialize.JSONStringer;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
@ -81,9 +76,9 @@ public class JSONConverter implements Converter {
if (null == value) { if (null == value) {
return null; return null;
} }
if (value instanceof JSONString) { if (value instanceof JSONStringer) {
// 被JSONString包装的对象获取其原始类型 // 被JSONString包装的对象获取其原始类型
value = ((JSONString) value).getRaw(); value = ((JSONStringer) value).getRaw();
} }
// JSON转对象 // JSON转对象
@ -131,7 +126,20 @@ public class JSONConverter implements Converter {
json = (JSON) obj; json = (JSON) obj;
} else if (obj instanceof CharSequence) { } else if (obj instanceof CharSequence) {
final String jsonStr = StrUtil.trim((CharSequence) obj); final String jsonStr = StrUtil.trim((CharSequence) obj);
json = JSONUtil.isTypeJSONArray(jsonStr) ? new JSONArray(jsonStr, config) : new JSONObject(jsonStr, config); switch (jsonStr.charAt(0)){
case '"':
case '\'':
return new JSONString(jsonStr.toCharArray(), config);
case '[':
return new JSONArray(jsonStr, config);
case '{':
return new JSONObject(jsonStr, config);
default:
if(NumberUtil.isNumber(jsonStr)){
return new JSONNumber(NumberUtil.toBigDecimal(jsonStr), config);
}
throw new JSONException("Unsupported String to JSON: {}", jsonStr);
}
} else if (obj instanceof MapWrapper) { } else if (obj instanceof MapWrapper) {
// MapWrapper实现了Iterable会被当作JSONArray此处做修正 // MapWrapper实现了Iterable会被当作JSONArray此处做修正
json = new JSONObject(obj, config); json = new JSONObject(obj, config);

View File

@ -20,7 +20,7 @@ import java.util.Date;
* @author looly * @author looly
* @since 6.0.0 * @since 6.0.0
*/ */
public class DateJSONString implements JSONString { public class DateJSONString implements JSONStringer {
final Object dateObj; final Object dateObj;
final JSONConfig jsonConfig; final JSONConfig jsonConfig;

View File

@ -10,7 +10,7 @@ import cn.hutool.core.lang.func.Wrapper;
* *
*/ */
@FunctionalInterface @FunctionalInterface
public interface JSONString extends Wrapper<Object> { public interface JSONStringer extends Wrapper<Object> {
/** /**
* 自定义转JSON字符串的方法 * 自定义转JSON字符串的方法

View File

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

View File

@ -8,7 +8,7 @@ import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.InternalJSONUtil; import cn.hutool.json.InternalJSONUtil;
import cn.hutool.json.JSON; import cn.hutool.json.JSON;
import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONConfig;
import cn.hutool.json.serialize.JSONString; import cn.hutool.json.serialize.JSONStringer;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
@ -321,8 +321,8 @@ public class JSONWriter extends Writer {
DateValueWriter.INSTANCE.write(this, value); DateValueWriter.INSTANCE.write(this, value);
} else if (value instanceof Boolean) { } else if (value instanceof Boolean) {
BooleanValueWriter.INSTANCE.write(this, (Boolean) value); BooleanValueWriter.INSTANCE.write(this, (Boolean) value);
} else if (value instanceof JSONString) { } else if (value instanceof JSONStringer) {
JSONStringValueWriter.INSTANCE.write(this, (JSONString) value); JSONStringValueWriter.INSTANCE.write(this, (JSONStringer) value);
} else { } else {
writeQuoteStrValue(value.toString()); writeQuoteStrValue(value.toString());
} }

View File

@ -0,0 +1,34 @@
package cn.hutool.json;
import org.junit.Assert;
import org.junit.Test;
public class IssueI6LBZATest {
@Test
public void parseJSONStringTest() {
final String a = "\"a\"";
final JSON parse = JSONUtil.parse(a);
Assert.assertEquals(JSONString.class, parse.getClass());
}
@Test
public void parseJSONStringTest2() {
final String a = "'a'";
final JSON parse = JSONUtil.parse(a);
Assert.assertEquals(JSONString.class, parse.getClass());
}
@Test(expected = JSONException.class)
public void parseJSONErrorTest() {
final String a = "a";
final JSON parse = JSONUtil.parse(a);
Assert.assertEquals(JSONString.class, parse.getClass());
}
@Test
public void parseJSONNumberTest() {
final String a = "123";
final JSON parse = JSONUtil.parse(a);
Assert.assertEquals(JSONNumber.class, parse.getClass());
}
}

View File

@ -4,7 +4,7 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.math.NumberUtil; import cn.hutool.core.math.NumberUtil;
import cn.hutool.json.serialize.JSONString; import cn.hutool.json.serialize.JSONStringer;
import cn.hutool.json.test.bean.Price; import cn.hutool.json.test.bean.Price;
import cn.hutool.json.test.bean.UserA; import cn.hutool.json.test.bean.UserA;
import cn.hutool.json.test.bean.UserC; import cn.hutool.json.test.bean.UserC;
@ -179,7 +179,7 @@ public class JSONUtilTest {
@Test @Test
public void customValueTest() { public void customValueTest() {
final JSONObject jsonObject = JSONUtil.ofObj() final JSONObject jsonObject = JSONUtil.ofObj()
.set("test2", (JSONString) () -> NumberUtil.format("#.0", 12.00D)); .set("test2", (JSONStringer) () -> NumberUtil.format("#.0", 12.00D));
Assert.assertEquals("{\"test2\":12.0}", jsonObject.toString()); Assert.assertEquals("{\"test2\":12.0}", jsonObject.toString());
} }

View File

@ -1,7 +1,5 @@
package cn.hutool.log.test; package cn.hutool.log;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.log.dialect.commons.ApacheCommonsLogFactory; import cn.hutool.log.dialect.commons.ApacheCommonsLogFactory;
import cn.hutool.log.dialect.console.ConsoleLogFactory; import cn.hutool.log.dialect.console.ConsoleLogFactory;
import cn.hutool.log.dialect.jboss.JbossLogFactory; import cn.hutool.log.dialect.jboss.JbossLogFactory;

View File

@ -1,12 +1,9 @@
package cn.hutool.log.test; package cn.hutool.log;
import cn.hutool.log.level.Level;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.log.level.Level;
/** /**
* 日志门面单元测试 * 日志门面单元测试
* @author Looly * @author Looly

View File

@ -1,7 +1,5 @@
package cn.hutool.log.test; package cn.hutool.log;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.log.dialect.logtube.LogTubeLogFactory; import cn.hutool.log.dialect.logtube.LogTubeLogFactory;
import org.junit.Test; import org.junit.Test;

View File

@ -1,7 +1,5 @@
package cn.hutool.log.test; package cn.hutool.log;
import cn.hutool.log.LogFactory;
import cn.hutool.log.StaticLog;
import cn.hutool.log.dialect.console.ConsoleColorLogFactory; import cn.hutool.log.dialect.console.ConsoleColorLogFactory;
import cn.hutool.log.dialect.console.ConsoleLogFactory; import cn.hutool.log.dialect.console.ConsoleLogFactory;
import org.junit.Test; import org.junit.Test;