如果你的项目使用了Spring,那肯定已经引入了Jackson的jar,Spring默认就是使用Jackson来处理json序列号的,这里我分享一个基于Jackson封装的一个工具类,可以在项目中需要手动序列化json的时候用,另外,我们知道SpringMVC在Controller层就收参数和返回Json数据给前端的时候使用的Jackson来序列化(可以换为fastjson,自行百度,这不是重点),其中,在序列化的时候,处理时间有点头疼,一般都会用@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
做入参格式化、@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
做出参格式化,其实,还有一种更简单的方法可以实现全局处理,我写到了这篇博客里面,有需要的,可以看看:SpringBoot关于时间入参、出参之处理
Jackson 工具类(兼容Java8时间、科学记数法)
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* Jackson 工具类
* </br>
* <ul>
* <li>兼容 Java8 的时间,</li>
* <li>不会出现科学计算法,已做处理</li>
* </ul>
*
* @author leigq
* @date 2020 -07-22 13:09:05
*/
public final class JacksonUtils {
/**
* 提供一个全局可用的序列化 Bean,该对象只在本类使用,不提供给其他类用。<br/>
*/
private static final ObjectMapper OBJECT_MAPPER = customObjectMapper(new ObjectMapper());
private static final String DATE_FORMATTER = "yyyy-MM-dd";
private static final String TIME_FORMATTER = "HH:mm:ss";
private static final String DATE_TIME_FORMATTER = DATE_FORMATTER + " " + TIME_FORMATTER;
private JacksonUtils() {
}
/**
* 将对象转为 JSON 字符串
*
* @param <T> the type parameter
* @param obj 可以是不带泛型的Java集合、Map、POJO对象、数组,也可以是复杂的对象
* @return json字符串 string
* @author leigq
* @date 2020 -07-22 11:58:18
*/
public static <T> String objToJson(T obj) {
try {
return OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new JacksonUtilsException(e);
}
}
/**
* 将 JSON 字符串转为不带泛型的对象, 只能转换成不带泛型的Java集合、Map、POJO这类简单对象
*
* @param <T> the type parameter
* @param json json字符串
* @param type 对象的类型
* @return 对象
* @author leigq
* @date 2020 -07-22 11:58:21
*/
public static <T> T jsonToObj(String json, Class<T> type) {
try {
return OBJECT_MAPPER.readValue(json, type);
} catch (IOException e) {
throw new JacksonUtilsException(e);
}
}
/**
* 将 JSON 字符串转为带泛型的对象
* <br>
*
* @param <T> the type parameter
* @param json the json
* @param collectionClass 集合类型
* @param elementClasses 元素类型
* @return 比如 {@code Set<Permission>} 这类带泛型的对象
* @author leigq
* @date 2020 -07-22 14:15:05
*/
public static <T> T jsonToObjOfParametric(String json, Class<?> collectionClass, Class<?>... elementClasses) {
try {
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
return OBJECT_MAPPER.readValue(json, javaType);
} catch (IOException e) {
throw new JacksonUtilsException(e);
}
}
/**
* 自定义配置以增强 ObjectMapper 默认配置,主要体现在 Java8 时间处理、科学记数法处理
* <br/>
* 如果你还需要额外的增强配置可以这样使用:<br/>
* <per>
* final ObjectMapper objectMapper = JacksonUtils.customObjectMapper(new ObjectMapper());
* objectMapper.setDateFormat(new SimpleDateFormat("YYYY-MM-dd"));
* </per>
*
* @param objectMapper the object mapper
* @return the object mapper
* @author leigq
* @date 2020 -07-24 11:14:28
*/
public static ObjectMapper customObjectMapper(ObjectMapper objectMapper) {
/* 一些配置 配置参考:http://www.imooc.com/wenda/detail/425280*/
objectMapper
// 设置时区
.setTimeZone(TimeZone.getTimeZone("GMT+8"))
// Date 对象的格式,非 java8 时间
.setDateFormat(new SimpleDateFormat(DATE_TIME_FORMATTER))
// 默认忽略值为 null 的属性,暂时不忽略,放开注释即不会序列化为 null 的属性
// .setSerializationInclusion(JsonInclude.Include.NON_NULL)
// 禁止打印时间为时间戳
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
// 禁止使用科学记数法
.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
// 自定义Java8的时间兼容模块
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 序列化配置,针对java8 时间
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMATTER)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_FORMATTER)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(TIME_FORMATTER)));
// 反序列化配置,针对java8 时间
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMATTER)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DATE_FORMATTER)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TIME_FORMATTER)));
/*注册模块*/
objectMapper
// Java8的时间兼容模块
.registerModule(javaTimeModule)
// Jdk8Module() -> 注册jdk8模块
.registerModule(new Jdk8Module())
// new ParameterNamesModule() ->
.registerModule(new ParameterNamesModule());
return objectMapper;
}
private static class JacksonUtilsException extends RuntimeException {
public JacksonUtilsException(Throwable cause) {
super(cause);
}
}
}