LocalDateTime 序列化问题
jackson LocalDateTime 返回前台 json 成了数组
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();
}
}