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 -->
|
||||
<bouncycastle.version>1.78.1</bouncycastle.version>
|
||||
<jjwt.version>0.12.6</jjwt.version>
|
||||
<jackson.version>2.17.2</jackson.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -52,9 +53,15 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.17.2</version>
|
||||
<version>${jackson.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
|
@@ -94,6 +94,8 @@ public class FastJSON2Engine extends AbstractJSONEngine {
|
||||
protected void initEngine() {
|
||||
if(null == this.readerContext){
|
||||
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){
|
||||
final List<JSONWriter.Feature> features = ListUtil.of();
|
||||
@@ -101,6 +103,10 @@ public class FastJSON2Engine extends AbstractJSONEngine {
|
||||
features.add(JSONWriter.Feature.PrettyFormat);
|
||||
}
|
||||
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;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.*;
|
||||
import org.dromara.hutool.core.date.TimeUtil;
|
||||
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.json.JSONException;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Gson引擎实现
|
||||
@@ -79,6 +82,20 @@ public class GsonEngine extends AbstractJSONEngine{
|
||||
if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@@ -60,6 +60,12 @@ public class HutoolJSONEngine extends AbstractJSONEngine {
|
||||
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;
|
||||
/**
|
||||
* 日期格式,null表示默认的时间戳
|
||||
*/
|
||||
private String dateFormat;
|
||||
|
||||
/**
|
||||
* 获取是否启用格式化输出
|
||||
@@ -60,4 +64,25 @@ public class JSONEngineConfig implements Serializable {
|
||||
this.prettyPrint = prettyPrint;
|
||||
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)){
|
||||
engineName = "FastJSON2";
|
||||
}
|
||||
if(StrUtil.equalsIgnoreCase("hutool", engineName)){
|
||||
engineName = "HutoolJSON";
|
||||
}
|
||||
|
||||
if (!StrUtil.endWithIgnoreCase(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.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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.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.json.JSONException;
|
||||
|
||||
@@ -48,6 +52,16 @@ public class JacksonEngine extends AbstractJSONEngine {
|
||||
Assert.notNull(ObjectMapper.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Jackson的{@link ObjectMapper}对象
|
||||
*
|
||||
* @return {@link ObjectMapper}对象
|
||||
*/
|
||||
public ObjectMapper getMapper() {
|
||||
initEngine();
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final Object bean, final Writer writer) {
|
||||
initEngine();
|
||||
@@ -102,7 +116,33 @@ public class JacksonEngine extends AbstractJSONEngine {
|
||||
if (ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false)) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册模块
|
||||
*
|
||||
* @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;
|
||||
|
||||
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.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -20,4 +23,17 @@ public class FastJSONTest {
|
||||
" \"gender\":true\n" +
|
||||
"}", 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;
|
||||
|
||||
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;
|
||||
|
||||
@@ -21,4 +24,17 @@ public class GsonTest {
|
||||
" \"gender\": true\n" +
|
||||
"}", 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;
|
||||
|
||||
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;
|
||||
|
||||
@@ -17,4 +20,17 @@ public class HutoolJSONTest {
|
||||
" \"gender\": true\n" +
|
||||
"}", 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;
|
||||
|
||||
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.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -23,4 +26,18 @@ public class JacksonTest {
|
||||
" \"gender\" : true\n" +
|
||||
"}", 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