Get请求-LocalDateTime的转换问题

问题分析

        在处理 HTTP GET 请求时,如果尝试接收一个 LocalDateTime 类型的参数,可能会遇到序列化或反序列化的问题。这是因为 URL 参数通常是字符串形式,而 LocalDateTime 是 Java 中的一个日期时间对象,需要适当的格式化才能正确解析。不然可以会出现如下错误:

Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2024-08-08 22:22:22'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2024-08-08 22:22:22]

解决方案

一、LocalDateTime 转换器(全局)

        get请求的话, 不走反序列化,而是直接将String的值塞给对应的类型,默认是没有转换器,会抛出异常。

        配置了转换器后,当用LocalDateTime接收get请求参数的时候,就会进入这个转换器中。


import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Component
public class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public LocalDateTime convert(String source) {
        return LocalDateTime.parse(source, formatter);
    }
}

二、显示参数处理

        如果不想使用自定义转换器,可以在控制器方法中显式地处理字符串参数,并手动转换为 LocalDateTime:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@RestController
public class MyController {

    @GetMapping("/test1")
    public void resolveRequestParamDateTime(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime localDateTime) {
        log.info("localDateTime:{}", localDateTime);
    }

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @GetMapping("/test2")
    public String getDateTime(@RequestParam("date") String dateString) {
        LocalDateTime date = LocalDateTime.parse(dateString, formatter);
        // 处理逻辑
        return "Received date: " + date;
    }
}

三、application.yml配置

        application.yml配置 SpringBoot2.3.x以及更高的版本,springmvc增加了日期时间格式配置,既可以解决LocalDateTime类型参数解析,也可以解决Date类型参数解析

spring:
  mvc:
    date: yyyy-MM-dd
    time: HH:mm:ss
    date-time: yyyy-MM-dd HH:mm:ss

四、LocalDateTimeConfig

        在Spring IOC容器中注入Converter,SpringBoot会自动将IOC容器中的Converter放到GenericConversionService中


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class LocalDateTimeConfig {
    @Bean
    public Converter<String, LocalDateTime> stringToLocalDateTimeConverter() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {
                return LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        };
    }

    @Bean
    public Converter<String, LocalDate> stringToLocalDateConverter() {
        return new Converter<String, LocalDate>() {
            @Override
            public LocalDate convert(String source) {
                return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            }
        };
    }

    @Bean
    public Converter<String, LocalTime> stringToLocalTimeConverter() {
        return new Converter<String, LocalTime>() {
            @Override
            public LocalTime convert(String source) {
                return LocalTime.parse(source, DateTimeFormatter.ofPattern("HH:mm:ss"));
            }
        };
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值