zoukankan      html  css  js  c++  java
  • 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();
        }
    }
    
  • 相关阅读:
    【SpringMVC学习09】SpringMVC与前台的json数据交互
    【SpringMVC学习08】SpringMVC中实现文件上传
    【SpringMVC学习07】SpringMVC中的统一异常处理
    【SpringMVC学习06】SpringMVC中的数据校验
    【SpringMVC学习05】SpringMVC中的参数绑定总结——较乱后期准备加入 同一篇幅他人的参数绑定
    【SpringMVC学习04】Spring、MyBatis和SpringMVC的整合
    【SpringMVC学习03】SpringMVC中注解和非注解方式下的映射器和适配器总结
    【SpringMVC学习02】走进SpringMVC的世界
    【MyBatis】MyBatis分页插件PageHelper的使用
    【MyBatis学习15】MyBatis的逆向工程生成代码
  • 原文地址:https://www.cnblogs.com/javayanglei/p/14182705.html
Copyright © 2011-2022 走看看