mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix test
This commit is contained in:
parent
e54c0b26f6
commit
ea56cc567c
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.lang.Assert;
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
|
||||
/**
|
||||
* JSON格式化风格,用于格式化JSON字符串
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JSONFormatStyle {
|
||||
|
||||
/**
|
||||
* 获取格式化风格
|
||||
*
|
||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
||||
* @return JSONFormatStyle
|
||||
*/
|
||||
public static JSONFormatStyle getStyle(final int indentFactor){
|
||||
if(0 == indentFactor){
|
||||
return JSONFormatStyle.COMPACT;
|
||||
} else if(2 == indentFactor){
|
||||
return JSONFormatStyle.PRETTY;
|
||||
}
|
||||
return new JSONFormatStyle("\n", StrUtil.repeat(CharUtil.SPACE, indentFactor), indentFactor > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认紧凑风格:
|
||||
*
|
||||
* <ul>
|
||||
* <li>无换行</li>
|
||||
* <li>无缩进</li>
|
||||
* <li>{@code ','} 和 {@code ':'}后无空格</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static final JSONFormatStyle COMPACT = new JSONFormatStyle("", "", false);
|
||||
|
||||
/**
|
||||
* 默认格式化风格:
|
||||
*
|
||||
* <ul>
|
||||
* <li>换行符:{@code "\n"}</li>
|
||||
* <li>双空格缩进</li>
|
||||
* <li>{@code ','} 和 {@code ':'}后加空格</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static final JSONFormatStyle PRETTY = new JSONFormatStyle("\n", " ", true);
|
||||
|
||||
/**
|
||||
* 换行符,可以是 "\n" 或 "\r\n"的一个或多个
|
||||
*/
|
||||
private final String newline;
|
||||
/**
|
||||
* 缩进符,如空格、制表符等
|
||||
*/
|
||||
private final String indent;
|
||||
/**
|
||||
* {@code ','} 和 {@code ':'}分隔符后是否加空格,加空格结果如:{"a": 1}
|
||||
*/
|
||||
private final boolean spaceAfterSeparators;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param newline 换行符
|
||||
* @param indent 缩进符
|
||||
* @param spaceAfterSeparators 分隔符后是否加空格
|
||||
*/
|
||||
public JSONFormatStyle(final String newline, final String indent, final boolean spaceAfterSeparators) {
|
||||
this.newline = Assert.notNull(newline);
|
||||
this.indent = Assert.notNull(indent);;
|
||||
this.spaceAfterSeparators = spaceAfterSeparators;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取换行符
|
||||
*
|
||||
* @return 换行符
|
||||
*/
|
||||
public String getNewline() {
|
||||
return newline;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缩进符
|
||||
*
|
||||
* @return 缩进符
|
||||
*/
|
||||
public String getIndent() {
|
||||
return indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分隔符后是否加空格
|
||||
*
|
||||
* @return 分隔符后是否加空格
|
||||
*/
|
||||
public boolean isSpaceAfterSeparators() {
|
||||
return spaceAfterSeparators;
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ import org.dromara.hutool.json.support.InternalJSONUtil;
|
||||
import org.dromara.hutool.json.JSON;
|
||||
import org.dromara.hutool.json.JSONConfig;
|
||||
import org.dromara.hutool.json.JSONException;
|
||||
import org.dromara.hutool.json.support.JSONFormatStyle;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.Flushable;
|
||||
@ -65,17 +66,17 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
*
|
||||
* @param appendable {@link Appendable}
|
||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
||||
* @param indent 本级别缩进量
|
||||
* @param level 层级
|
||||
* @param config JSON选项
|
||||
* @param predicate predicate 字段过滤器
|
||||
* @return JSONWriter
|
||||
*/
|
||||
public static JSONWriter of(final Appendable appendable,
|
||||
final int indentFactor,
|
||||
final int indent,
|
||||
final int level,
|
||||
final JSONConfig config,
|
||||
final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
return new JSONWriter(appendable, indentFactor, indent, config, predicate);
|
||||
return new JSONWriter(appendable, JSONFormatStyle.getStyle(indentFactor), level, config, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,9 +97,9 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
private final JSONConfig config;
|
||||
|
||||
/**
|
||||
* 缩进因子,定义每一级别增加的缩进量
|
||||
* 格式化风格
|
||||
*/
|
||||
private final int indentFactor;
|
||||
private final JSONFormatStyle formatStyle;
|
||||
/**
|
||||
* 键值对过滤器,用于修改键值对
|
||||
*/
|
||||
@ -110,27 +111,27 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
*/
|
||||
private boolean needSeparator;
|
||||
/**
|
||||
* 本级别缩进量
|
||||
* 层级
|
||||
*/
|
||||
private int indent;
|
||||
private int level;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param appendable {@link Appendable}
|
||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
||||
* @param indent 本级别缩进量
|
||||
* @param formatStyle 格式化风格
|
||||
* @param level 层级
|
||||
* @param config JSON选项
|
||||
* @param predicate 字段过滤器
|
||||
*/
|
||||
public JSONWriter(final Appendable appendable,
|
||||
final int indentFactor,
|
||||
final int indent,
|
||||
final JSONFormatStyle formatStyle,
|
||||
final int level,
|
||||
final JSONConfig config,
|
||||
final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||
this.appendable = appendable;
|
||||
this.indentFactor = indentFactor;
|
||||
this.indent = indent;
|
||||
this.formatStyle = formatStyle;
|
||||
this.level = level;
|
||||
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
|
||||
this.predicate = predicate;
|
||||
}
|
||||
@ -153,7 +154,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
public JSONWriter beginObj() {
|
||||
append(CharUtil.DELIM_START);
|
||||
needSeparator = false;
|
||||
indent += indentFactor;
|
||||
level += 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -175,7 +176,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
public JSONWriter beginArray() {
|
||||
append(CharUtil.BRACKET_START);
|
||||
needSeparator = false;
|
||||
indent += indentFactor;
|
||||
level += 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -231,7 +232,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
append(CharUtil.COMMA);
|
||||
}
|
||||
// 换行缩进
|
||||
writeLF().writeSpace(indent);
|
||||
writeNewLine().writeIndent(level);
|
||||
writeQuoteStrValue(key);
|
||||
return this;
|
||||
}
|
||||
@ -271,15 +272,28 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 写出空格
|
||||
* 写出空白字符,默认写出一个空格
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public JSONWriter writeSpaceAfterSeparators() {
|
||||
if (this.formatStyle.isSpaceAfterSeparators()) {
|
||||
return append(CharUtil.SPACE);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写出缩进
|
||||
*
|
||||
* @param count 空格数
|
||||
*/
|
||||
public void writeSpace(final int count) {
|
||||
if (indentFactor > 0) {
|
||||
public void writeIndent(final int count) {
|
||||
final String indentStr = this.formatStyle.getIndent();
|
||||
if (StrUtil.isNotEmpty(indentStr)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
//noinspection resource
|
||||
append(CharUtil.SPACE);
|
||||
append(indentStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -289,10 +303,11 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public JSONWriter writeLF() {
|
||||
if (indentFactor > 0) {
|
||||
public JSONWriter writeNewLine() {
|
||||
final String newline = this.formatStyle.getNewline();
|
||||
if (StrUtil.isNotEmpty(newline)) {
|
||||
//noinspection resource
|
||||
append(CharUtil.LF);
|
||||
append(newline);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -326,16 +341,16 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
final String numberStr = NumberUtil.toStr(number, isStripTrailingZeros);
|
||||
|
||||
// 检查有效性
|
||||
if(!ReUtil.isMatch(JSON_NUMBER_PATTERN, numberStr)){
|
||||
if (!ReUtil.isMatch(JSON_NUMBER_PATTERN, numberStr)) {
|
||||
throw new JSONException("Invalid RFC8259 JSON format number: " + numberStr);
|
||||
}
|
||||
|
||||
final NumberWriteMode numberWriteMode = (null == config) ? NumberWriteMode.NORMAL : config.getNumberWriteMode();
|
||||
switch (numberWriteMode){
|
||||
switch (numberWriteMode) {
|
||||
case JS:
|
||||
if(number.longValue() > JS_MAX_NUMBER){
|
||||
if (number.longValue() > JS_MAX_NUMBER) {
|
||||
writeQuoteStrValue(numberStr);
|
||||
} else{
|
||||
} else {
|
||||
return writeRaw(numberStr);
|
||||
}
|
||||
break;
|
||||
@ -394,9 +409,9 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
@SuppressWarnings("resource")
|
||||
private JSONWriter end(final boolean arrayMode) {
|
||||
// 结束子缩进
|
||||
indent -= indentFactor;
|
||||
level -= 1;
|
||||
// 换行缩进
|
||||
writeLF().writeSpace(indent);
|
||||
writeNewLine().writeIndent(level);
|
||||
append(arrayMode ? CharUtil.BRACKET_END : CharUtil.DELIM_END);
|
||||
flush();
|
||||
// 当前对象或数组结束,当新的
|
||||
@ -419,10 +434,10 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
||||
}
|
||||
// 换行缩进
|
||||
//noinspection resource
|
||||
writeLF().writeSpace(indent);
|
||||
writeNewLine().writeIndent(level);
|
||||
} else {
|
||||
//noinspection resource
|
||||
append(CharUtil.COLON).writeSpace(1);
|
||||
append(CharUtil.COLON).writeSpaceAfterSeparators();
|
||||
}
|
||||
needSeparator = true;
|
||||
return writeObjValue(value);
|
||||
|
@ -18,6 +18,7 @@ package org.dromara.hutool.json;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.hutool.core.collection.ListUtil;
|
||||
import org.dromara.hutool.core.date.DateTime;
|
||||
import org.dromara.hutool.core.date.DateUtil;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.json.test.bean.Price;
|
||||
@ -144,14 +145,16 @@ public class JSONUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toJsonStrTest() {
|
||||
public void toJsonPrettyStrTest() {
|
||||
final DateTime date = DateUtil.date(1727800929605L);
|
||||
final UserA a1 = new UserA();
|
||||
a1.setA("aaaa");
|
||||
a1.setDate(DateUtil.now());
|
||||
a1.setDate(date);
|
||||
a1.setName("AAAAName");
|
||||
|
||||
final UserA a2 = new UserA();
|
||||
a2.setA("aaaa222");
|
||||
a2.setDate(DateUtil.now());
|
||||
a2.setDate(date);
|
||||
a2.setName("AAAA222Name");
|
||||
|
||||
final ArrayList<UserA> list = ListUtil.of(a1, a2);
|
||||
@ -159,9 +162,22 @@ public class JSONUtilTest {
|
||||
map.put("total", 13);
|
||||
map.put("rows", list);
|
||||
|
||||
final String str = JSONUtil.toJsonPrettyStr(map);
|
||||
JSONUtil.parse(str);
|
||||
Assertions.assertNotNull(str);
|
||||
final String jsonStr = JSONUtil.toJsonPrettyStr(map);
|
||||
Assertions.assertEquals("{\n" +
|
||||
" \"total\": 13,\n" +
|
||||
" \"rows\": [\n" +
|
||||
" {\n" +
|
||||
" \"name\": \"AAAAName\",\n" +
|
||||
" \"a\": \"aaaa\",\n" +
|
||||
" \"date\": 1727800929605\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"name\": \"AAAA222Name\",\n" +
|
||||
" \"a\": \"aaaa222\",\n" +
|
||||
" \"date\": 1727800929605\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}", jsonStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,12 +16,16 @@
|
||||
|
||||
package org.dromara.hutool.json.engine;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.hutool.core.date.DateTime;
|
||||
import org.dromara.hutool.core.date.DateUtil;
|
||||
import org.dromara.hutool.core.date.TimeUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@ -56,6 +60,11 @@ public class JSONEngineTest {
|
||||
Arrays.stream(engineNames).forEach(this::assertEmptyBeanToJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringOrFromStringTest() {
|
||||
Arrays.stream(engineNames).forEach(this::assertToStringOrFromString);
|
||||
}
|
||||
|
||||
private void assertWriteDateFormat(final String engineName) {
|
||||
final DateTime date = DateUtil.parse("2024-01-01 01:12:21");
|
||||
final BeanWithDate bean = new BeanWithDate(date, TimeUtil.of(date));
|
||||
@ -110,8 +119,37 @@ public class JSONEngineTest {
|
||||
assertEquals("{}", jsonString);
|
||||
}
|
||||
|
||||
private void assertToStringOrFromString(final String engineName) {
|
||||
final JSONEngine engine = JSONEngineFactory.createEngine(engineName);
|
||||
final TestBean testBean = new TestBean("张三", 18, true);
|
||||
|
||||
final String jsonStr = "{\"name\":\"张三\",\"age\":18,\"gender\":true}";
|
||||
if("moshi".equals(engineName)){
|
||||
// TODO Moshi无法指定key的顺序
|
||||
assertEquals("{\"age\":18,\"gender\":true,\"name\":\"张三\"}", engine.toJsonString(testBean));
|
||||
}else{
|
||||
assertEquals(jsonStr, engine.toJsonString(testBean));
|
||||
}
|
||||
|
||||
final TestBean testBean1 = engine.deserialize(new StringReader(jsonStr), TestBean.class);
|
||||
assertEquals(testBean, testBean1);
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class EmptyBean{
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
static class TestBean {
|
||||
// 解决输出顺序问题
|
||||
@JSONField(ordinal = 1)
|
||||
private String name;
|
||||
@JSONField(ordinal = 2)
|
||||
private int age;
|
||||
@JSONField(ordinal = 3)
|
||||
private boolean gender;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user