LocalDateTime 序列化问题

jackson LocalDateTime 返回前台 json 成了数组

参考 LocalDate 和 LocalDateTime 序列化和反序列化的问题

returnTime: [2020, 12, 3, 16, 0]

解决办法:

ConverterConfig

package com.xxtsoft.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

/**
 * 配置 Jackson 序列化日期
 *
 * @author yang
 */
@Configuration
public class ConverterConfig {
    @Bean
    public DateJacksonConverter dateJacksonConverter() {
        return new DateJacksonConverter();
    }

    @Bean
    public Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean(
            @Autowired
                    DateJacksonConverter dateJacksonConverter) {
        Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean = new Jackson2ObjectMapperFactoryBean();

        jackson2ObjectMapperFactoryBean.setDeserializers(dateJacksonConverter);
        return jackson2ObjectMapperFactoryBean;
    }

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(
            @Autowired
                    ObjectMapper objectMapper) {
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter =
                new MappingJackson2HttpMessageConverter();
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
        return mappingJackson2HttpMessageConverter;
    }


    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        //用于解决 java.time 模块的时间序列化为 json 时变成数组的问题
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
    }
}

DateJacksonConverter

package com.xxtsoft.config;


import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.io.IOException;
import java.text.ParseException;
import java.util.Date;

/**
 * 自定义 Jackson 反序列化日期类型时应用的类型转换器 ,
 * 一般用于@RequestBody接受参数时使用
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-12-03 17:33
 */
public class DateJacksonConverter extends JsonDeserializer<Date> {
    private static final String[] PATTERN =
            new String[]{"yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.S",
                    "yyyy.MM.dd", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss.S",
                    "yyyy/MM/dd", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss.S"};

    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {

        Date targetDate = null;
        String originDate = p.getText();
        if (StringUtils.isNotEmpty(originDate)) {
            try {
                long longDate = Long.parseLong(originDate.trim());
                targetDate = new Date(longDate);
            } catch (NumberFormatException e) {
                try {
                    targetDate = DateUtils.parseDate(originDate, DateJacksonConverter.PATTERN);
                } catch (ParseException pe) {
                    throw new IOException(String.format(
                            "'%s' can not convert to type 'java.util.Date',just support timestamp(type of long) and following date format(%s)",
                            originDate,
                            StringUtils.join(PATTERN, ",")));
                }
            }
        }


        return targetDate;
    }

    @Override
    public Class<?> handledType() {
        return Date.class;
    }
}

String2DateConverter

package com.xxtsoft.config.date.converter;

import cn.hutool.core.convert.Convert;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 字符串转换成 Date
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-12-17 15:41
 */
@Component
public class String2DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        return Convert.toDate(s);
    }
}

String2LocalDateConverter

package com.xxtsoft.config.date.converter;

import cn.hutool.core.date.DatePattern;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 时间格式化 工具,
 * String to LocalDate
 * 用户 controller 参数是 LocalDate 或者 Date
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-12-04 17:15
 */

@Component
public class String2LocalDateConverter implements Converter<String, LocalDate> {

    private static final List<String> SUPPORTED_FORMATS = Arrays.asList(DatePattern.NORM_DATE_PATTERN, DatePattern.PURE_DATE_PATTERN);
    private static final List<DateTimeFormatter> DATE_TIME_FORMATTERS = SUPPORTED_FORMATS
            .stream()
            .map(DateTimeFormatter::ofPattern)
            .collect(Collectors.toList());

    @Override
    public LocalDate convert(String s) {
        for (DateTimeFormatter dateTimeFormatter : DATE_TIME_FORMATTERS) {
            try {
                return LocalDate.parse(s, dateTimeFormatter);
            } catch (DateTimeParseException ex) {
                // deliberate empty block so that all parsers run
            }
        }

        throw new DateTimeException(String.format("unable to parse (%s) supported formats are %s",
                s, String.join(", ", SUPPORTED_FORMATS)));
    }
}

String2LocalDateTimeConverter

package com.xxtsoft.config.date.converter;

import cn.hutool.core.date.DateUtil;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * String to LocalDateTime
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-12-17 15:26
 */
@Component
public class String2LocalDateTimeConverter implements Converter<String, LocalDateTime> {

    @Override
    public LocalDateTime convert(String s) {
        return DateUtil.parseLocalDateTime(s);
    }
}

String2LocalTimeConverter

package com.xxtsoft.config.date.converter;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.time.LocalTime;

/**
 * 字符串转换成 LocalTime
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-12-17 15:36
 */
@Component
public class String2LocalTimeConverter implements Converter<String, LocalTime> {
    @Override
    public LocalTime convert(String s) {
        return DateUtil.parseLocalDateTime(s, DatePattern.NORM_TIME_PATTERN).toLocalTime();
    }
}
posted @ 2020-12-24 09:49  javaYanglei  阅读(3059)  评论(0编辑  收藏  举报