diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/UTF8OutputStreamWriter.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/UTF8OutputStreamWriter.java
new file mode 100644
index 000000000..ae53435f4
--- /dev/null
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/UTF8OutputStreamWriter.java
@@ -0,0 +1,160 @@
+/*
+ * 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.core.io.stream;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ *
This class is used to write a stream of chars as a stream of
+ * bytes using the UTF8 encoding. It assumes that the underlying
+ * output stream is buffered or does not need additional buffering.
+ *
+ * It is more efficient than using a {@link java.io.OutputStreamWriter}
+ * because it does not need to be wrapped in a
+ * {@link java.io.BufferedWriter}. Creating multiple instances
+ * of {@link java.io.BufferedWriter} has been shown to be very expensive.
+ *
+ * copy from: {@code com.sun.xml.internal.stream.writers.UTF8OutputStreamWriter}
+ *
+ * @author Santiago.PericasGeertsen@sun.com
+ */
+public class UTF8OutputStreamWriter extends Writer {
+
+ /**
+ * Undelying output stream. This class assumes that this
+ * output stream does not need buffering.
+ */
+ private final OutputStream out;
+
+ /**
+ * Java represents chars that are not in the Basic Multilingual
+ * Plane (BMP) in UTF-16. This int stores the first code unit
+ * for a code point encoded in two UTF-16 code units.
+ */
+ int lastUTF16CodePoint = 0;
+
+ /**
+ * Creates a new UTF8OutputStreamWriter.
+ *
+ * @param out The underlying output stream.
+ */
+ public UTF8OutputStreamWriter(final OutputStream out) {
+ this.out = out;
+ }
+
+ @Override
+ public void write(final int c) throws IOException {
+ // Check in we are encoding at high and low surrogates
+ if (lastUTF16CodePoint != 0) {
+ final int uc =
+ (((lastUTF16CodePoint & 0x3ff) << 10) | (c & 0x3ff)) + 0x10000;
+
+ out.write(0xF0 | (uc >> 18));
+ out.write(0x80 | ((uc >> 12) & 0x3F));
+ out.write(0x80 | ((uc >> 6) & 0x3F));
+ out.write(0x80 | (uc & 0x3F));
+
+ lastUTF16CodePoint = 0;
+ return;
+ }
+
+ // Otherwise, encode char as defined in UTF-8
+ if (c < 0x80) {
+ // 1 byte, 7 bits
+ out.write((int) c);
+ } else if (c < 0x800) {
+ // 2 bytes, 11 bits
+ out.write(0xC0 | (c >> 6)); // first 5
+ out.write(0x80 | (c & 0x3F)); // second 6
+ } else if (c <= '\uFFFF') {
+ if (!isHighSurrogate(c) && !isLowSurrogate(c)) {
+ // 3 bytes, 16 bits
+ out.write(0xE0 | (c >> 12)); // first 4
+ out.write(0x80 | ((c >> 6) & 0x3F)); // second 6
+ out.write(0x80 | (c & 0x3F)); // third 6
+ } else {
+ lastUTF16CodePoint = c;
+ }
+ }
+ }
+
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ @Override
+ public void write(final char[] cbuf) throws IOException {
+ for (int i = 0; i < cbuf.length; i++) {
+ write(cbuf[i]);
+ }
+ }
+
+ @Override
+ public void write(final char[] cbuf, final int off, final int len) throws IOException {
+ for (int i = 0; i < len; i++) {
+ write(cbuf[off + i]);
+ }
+ }
+
+ @Override
+ public void write(final String str) throws IOException {
+ final int len = str.length();
+ for (int i = 0; i < len; i++) {
+ write(str.charAt(i));
+ }
+ }
+
+ @Override
+ public void write(final String str, final int off, final int len) throws IOException {
+ for (int i = 0; i < len; i++) {
+ write(str.charAt(off + i));
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (lastUTF16CodePoint != 0) {
+ throw new IllegalStateException("Attempting to close a UTF8OutputStreamWriter"
+ + " while awaiting for a UTF-16 code unit");
+ }
+ out.close();
+ }
+
+ /**
+ * Returns whether the given character is a high surrogate
+ *
+ * @param c The character to check.
+ * @return true if the character is a high surrogate.
+ */
+ private static boolean isHighSurrogate(final int c) {
+ return (0xD800 <= c && c <= 0xDBFF);
+ }
+
+ /**
+ * Returns whether the given character is a low surrogate
+ *
+ * @param c The character to check.
+ * @return true if the character is a low surrogate.
+ */
+ private static boolean isLowSurrogate(final int c) {
+ return (0xDC00 <= c && c <= 0xDFFF);
+ }
+}
diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml
index e0aa29f23..cf24ecc3c 100755
--- a/hutool-json/pom.xml
+++ b/hutool-json/pom.xml
@@ -140,7 +140,6 @@
src/test/jmh
- my-resources
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java
index 4ccff81d1..b9def36f0 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java
@@ -16,13 +16,14 @@
package org.dromara.hutool.json.engine;
+import org.dromara.hutool.core.io.stream.UTF8OutputStreamWriter;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.JSON;
import org.dromara.hutool.json.JSONConfig;
import org.dromara.hutool.json.JSONFactory;
+import java.io.OutputStream;
import java.io.Reader;
-import java.io.Writer;
import java.lang.reflect.Type;
/**
@@ -36,13 +37,21 @@ public class HutoolJSONEngine extends AbstractJSONEngine {
private JSONFactory jsonFactory;
@Override
- public void serialize(final Object bean, final Writer writer) {
+ public void serialize(final Object bean, final OutputStream out) {
initEngine();
final JSON json = jsonFactory.parse(bean);
- json.write(jsonFactory.ofWriter(writer,
+ json.write(jsonFactory.ofWriter(new UTF8OutputStreamWriter(out),
ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)));
}
+ @Override
+ public String toJsonString(final Object bean) {
+ initEngine();
+ final JSON json = jsonFactory.parse(bean);
+ final boolean isPrettyPrint = ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false);
+ return isPrettyPrint ? json.toStringPretty() : json.toString();
+ }
+
@Override
public T deserialize(final Reader reader, final Object type) {
initEngine();
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/JSONEngine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/JSONEngine.java
index 6398c3a64..3da51ae5b 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/JSONEngine.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/JSONEngine.java
@@ -16,10 +16,10 @@
package org.dromara.hutool.json.engine;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
+import org.dromara.hutool.core.io.stream.FastByteArrayOutputStream;
+import org.dromara.hutool.core.util.CharsetUtil;
+
+import java.io.*;
/**
* JSON引擎实现
@@ -43,9 +43,9 @@ public interface JSONEngine {
* 生成JSON数据(序列化),用于将指定的Bean对象通过Writer写出为JSON字符串
*
* @param bean Java Bean(POJO)对象
- * @param writer 写出到的Writer
+ * @param out 写出到的{@link OutputStream}
*/
- void serialize(Object bean, Writer writer);
+ void serialize(Object bean, OutputStream out);
/**
* 解析JSON数据(反序列化),用于从Reader中读取JSON字符串,转换为Bean对象
@@ -65,9 +65,9 @@ public interface JSONEngine {
* @return JSON字符串
*/
default String toJsonString(final Object bean) {
- final StringWriter stringWriter = new StringWriter();
- serialize(bean, stringWriter);
- return stringWriter.toString();
+ final FastByteArrayOutputStream out = new FastByteArrayOutputStream();
+ serialize(bean, out);
+ return out.toString(CharsetUtil.UTF_8);
}
/**
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/fastjson/FastJSON2Engine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/fastjson/FastJSON2Engine.java
index 1e2b80cce..67426272b 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/fastjson/FastJSON2Engine.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/fastjson/FastJSON2Engine.java
@@ -22,13 +22,16 @@ import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.writer.ObjectWriter;
import org.dromara.hutool.core.collection.ListUtil;
+import org.dromara.hutool.core.io.IORuntimeException;
+import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.engine.AbstractJSONEngine;
import org.dromara.hutool.json.engine.JSONEngineConfig;
+import java.io.IOException;
+import java.io.OutputStream;
import java.io.Reader;
-import java.io.Writer;
import java.lang.reflect.Type;
import java.util.List;
@@ -53,19 +56,26 @@ public class FastJSON2Engine extends AbstractJSONEngine {
}
@Override
- public void serialize(final Object bean, final Writer writer) {
- initEngine();
- try (final JSONWriter jsonWriter = JSONWriter.of(this.writerContext)) {
- if (bean == null) {
- jsonWriter.writeNull();
- } else {
- jsonWriter.setRootObject(bean);
- final Class> valueClass = bean.getClass();
- final ObjectWriter> objectWriter = this.writerContext.getObjectWriter(valueClass, valueClass);
- objectWriter.write(jsonWriter, bean, null, null, 0);
- }
+ public void serialize(final Object bean, final OutputStream out) {
+ JSONWriter jsonWriter = null;
+ try{
+ jsonWriter = toJsonWriter(bean);
+ jsonWriter.flushTo(out);
+ } catch (final IOException e){
+ throw new IORuntimeException(e);
+ } finally {
+ IoUtil.closeQuietly(jsonWriter);
+ }
+ }
- jsonWriter.flushTo(writer);
+ @Override
+ public String toJsonString(final Object bean) {
+ JSONWriter jsonWriter = null;
+ try{
+ jsonWriter = toJsonWriter(bean);
+ return jsonWriter.toString();
+ } finally {
+ IoUtil.closeQuietly(jsonWriter);
}
}
@@ -116,4 +126,26 @@ public class FastJSON2Engine extends AbstractJSONEngine {
this.writerContext.setDateFormat(ObjUtil.defaultIfNull(config.getDateFormat(), "millis"));
}
}
+
+ /**
+ * 将对象转为JSONWriter
+ *
+ * @param bean 对象
+ * @return JSONWriter
+ */
+ private JSONWriter toJsonWriter(final Object bean) {
+ initEngine();
+
+ final JSONWriter jsonWriter = JSONWriter.of(this.writerContext);
+ if (bean == null) {
+ jsonWriter.writeNull();
+ } else {
+ jsonWriter.setRootObject(bean);
+ final Class> valueClass = bean.getClass();
+ final ObjectWriter> objectWriter = this.writerContext.getObjectWriter(valueClass, valueClass);
+ objectWriter.write(jsonWriter, bean, null, null, 0);
+ }
+
+ return jsonWriter;
+ }
}
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/GsonEngine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/GsonEngine.java
index f0adab467..f6d6de0d1 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/GsonEngine.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/GsonEngine.java
@@ -18,6 +18,7 @@ package org.dromara.hutool.json.engine.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import org.dromara.hutool.core.io.stream.UTF8OutputStreamWriter;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.wrapper.Wrapper;
import org.dromara.hutool.core.util.ObjUtil;
@@ -25,8 +26,8 @@ import org.dromara.hutool.json.JSONException;
import org.dromara.hutool.json.engine.AbstractJSONEngine;
import org.dromara.hutool.json.engine.JSONEngineConfig;
+import java.io.OutputStream;
import java.io.Reader;
-import java.io.Writer;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -60,9 +61,15 @@ public class GsonEngine extends AbstractJSONEngine implements Wrapper {
}
@Override
- public void serialize(final Object bean, final Writer writer) {
+ public void serialize(final Object bean, final OutputStream out) {
initEngine();
- gson.toJson(bean, writer);
+ gson.toJson(bean, new UTF8OutputStreamWriter(out));
+ }
+
+ @Override
+ public String toJsonString(final Object bean) {
+ initEngine();
+ return gson.toJson(bean);
}
@SuppressWarnings("unchecked")
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/jackson/JacksonEngine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/jackson/JacksonEngine.java
index e1f2c9506..50aee205c 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/jackson/JacksonEngine.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/jackson/JacksonEngine.java
@@ -35,8 +35,8 @@ import org.dromara.hutool.json.engine.AbstractJSONEngine;
import org.dromara.hutool.json.engine.JSONEngineConfig;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.Reader;
-import java.io.Writer;
/**
* Jackson引擎
@@ -68,10 +68,20 @@ public class JacksonEngine extends AbstractJSONEngine implements Wrapper {
}else{
jsonWriter.value(DateUtil.format(date, dateFormat));
}
- jsonWriter.flush();
}
@Override
public Date fromJson(final JsonReader jsonReader) throws IOException {
+ if(jsonReader.peek() == JsonReader.Token.NULL){
+ return jsonReader.nextNull();
+ }
+
return StrUtil.isEmpty(dateFormat) ?
DateUtil.date(jsonReader.nextLong()) :
DateUtil.parse(jsonReader.nextString(), dateFormat);
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/MoshiEngine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/MoshiEngine.java
index a26b81630..04ede274a 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/MoshiEngine.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/MoshiEngine.java
@@ -22,7 +22,6 @@ import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import org.dromara.hutool.core.io.stream.ReaderInputStream;
-import org.dromara.hutool.core.io.stream.WriterOutputStream;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.wrapper.Wrapper;
import org.dromara.hutool.core.util.CharsetUtil;
@@ -32,8 +31,8 @@ import org.dromara.hutool.json.engine.AbstractJSONEngine;
import org.dromara.hutool.json.engine.JSONEngineConfig;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.Reader;
-import java.io.Writer;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -64,27 +63,22 @@ public class MoshiEngine extends AbstractJSONEngine implements Wrapper {
return this.moshi;
}
- @SuppressWarnings("unchecked")
@Override
- public void serialize(final Object bean, final Writer writer) {
- initEngine();
- final BufferedSink sink = Okio.buffer(Okio.sink(new WriterOutputStream(writer, CharsetUtil.UTF_8)));
- JsonAdapter adapter = (JsonAdapter) this.moshi.adapter(bean.getClass());
-
- if(ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)){
- adapter = adapter.indent(" ");
- }
- if(!ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isIgnoreNullValue, true)){
- adapter = adapter.serializeNulls();
- }
-
+ public void serialize(final Object bean, final OutputStream out) {
+ final BufferedSink sink = Okio.buffer(Okio.sink(out));
try {
- adapter.toJson(sink, bean);
+ getAdapter(this.moshi, bean.getClass()).toJson(sink, bean);
} catch (final IOException e) {
throw new JSONException(e);
}
}
+ @Override
+ public String toJsonString(final Object bean) {
+ final JsonAdapter adapter = getAdapter(this.moshi, bean.getClass());
+ return adapter.toJson(bean);
+ }
+
@SuppressWarnings("unchecked")
@Override
public T deserialize(final Reader reader, final Object type) {
@@ -120,13 +114,32 @@ public class MoshiEngine extends AbstractJSONEngine implements Wrapper {
this.moshi = builder.build();
}
+ /**
+ * 获取并配置{@link JsonAdapter}
+ *
+ * @param moshi {@link Moshi}
+ * @param type Bean类型
+ * @return this
+ */
+ private JsonAdapter getAdapter(final Moshi moshi, final Type type) {
+ initEngine();
+ JsonAdapter adapter = this.moshi.adapter(type);
+ if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
+ adapter = adapter.indent(" ");
+ }
+ if (!ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isIgnoreNullValue, true)) {
+ adapter = adapter.serializeNulls();
+ }
+ return adapter;
+ }
+
/**
* 注册日期相关序列化描述
*
- * @param builder Gson构造器
+ * @param builder Gson构造器
* @param dateFormat 日期格式
*/
- private void registerDate(final Moshi.Builder builder, final String dateFormat){
+ private void registerDate(final Moshi.Builder builder, final String dateFormat) {
builder.add(DateMoshiAdapter.createFactory(dateFormat));
builder.add(LocalDateTime.class, new TemporalMoshiAdapter(LocalDateTime.class, dateFormat));
builder.add(LocalDate.class, new TemporalMoshiAdapter(LocalDate.class, dateFormat));
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TemporalMoshiAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TemporalMoshiAdapter.java
index 96f5ee0db..6f121d4b8 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TemporalMoshiAdapter.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TemporalMoshiAdapter.java
@@ -60,11 +60,13 @@ public class TemporalMoshiAdapter extends JsonAdapter {
} else {
jsonWriter.value(TimeUtil.format(src, dateFormat));
}
- jsonWriter.flush();
}
@Override
public TemporalAccessor fromJson(final JsonReader jsonReader) throws IOException {
+ if(jsonReader.peek() == JsonReader.Token.NULL){
+ return jsonReader.nextNull();
+ }
return StrUtil.isEmpty(dateFormat) ?
ConvertUtil.convert(this.type, jsonReader.nextLong()) :
ConvertUtil.convert(this.type, TimeUtil.parse(jsonReader.nextString(), dateFormat));
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TimeZoneMoshiAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TimeZoneMoshiAdapter.java
index c1dd268db..176cff3b3 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TimeZoneMoshiAdapter.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/TimeZoneMoshiAdapter.java
@@ -60,7 +60,6 @@ public class TimeZoneMoshiAdapter extends JsonAdapter {
return;
}
jsonWriter.value(timeZone.getID());
- jsonWriter.flush();
}
@Override
diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/engine/BeanWithLocalDateTime.java b/hutool-json/src/test/java/org/dromara/hutool/json/engine/BeanWithLocalDateTime.java
new file mode 100644
index 000000000..15812acc8
--- /dev/null
+++ b/hutool-json/src/test/java/org/dromara/hutool/json/engine/BeanWithLocalDateTime.java
@@ -0,0 +1,28 @@
+/*
+ * 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.engine;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+public class BeanWithLocalDateTime {
+ private LocalDateTime date;
+}
diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/engine/JSONEngineFactoryTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/engine/JSONEngineFactoryTest.java
index fe033025e..4a87441be 100644
--- a/hutool-json/src/test/java/org/dromara/hutool/json/engine/JSONEngineFactoryTest.java
+++ b/hutool-json/src/test/java/org/dromara/hutool/json/engine/JSONEngineFactoryTest.java
@@ -26,7 +26,6 @@ import org.dromara.hutool.json.engine.jackson.JacksonEngine;
import org.junit.jupiter.api.Test;
import java.io.StringReader;
-import java.io.StringWriter;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -72,12 +71,10 @@ public class JSONEngineFactoryTest {
final JSONEngine engine = JSONEngineFactory.createEngine("gson");
assertEquals(GsonEngine.class, engine.getClass());
- final StringWriter stringWriter = new StringWriter();
final TestBean testBean = new TestBean("张三", 18, true);
- engine.serialize(testBean, stringWriter);
final String jsonStr = "{\"name\":\"张三\",\"age\":18,\"gender\":true}";
- assertEquals(jsonStr, stringWriter.toString());
+ assertEquals(jsonStr, engine.toJsonString(testBean));
final TestBean testBean1 = engine.deserialize(new StringReader(jsonStr), TestBean.class);
assertEquals(testBean, testBean1);
@@ -88,12 +85,10 @@ public class JSONEngineFactoryTest {
final JSONEngine engine = JSONEngineFactory.createEngine("fastjson");
assertEquals(FastJSON2Engine.class, engine.getClass());
- final StringWriter stringWriter = new StringWriter();
final TestBean testBean = new TestBean("张三", 18, true);
- engine.serialize(testBean, stringWriter);
final String jsonStr = "{\"name\":\"张三\",\"age\":18,\"gender\":true}";
- assertEquals(jsonStr, stringWriter.toString());
+ assertEquals(jsonStr, engine.toJsonString(testBean));
final TestBean testBean1 = engine.deserialize(new StringReader(jsonStr), TestBean.class);
assertEquals(testBean, testBean1);
@@ -104,12 +99,10 @@ public class JSONEngineFactoryTest {
final JSONEngine engine = JSONEngineFactory.createEngine("hutoolJSON");
assertEquals(HutoolJSONEngine.class, engine.getClass());
- final StringWriter stringWriter = new StringWriter();
final TestBean testBean = new TestBean("张三", 18, true);
- engine.serialize(testBean, stringWriter);
final String jsonStr = "{\"name\":\"张三\",\"age\":18,\"gender\":true}";
- assertEquals(jsonStr, stringWriter.toString());
+ assertEquals(jsonStr, engine.toJsonString(testBean));
final TestBean testBean1 = engine.deserialize(new StringReader(jsonStr), TestBean.class);
assertEquals(testBean, testBean1);
diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/engine/MoshiTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/engine/MoshiTest.java
new file mode 100644
index 000000000..0eed36469
--- /dev/null
+++ b/hutool-json/src/test/java/org/dromara/hutool/json/engine/MoshiTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.engine;
+
+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.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class MoshiTest {
+
+ @Test
+ void writeLocalDateFormatTest() {
+ final DateTime date = DateUtil.parse("2024-01-01 01:12:21");
+ final BeanWithLocalDateTime bean = new BeanWithLocalDateTime(TimeUtil.of(date));
+ final JSONEngine engine = JSONEngineFactory.createEngine("moshi");
+
+ final String jsonString = engine.toJsonString(bean);
+ Assertions.assertEquals("{\"date\":1704042741000}", jsonString);
+
+ engine.init(JSONEngineConfig.of().setDateFormat("yyyy-MM-dd HH:mm:ss"));
+ Assertions.assertEquals("{\"date\":\"2024-01-01 01:12:21\"}", engine.toJsonString(bean));
+ }
+}
diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/CustomSerializeTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/serializer/CustomSerializeTest.java
similarity index 91%
rename from hutool-json/src/test/java/org/dromara/hutool/json/CustomSerializeTest.java
rename to hutool-json/src/test/java/org/dromara/hutool/json/serializer/CustomSerializeTest.java
index 7e7f20813..170519978 100644
--- a/hutool-json/src/test/java/org/dromara/hutool/json/CustomSerializeTest.java
+++ b/hutool-json/src/test/java/org/dromara/hutool/json/serializer/CustomSerializeTest.java
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-package org.dromara.hutool.json;
+package org.dromara.hutool.json.serializer;
import lombok.ToString;
-import org.dromara.hutool.json.serializer.JSONDeserializer;
-import org.dromara.hutool.json.serializer.JSONSerializer;
-import org.dromara.hutool.json.serializer.TypeAdapterManager;
+import org.dromara.hutool.json.JSONObject;
+import org.dromara.hutool.json.JSONUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;