mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add config
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
<!-- versions -->
|
<!-- versions -->
|
||||||
<bouncycastle.version>1.78.1</bouncycastle.version>
|
<bouncycastle.version>1.78.1</bouncycastle.version>
|
||||||
<jjwt.version>0.12.6</jjwt.version>
|
<jjwt.version>0.12.6</jjwt.version>
|
||||||
|
<jackson.version>2.17.2</jackson.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -52,9 +53,15 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.17.2</version>
|
<version>${jackson.version}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
|
@@ -94,6 +94,8 @@ public class FastJSON2Engine extends AbstractJSONEngine {
|
|||||||
protected void initEngine() {
|
protected void initEngine() {
|
||||||
if(null == this.readerContext){
|
if(null == this.readerContext){
|
||||||
this.readerContext = JSONFactory.createReadContext();
|
this.readerContext = JSONFactory.createReadContext();
|
||||||
|
final String dateFormat = ObjUtil.defaultIfNull(this.config, JSONEngineConfig::getDateFormat, "millis");
|
||||||
|
this.readerContext.setDateFormat(ObjUtil.defaultIfNull(dateFormat, "millis"));
|
||||||
}
|
}
|
||||||
if(null == this.writerContext){
|
if(null == this.writerContext){
|
||||||
final List<JSONWriter.Feature> features = ListUtil.of();
|
final List<JSONWriter.Feature> features = ListUtil.of();
|
||||||
@@ -101,6 +103,10 @@ public class FastJSON2Engine extends AbstractJSONEngine {
|
|||||||
features.add(JSONWriter.Feature.PrettyFormat);
|
features.add(JSONWriter.Feature.PrettyFormat);
|
||||||
}
|
}
|
||||||
this.writerContext = JSONFactory.createWriteContext(features.toArray(new JSONWriter.Feature[0]));
|
this.writerContext = JSONFactory.createWriteContext(features.toArray(new JSONWriter.Feature[0]));
|
||||||
|
|
||||||
|
// 自定义配置
|
||||||
|
final String dateFormat = ObjUtil.defaultIfNull(this.config, JSONEngineConfig::getDateFormat, "millis");
|
||||||
|
this.writerContext.setDateFormat(ObjUtil.defaultIfNull(dateFormat, "millis"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,15 +16,18 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.json.engine;
|
package org.dromara.hutool.json.engine;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.*;
|
||||||
import com.google.gson.GsonBuilder;
|
import org.dromara.hutool.core.date.TimeUtil;
|
||||||
import org.dromara.hutool.core.lang.Assert;
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
import org.dromara.hutool.json.JSONException;
|
import org.dromara.hutool.json.JSONException;
|
||||||
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gson引擎实现
|
* Gson引擎实现
|
||||||
@@ -79,6 +82,20 @@ public class GsonEngine extends AbstractJSONEngine{
|
|||||||
if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
|
if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
|
||||||
builder.setPrettyPrinting();
|
builder.setPrettyPrinting();
|
||||||
}
|
}
|
||||||
|
final String dateFormat = ObjUtil.apply(this.config, JSONEngineConfig::getDateFormat);
|
||||||
|
if (StrUtil.isNotEmpty(dateFormat)) {
|
||||||
|
builder.setDateFormat(dateFormat);
|
||||||
|
builder.registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, typeOfT, context) -> TimeUtil.parse(json.getAsString(), dateFormat));
|
||||||
|
builder.registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (date, type, jsonSerializationContext) -> new JsonPrimitive(TimeUtil.format(date, dateFormat)));
|
||||||
|
} else {
|
||||||
|
// 无自定义格式,则默认输出时间戳
|
||||||
|
// https://stackoverflow.com/questions/41979086/how-to-serialize-date-to-long-using-gson
|
||||||
|
builder.registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong()));
|
||||||
|
builder.registerTypeAdapter(Date.class, (JsonSerializer<Date>) (date, type, jsonSerializationContext) -> new JsonPrimitive(date.getTime()));
|
||||||
|
builder.registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, typeOfT, context) -> TimeUtil.of(json.getAsJsonPrimitive().getAsLong()));
|
||||||
|
builder.registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (date, type, jsonSerializationContext) -> new JsonPrimitive(TimeUtil.toEpochMilli(date)));
|
||||||
|
}
|
||||||
|
|
||||||
this.gson = builder.create();
|
this.gson = builder.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,12 @@ public class HutoolJSONEngine extends AbstractJSONEngine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hutoolSJONConfig = JSONConfig.of();
|
// 自定义配置
|
||||||
|
final JSONConfig hutoolSJONConfig = JSONConfig.of();
|
||||||
|
if(null != this.config){
|
||||||
|
hutoolSJONConfig.setDateFormat(this.config.getDateFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hutoolSJONConfig = hutoolSJONConfig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,10 @@ public class JSONEngineConfig implements Serializable {
|
|||||||
* 是否格式化输出
|
* 是否格式化输出
|
||||||
*/
|
*/
|
||||||
private boolean prettyPrint;
|
private boolean prettyPrint;
|
||||||
|
/**
|
||||||
|
* 日期格式,null表示默认的时间戳
|
||||||
|
*/
|
||||||
|
private String dateFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取是否启用格式化输出
|
* 获取是否启用格式化输出
|
||||||
@@ -60,4 +64,25 @@ public class JSONEngineConfig implements Serializable {
|
|||||||
this.prettyPrint = prettyPrint;
|
this.prettyPrint = prettyPrint;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期格式,null表示默认的时间戳
|
||||||
|
*
|
||||||
|
* @return 日期格式,null表示默认的时间戳
|
||||||
|
*/
|
||||||
|
public String getDateFormat() {
|
||||||
|
return dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置日期格式,null表示默认的时间戳<br>
|
||||||
|
* 此方法设置的日期格式仅对转换为JSON字符串有效,对解析JSON为bean无效。
|
||||||
|
*
|
||||||
|
* @param dateFormat 日期格式,null表示默认的时间戳
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public JSONEngineConfig setDateFormat(final String dateFormat) {
|
||||||
|
this.dateFormat = dateFormat;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,9 @@ public class JSONEngineFactory {
|
|||||||
if(StrUtil.equalsIgnoreCase("fastjson", engineName)){
|
if(StrUtil.equalsIgnoreCase("fastjson", engineName)){
|
||||||
engineName = "FastJSON2";
|
engineName = "FastJSON2";
|
||||||
}
|
}
|
||||||
|
if(StrUtil.equalsIgnoreCase("hutool", engineName)){
|
||||||
|
engineName = "HutoolJSON";
|
||||||
|
}
|
||||||
|
|
||||||
if (!StrUtil.endWithIgnoreCase(engineName, "Engine")) {
|
if (!StrUtil.endWithIgnoreCase(engineName, "Engine")) {
|
||||||
engineName = engineName + "Engine";
|
engineName = engineName + "Engine";
|
||||||
|
@@ -19,10 +19,14 @@ package org.dromara.hutool.json.engine;
|
|||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.JavaType;
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
|
import com.fasterxml.jackson.databind.Module;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import org.dromara.hutool.core.date.DateUtil;
|
||||||
import org.dromara.hutool.core.io.IORuntimeException;
|
import org.dromara.hutool.core.io.IORuntimeException;
|
||||||
import org.dromara.hutool.core.lang.Assert;
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
|
import org.dromara.hutool.core.reflect.ConstructorUtil;
|
||||||
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
import org.dromara.hutool.json.JSONException;
|
import org.dromara.hutool.json.JSONException;
|
||||||
|
|
||||||
@@ -48,6 +52,16 @@ public class JacksonEngine extends AbstractJSONEngine {
|
|||||||
Assert.notNull(ObjectMapper.class);
|
Assert.notNull(ObjectMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Jackson的{@link ObjectMapper}对象
|
||||||
|
*
|
||||||
|
* @return {@link ObjectMapper}对象
|
||||||
|
*/
|
||||||
|
public ObjectMapper getMapper() {
|
||||||
|
initEngine();
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(final Object bean, final Writer writer) {
|
public void serialize(final Object bean, final Writer writer) {
|
||||||
initEngine();
|
initEngine();
|
||||||
@@ -102,7 +116,33 @@ public class JacksonEngine extends AbstractJSONEngine {
|
|||||||
if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
|
if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
|
||||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||||
}
|
}
|
||||||
|
final String dateFormat = ObjUtil.apply(this.config, JSONEngineConfig::getDateFormat);
|
||||||
|
if(StrUtil.isNotEmpty(dateFormat)){
|
||||||
|
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
mapper.setDateFormat(DateUtil.newSimpleFormat(dateFormat));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持Java8+日期格式
|
||||||
|
registerModule(mapper, "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");
|
||||||
|
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册模块
|
||||||
|
*
|
||||||
|
* @param mapper Jackson的{@link ObjectMapper}对象
|
||||||
|
* @param moduleClass 模块类名
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
|
private void registerModule(final ObjectMapper mapper, final String moduleClass) {
|
||||||
|
final Class<?> aClass;
|
||||||
|
try {
|
||||||
|
aClass = Class.forName(moduleClass);
|
||||||
|
} catch (final ClassNotFoundException ignore) {
|
||||||
|
//用户未引入JSR310,则跳过不加载模块
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mapper.registerModule((Module) ConstructorUtil.newInstance(aClass));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024. looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* https://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.json.engine;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class BeanWithDate {
|
||||||
|
private Date date1;
|
||||||
|
private LocalDateTime date2;
|
||||||
|
}
|
@@ -1,5 +1,8 @@
|
|||||||
package org.dromara.hutool.json.engine;
|
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.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -20,4 +23,17 @@ public class FastJSONTest {
|
|||||||
" \"gender\":true\n" +
|
" \"gender\":true\n" +
|
||||||
"}", jsonString);
|
"}", jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeDateFormatTest() {
|
||||||
|
final DateTime date = DateUtil.parse("2024-01-01 01:12:21");
|
||||||
|
final BeanWithDate bean = new BeanWithDate(date, TimeUtil.of(date));
|
||||||
|
final JSONEngine engine = JSONEngineFactory.createEngine("fastjson");
|
||||||
|
|
||||||
|
final String jsonString = engine.toJsonString(bean);
|
||||||
|
Assertions.assertEquals("{\"date1\":1704042741000,\"date2\":1704042741000}", jsonString);
|
||||||
|
|
||||||
|
engine.init(JSONEngineConfig.of().setDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
Assertions.assertEquals("{\"date1\":\"2024-01-01 01:12:21\",\"date2\":\"2024-01-01 01:12:21\"}", engine.toJsonString(bean));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
package org.dromara.hutool.json.engine;
|
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.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -21,4 +24,17 @@ public class GsonTest {
|
|||||||
" \"gender\": true\n" +
|
" \"gender\": true\n" +
|
||||||
"}", jsonString);
|
"}", jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeDateFormatTest() {
|
||||||
|
final DateTime date = DateUtil.parse("2024-01-01 01:12:21");
|
||||||
|
final BeanWithDate bean = new BeanWithDate(date, TimeUtil.of(date));
|
||||||
|
final JSONEngine engine = JSONEngineFactory.createEngine("gson");
|
||||||
|
|
||||||
|
final String jsonString = engine.toJsonString(bean);
|
||||||
|
Assertions.assertEquals("{\"date1\":1704042741000,\"date2\":1704042741000}", jsonString);
|
||||||
|
|
||||||
|
engine.init(JSONEngineConfig.of().setDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
Assertions.assertEquals("{\"date1\":\"2024-01-01 01:12:21\",\"date2\":\"2024-01-01 01:12:21\"}", engine.toJsonString(bean));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
package org.dromara.hutool.json.engine;
|
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.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -17,4 +20,17 @@ public class HutoolJSONTest {
|
|||||||
" \"gender\": true\n" +
|
" \"gender\": true\n" +
|
||||||
"}", jsonString);
|
"}", jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeDateFormatTest() {
|
||||||
|
final DateTime date = DateUtil.parse("2024-01-01 01:12:21");
|
||||||
|
final BeanWithDate bean = new BeanWithDate(date, TimeUtil.of(date));
|
||||||
|
final JSONEngine engine = JSONEngineFactory.createEngine("hutool");
|
||||||
|
|
||||||
|
final String jsonString = engine.toJsonString(bean);
|
||||||
|
Assertions.assertEquals("{\"date1\":1704042741000,\"date2\":1704042741000}", jsonString);
|
||||||
|
|
||||||
|
engine.init(JSONEngineConfig.of().setDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
Assertions.assertEquals("{\"date1\":\"2024-01-01 01:12:21\",\"date2\":\"2024-01-01 01:12:21\"}", engine.toJsonString(bean));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
package org.dromara.hutool.json.engine;
|
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.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -23,4 +26,18 @@ public class JacksonTest {
|
|||||||
" \"gender\" : true\n" +
|
" \"gender\" : true\n" +
|
||||||
"}", jsonString);
|
"}", jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeDateFormatTest() {
|
||||||
|
final DateTime date = DateUtil.parse("2024-01-01 01:12:21");
|
||||||
|
final BeanWithDate bean = new BeanWithDate(date, TimeUtil.of(date));
|
||||||
|
final JSONEngine engine = JSONEngineFactory.createEngine("jackson");
|
||||||
|
|
||||||
|
final String jsonString = engine.toJsonString(bean);
|
||||||
|
Assertions.assertEquals("{\"date1\":1704042741000,\"date2\":[2024,1,1,1,12,21]}", jsonString);
|
||||||
|
|
||||||
|
//TODO LocalDateTime的格式化未解决
|
||||||
|
engine.init(JSONEngineConfig.of().setDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
Assertions.assertEquals("{\"date1\":\"2024-01-01 01:12:21\",\"date2\":\"2024-01-01T01:12:21\"}", engine.toJsonString(bean));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user