diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/TypeUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/TypeUtil.java
index d63f55082..584358eca 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/TypeUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/TypeUtil.java
@@ -312,7 +312,7 @@ public class TypeUtil {
* @since 4.5.2
*/
public static ParameterizedType toParameterizedType(Type type, final int interfaceIndex) {
- if(type instanceof TypeReference){
+ if (type instanceof TypeReference) {
type = ((TypeReference>) type).getType();
}
@@ -473,6 +473,22 @@ public class TypeUtil {
return parameterizedType;
}
+ /**
+ * 创建泛型对象,例如:
+ *
+ *
{@code
+ * List list = TypeUtil.createParameterizedType(List.class, String.class);
+ * }
+ *
+ * @param rawType 原始类型,例如:List.class
+ * @param actualTypeArguments 实际类型,例如:String.class
+ * @return 泛型对象
+ * @since 6.0.0
+ */
+ public static Type createParameterizedType(final Type rawType, final Type... actualTypeArguments) {
+ return new ParameterizedTypeImpl(actualTypeArguments, null, rawType);
+ }
+
/**
* 获得泛型变量对应的泛型实际类型,如果此变量没有对应的实际类型,返回null
*
diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml
index 2d305599c..e0aa29f23 100755
--- a/hutool-json/pom.xml
+++ b/hutool-json/pom.xml
@@ -38,6 +38,10 @@
1.78.1
0.12.6
2.17.2
+ 2.11.0
+ 2.0.41
+ 1.15.1
+ 1.37
@@ -69,13 +73,19 @@
com.google.code.gson
gson
- 2.11.0
+ ${gson.version}
true
com.alibaba.fastjson2
fastjson2
- 2.0.41
+ ${fastjson2.version}
+ true
+
+
+ com.squareup.moshi
+ moshi
+ 1.15.1
true
@@ -98,6 +108,45 @@
${jjwt.version}
test
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+ test
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+ test
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.6.0
+
+
+ add-jmh-resource
+ generate-test-sources
+
+ add-test-resource
+
+
+
+ src/test/jmh
+ my-resources
+
+
+
+
+
+
+
+
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/DateSerDesc.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/DateGsonTypeAdapter.java
similarity index 89%
rename from hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/DateSerDesc.java
rename to hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/DateGsonTypeAdapter.java
index ce638917c..6dc238ef7 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/DateSerDesc.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/gson/DateGsonTypeAdapter.java
@@ -30,12 +30,12 @@ import java.util.Date;
* @author Looly
* @since 6.0.0
*/
-public class DateSerDesc implements GsonTypeAdapter {
+public class DateGsonTypeAdapter implements GsonTypeAdapter {
/**
* 默认日期格式化描述,默认为null,表示使用时间戳
*/
- public static final DateSerDesc INSTANCE = new DateSerDesc(null);
+ public static final DateGsonTypeAdapter INSTANCE = new DateGsonTypeAdapter(null);
private final String dateFormat;
@@ -44,7 +44,7 @@ public class DateSerDesc implements GsonTypeAdapter {
*
* @param dateFormat 日期格式
*/
- public DateSerDesc(final String dateFormat) {
+ public DateGsonTypeAdapter(final String dateFormat) {
this.dateFormat = dateFormat;
}
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 22abb820c..f0adab467 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
@@ -115,7 +115,7 @@ public class GsonEngine extends AbstractJSONEngine implements Wrapper {
*/
private void registerDate(final GsonBuilder builder, final String dateFormat){
// java date
- builder.registerTypeHierarchyAdapter(Date.class, new DateSerDesc(dateFormat));
+ builder.registerTypeHierarchyAdapter(Date.class, new DateGsonTypeAdapter(dateFormat));
builder.registerTypeHierarchyAdapter(TimeZone.class, TimeZoneGsonTypeAdapter.INSTANCE);
// java.time
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/DateMoshiAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/DateMoshiAdapter.java
new file mode 100644
index 000000000..8baa449b5
--- /dev/null
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/DateMoshiAdapter.java
@@ -0,0 +1,85 @@
+/*
+ * 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.moshi;
+
+import com.squareup.moshi.JsonAdapter;
+import com.squareup.moshi.JsonReader;
+import com.squareup.moshi.JsonWriter;
+import org.dromara.hutool.core.date.DateUtil;
+import org.dromara.hutool.core.reflect.TypeUtil;
+import org.dromara.hutool.core.text.StrUtil;
+
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * 日期格式化适配器,用于moshi序列化与反序列化日期
+ *
+ * @author looly
+ * @since 6.0.0
+ */
+public class DateMoshiAdapter extends JsonAdapter {
+
+ /**
+ * 创建工厂
+ *
+ * @param dateFormat 日期格式
+ * @return 创建工厂
+ */
+ public static Factory createFactory(final String dateFormat){
+ return (type, set, moshi) -> {
+ if(Date.class.isAssignableFrom(TypeUtil.getClass(type))){
+ return new DateMoshiAdapter(dateFormat);
+ }
+
+ return null;
+ };
+ }
+
+ private final String dateFormat;
+
+ /**
+ * 构造
+ *
+ * @param dateFormat 日期格式
+ */
+ public DateMoshiAdapter(final String dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ @Override
+ public void toJson(final JsonWriter jsonWriter, final Date date) throws IOException {
+ if(null == date){
+ jsonWriter.nullValue();
+ return;
+ }
+
+ if(StrUtil.isEmpty(dateFormat)){
+ jsonWriter.value(date.getTime());
+ }else{
+ jsonWriter.value(DateUtil.format(date, dateFormat));
+ }
+ jsonWriter.flush();
+ }
+
+ @Override
+ public Date fromJson(final JsonReader jsonReader) throws IOException {
+ 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
new file mode 100644
index 000000000..a26b81630
--- /dev/null
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/moshi/MoshiEngine.java
@@ -0,0 +1,136 @@
+/*
+ * 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.moshi;
+
+import com.squareup.moshi.JsonAdapter;
+import com.squareup.moshi.Moshi;
+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;
+import org.dromara.hutool.core.util.ObjUtil;
+import org.dromara.hutool.json.JSONException;
+import org.dromara.hutool.json.engine.AbstractJSONEngine;
+import org.dromara.hutool.json.engine.JSONEngineConfig;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.reflect.Type;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+ * Moshi引擎实现
+ *
+ * @author looly
+ * @since 6.0.0
+ */
+public class MoshiEngine extends AbstractJSONEngine implements Wrapper {
+
+ private Moshi moshi;
+
+ /**
+ * 构造
+ */
+ public MoshiEngine() {
+ // issue#IABWBL JDK8下,在IDEA旗舰版加载Spring boot插件时,启动应用不会检查字段类是否存在
+ // 此处构造时调用下这个类,以便触发类是否存在的检查
+ Assert.notNull(Moshi.class);
+ }
+
+ @Override
+ public Moshi getRaw() {
+ initEngine();
+ 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