分享个兼容Java8时间的Jackson工具类

如果你的项目使用了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);
        }
    }

}

一些常用注解


作者:不敲代码的攻城狮
出处:https://www.cnblogs.com/leigq/
任何傻瓜都能写出计算机可以理解的代码。好的程序员能写出人能读懂的代码。

 
原文地址:https://www.cnblogs.com/leigq/p/13406568.html