当前位置:首页 » 《资源分享》 » 正文

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

18 人参与  2024年12月25日 10:01  分类 : 《资源分享》  评论

点击全文阅读


环境: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

public class LocalDateTimeConverter implements Converter<String, LocalDateTime> {   private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");      @Override   public LocalDateTime convert(String source) {      return LocalDateTime.parse(source,formatter);   }}

自定义Formatter

public class LocalDateTimeFormatter implements Formatter<LocalDateTime> {   private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");      @Override    public LocalDateTime parse(String text, Locale locale) throws ParseException {        return LocalDateTime.parse(text, formatter);    }    @Override    public String print(LocalDateTime object, Locale locale) {        return DateUtils.formatLocalDateTime(object,"yyyy-MM-dd'T'HH:mm:ss");    }}

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

@SpringBootConfigurationpublic class MvcConfiguration implements WebMvcConfigurer {       @Override    public void addFormatters(FormatterRegistry registry) {        //方法1:                registry.addFormatter(new LocalDateTimeFormatter());        //方法2:        registry.addConverter(new LocalDateTimeConverter());        //方法3:        registry.addFormatter(new Formatter<LocalDateTime>() {            @Override            public String print(LocalDateTime object, Locale locale) {                return //LocalDateTime转String ;            }            @Override            public LocalDateTime parse(String text, Locale locale) {                return //String转LocalDateTime;            }        });    }}

controller接收参数

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

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

@SpringBootConfigurationpublic class MvcConfiguration implements WebMvcConfigurer {     @Override    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {        resolvers.add(new HandlerMethodArgumentResolver() {            @Override            public boolean supportsParameter(MethodParameter parameter) {                //这里定义需要解析的类型,注:parameter.getParameterType()获取到的是controller中方法上参数的类型,                //如果是用@RequestParam或@ModelAttribute注解的则会用mvc默认的解析器                return true;            }            @Override            public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {                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会被最后一个覆盖。

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

formatStringToLocalDate(String text)

public static LocalDateTime formatStringToLocalDate(String time) {        //0[1-9]表示01到09,1[0-2]表示10到12,中间的|表示或,[12][0-9]表示10到29,3[01]表示30和31        String regexToDay = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$";        if (time.matches(regexToDay)) {            return formatStringToLocalDate(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)) {            return formatStringToLocalDate(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)) {            return formatStringToLocalDate(time, "yyyy-MM-dd HH:mm:ss.SSSX");        }        throw new BusinessException("不支持当前日期时间格式");    }

点击全文阅读


本文链接:http://zhangshiyu.com/post/206536.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1