0


LocalDateTime与前端字符串时间数据交互问题

环境:JDK17 / SpringBoot 3.2.4

  • 注解方式

在接收参数上加注解: @JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”)

在返回参数上加注解:@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”)

  • 全局配置方式
  • GET请求,LocalDateTime接收前端字符串类型时间数据解析

自定义Converter

publicclassLocalDateTimeConverterimplementsConverter<String,LocalDateTime>{privatefinalDateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");@OverridepublicLocalDateTimeconvert(String source){returnLocalDateTime.parse(source,formatter);}}

自定义Formatter

publicclassLocalDateTimeFormatterimplementsFormatter<LocalDateTime>{privatefinalDateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");@OverridepublicLocalDateTimeparse(String text,Locale locale)throwsParseException{returnLocalDateTime.parse(text, formatter);}@OverridepublicStringprint(LocalDateTime object,Locale locale){returnDateUtils.formatLocalDateTime(object,"yyyy-MM-dd'T'HH:mm:ss");}}

自定义Mvc配置,覆写addFormatters方法,注册Formatter或Converter
注:在自定义LocalDateTimeConverter 和LocalDateTimeFormatter时不要直接在MvcConfiguration中写内部类否则不生效。当然也可以直接实现接口。

@SpringBootConfigurationpublicclassMvcConfigurationimplementsWebMvcConfigurer{@OverridepublicvoidaddFormatters(FormatterRegistry registry){//方法1:        
        registry.addFormatter(newLocalDateTimeFormatter());//方法2:
        registry.addConverter(newLocalDateTimeConverter());//方法3:
        registry.addFormatter(newFormatter<LocalDateTime>(){@OverridepublicStringprint(LocalDateTime object,Locale locale){return//LocalDateTime转String ;}@OverridepublicLocalDateTimeparse(String text,Locale locale){return//String转LocalDateTime;}});}}

controller接收参数

@GetMapping(value="/")publicResponse<?>acceptTime(TimeDTO params){//用对象接收,对象中的部分属性类型为LocalDateTime}@GetMapping(value="/")publicResponse<?>acceptTime(@RequestParamLocalDateTime time){}

其它方法:在Mvc配置中注册自定义的参数解析器
目前测试Get方法用实体对象接收没问题,有个弊端就是需要所有的参数都自己解析,只解析部分另一部分有默认解析器解析还未找到方法。

@SpringBootConfigurationpublicclassMvcConfigurationimplementsWebMvcConfigurer{@OverridepublicvoidaddArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers){
        resolvers.add(newHandlerMethodArgumentResolver(){@OverridepublicbooleansupportsParameter(MethodParameter parameter){//这里定义需要解析的类型,注:parameter.getParameterType()获取到的是controller中方法上参数的类型,//如果是用@RequestParam或@ModelAttribute注解的则会用mvc默认的解析器returntrue;}@OverridepublicObjectresolveArgument(MethodParameter parameter,ModelAndViewContainer mavContainer,NativeWebRequest webRequest,WebDataBinderFactory binderFactory)throwsException{Object object = parameter.getParameterType().getDeclaredConstructor().newInstance();Map<String,String[]> params = webRequest.getParameterMap();for(Field field : parameter.getParameterType().getDeclaredFields()){String fieldName = field.getName();if(!params.containsKey(fieldName)){//只对有值的参数做解析continue;}
                    field.setAccessible(true);//解析LocalDateTime字段if(LocalDateTime.class.isAssignableFrom(field.getType())){String fieldValue = params.get(fieldName)[0];LocalDateTime dateTime =LocalDateTime.parse(fieldValue);
                        field.set(object, dateTime);}//解析其它类型的参数...}return object;}});}}
  • POST请求,时间参数为Body中的Json数据,LocalDateTime接收并解析以及反回LocalDateTime数据问题

自定义Bean jsonObjectMapper 对LocalDateTime做序列化和返序列化
默认反序列化也就是处理接收的LocalDateTime时间格式为:yyyy-MM-dd’T’HH:mm:ss.SSSX
默认的序列化也就是后端返回前端LocalDateTime的时间格式为:yyyy-MM-dd’T’HH:mm:ss
JavaTimeModule继承SimpleModule,注册多个SimpleModule会被最后一个覆盖。

@BeanpublicObjectMapperjsonObjectMapper(){ObjectMapper mapper =newObjectMapper();//设置时间类型的不以时间戳序列化
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);//忽略前端多传的参数
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);JavaTimeModule timeModule =newJavaTimeModule();//LocalDateTime序列化,并默认返回前端的字符串格式
        timeModule.addSerializer(LocalDateTime.class,newLocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));//LocalDateTime反序列化
        timeModule.addDeserializer(LocalDateTime.class,newStdDeserializer<>(LocalDateTime.class){@OverridepublicLocalDateTimedeserialize(JsonParser jsonParser,DeserializationContext deserializationContext)throwsIOException,JacksonException{String text = jsonParser.getText();//这里提供一个方法用于适配几种格式的字符串转LocalDateTimereturnDateUtils.formatStringToLocalDate(text);}});
        mapper.registerModule(timeModule);return mapper;}

formatStringToLocalDate(String text)

publicstaticLocalDateTimeformatStringToLocalDate(String time){//0[1-9]表示01到09,1[0-2]表示10到12,中间的|表示或,[12][0-9]表示10到29,3[01]表示30和31String regexToDay ="^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$";if(time.matches(regexToDay)){returnformatStringToLocalDate(time,"yyyy-MM-dd");}//\s+:匹配一个或多个空白字符(空格、制表符等)String regexToSecond ="^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])\\s+(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";if(time.matches(regexToSecond)){returnformatStringToLocalDate(time,"yyyy-MM-dd HH:mm:ss");}String regexStandard ="^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\.\\d{3}(Z)$";if(time.matches(regexStandard)){returnformatStringToLocalDate(time,"yyyy-MM-dd HH:mm:ss.SSSX");}thrownewBusinessException("不支持当前日期时间格式");}
标签: spring boot servlet

本文转载自: https://blog.csdn.net/weixin_43587900/article/details/141928537
版权归原作者 chevysky.cn 所有, 如有侵权,请联系我们删除。

“LocalDateTime与前端字符串时间数据交互问题”的评论:

还没有评论