上一篇中使用的是全注解下的时间参数处理,缺点较为明显:需要频繁加入注解。本文提供第二种处理方式:使用全局字符串方式处理入参时间,如入参:2022-07-06 12:01:01,这种方式是最好的传参方式。
- 优点: 参数上不需要加任何注解,即可全局统一入参格式&出参格式,且报文可阅读
- 缺点: 无
- 日期时间对象全注解方式出入参:https://www.jianshu.com/p/7049d5161c16
- 日期时间对象全局时间戳出入参:https://www.jianshu.com/p/bf9ad578bebc
public interface TimeConstants {
String DEFAULT_DATE_TIME_REGULAR = "^\d{4}-\d{1,2}-\d{1,2} {1}\d{1,2}:\d{1,2}:\d{1,2}$";
String DEFAULT_DATE_REGULAR = "^\d{4}-\d{1,2}-\d{1,2}$";
String DEFAULT_TIME_REGULAR = "^\d{1,2}:\d{1,2}:\d{1,2}$";
String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
String DEFAULT_TIME_FORMAT = "HH:mm:ss";
}
2.转换类核心代码:StringToDateConverter
import com.vip.tools.format.string.constant.TimeConstants; import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.lang.Nullable; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; import java.util.Map; @Configuration public class StringToDateConverter3.Jackson参数转换器配置{ private static final Map CLAZZ_MAP = new HashMap<>(); static { CLAZZ_MAP.put("HH:mm:ss", LocalTime.class); CLAZZ_MAP.put("yyyy-MM-dd", LocalDate.class); CLAZZ_MAP.put("yyyy-MM-dd HH:mm:ss", LocalDateTime.class); } @Bean(name = "localDateTimeConverter") public Converter localDateTimeConverter() { return new Converter () { @Override public LocalDateTime convert(@Nullable String source) { return (LocalDateTime) parse(source); } }; } @Bean(name = "localDateConverter") public Converter localDateConverter() { return new Converter () { @Override public LocalDate convert(@Nullable String source) { return (LocalDate) parse(source); } }; } @Bean(name = "localTimeConverter") public Converter localTimeConverter() { return new Converter () { @Override public LocalTime convert(@Nullable String source) { return (LocalTime) parse(source); } }; } @Bean(name = "dateConverter") public Converter dateConverter() { return new Converter () { @Override @SneakyThrows public Date convert(@Nullable String source) { if (StringUtils.isBlank(source)) { return null; } if (source.matches(TimeConstants.DEFAULT_DATE_TIME_REGULAR)) { return new SimpleDateFormat(TimeConstants.DEFAULT_DATE_TIME_FORMAT).parse(source); } throw new IllegalArgumentException("Invalid Time Value of Type String:" + source); } }; } @SneakyThrows @SuppressWarnings(value = "unchecked") private T parse(String source) { if (StringUtils.isBlank(source)) { return null; } source = source.trim(); if (source.matches(TimeConstants.DEFAULT_DATE_TIME_REGULAR)) { //判断是否yyyy-MM-dd HH:mm:ss格式 return (T) LocalDateTime.parse(source, DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_DATE_TIME_FORMAT)); } else if (source.matches(TimeConstants.DEFAULT_DATE_REGULAR)) { //判断是否yyyy-MM-dd格式 return (T) LocalDate.parse(source, DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_DATE_FORMAT)); } else if (source.matches(TimeConstants.DEFAULT_TIME_REGULAR)) { //判断是否HH:mm:ss格式 return (T) LocalTime.parse(source, DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_TIME_FORMAT)); } else { throw new IllegalArgumentException("Invalid Time Value of Type String:" + source); } } }
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
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.vip.tools.format.string.constant.TimeConstants;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class JacksonHttpMessageConverter extends MappingJackson2HttpMessageConverter {
public JacksonHttpMessageConverter() {
handleDateTime();
}
private void handleDateTime() {
ObjectMapper objectMapper = this.getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Date出入参格式化
objectMapper.setDateFormat(new SimpleDateFormat(TimeConstants.DEFAULT_DATE_TIME_FORMAT));
// Java8时间格式化
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 出参格式化
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_DATE_TIME_FORMAT)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_DATE_FORMAT)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_TIME_FORMAT)));
// 入参格式化
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_DATE_TIME_FORMAT)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_DATE_FORMAT)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_TIME_FORMAT)));
// 把“忽略重复的模块注册”禁用,否则下面的注册(LocalDateTime)不生效
objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS);
objectMapper.registerModule(javaTimeModule);
// 然后再设置为生效,避免被其他地方覆盖
objectMapper.enable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS);
// 设置格式化内容
this.setObjectMapper(objectMapper);
}
}
4.WebMvcConfiguration
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
@Configuration
@RequiredArgsConstructor
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
private final Converter localDateTimeConverter;
private final Converter localDateConverter;
private final Converter localTimeConverter;
private final Converter dateConverter;
@Override
protected void addFormatters(FormatterRegistry registry) {
registry.addConverter(localDateTimeConverter);
registry.addConverter(localDateConverter);
registry.addConverter(localTimeConverter);
registry.addConverter(dateConverter);
}
@Override
public void configureMessageConverters(List> converters) {
super.configureMessageConverters(converters);
JacksonHttpMessageConverter converter = new JacksonHttpMessageConverter();
converters.add(converter);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("
@Data
public class CityDTO {
private Date date;
private LocalDate localDate;
private LocalDateTime localDateTime;
private LocalTime localTime;
private String name;
}
controller
import com.vip.tools.format.string.dto.CityDTO;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
@RestController
@RequestMapping(value = "/string_format")
public class StringDateFormatController {
@PostMapping("/test")
public CityDTO format(@RequestParam Date date, @RequestParam LocalDate localDate, @RequestParam LocalDateTime localDateTime
, @RequestParam LocalTime localTime, @RequestBody CityDTO dto) {
System.out.println(date);
System.out.println(localDate);
System.out.println(localDateTime);
System.out.println(localTime);
System.out.println(dto);
return dto;
}
}
URL: http://localhost:9600/string_format/test?date=2020-01-25 12:00:23&localDate=2020-01-25&localDateTime=2020-01-25 12:00:23&localTime=12:00:23
Body参数:
{
"date": "2020-12-31 23:59:59",
"localDate": "2020-12-31",
"localDateTime": "2020-12-31 23:59:59",
"localTime": "23:59:59",
"name": "TEST"
}
控制台打印:
Sat Jan 25 12:00:23 CST 2020 2020-01-25 2020-01-25T12:00:23 12:00:23 CityDTO(date=Thu Dec 31 23:59:59 CST 2020, localDate=2020-12-31, localDateTime=2020-12-31T23:59:59, localTime=23:59:59, name=TEST)
响应结果:
{
"date": "2020-12-31 23:59:59",
"localDate": "2020-12-31",
"localDateTime": "2020-12-31 23:59:59",
"localTime": "23:59:59",
"name": "TEST"
}
日期对象全局字符串出入参配置完成。



