如何在Spring中使用LocalDateTime RequestParam?我得到"无法将字符串转换为LocalDateTime"

Ker*_* Hu 37 spring-mvc spring-boot java-time

我使用Spring Boot并包含jackson-datatype-jsr310在Maven中:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.7.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

当我尝试使用具有Java 8日期/时间类型的RequestParam时,

@GetMapping("/test")
public Page<User> get(
    @RequestParam(value = "start", required = false)
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start) {
//...
}
Run Code Online (Sandbox Code Playgroud)

并使用以下URL测试它:

/test?start=2016-10-8T00:00
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

{
  "timestamp": 1477528408379,
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException",
  "message": "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 [@org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime] for value '2016-10-8T00:00'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2016-10-8T00:00]",
  "path": "/test"
}
Run Code Online (Sandbox Code Playgroud)

d0x*_*d0x 51

你做的一切都正确:).是一个显示您正在做什么的示例.只需注释您的RequestParam @DateTimeFormat.GenericConversionService控制器中无需特殊或手动转换.这篇博客文章写到了这一点.

@RestController
@RequestMapping("/api/datetime/")
final class DateTimeController {

    @RequestMapping(value = "datetime", method = RequestMethod.POST)
    public void processDateTime(@RequestParam("datetime") 
                                @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateAndTime) {
        //Do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

我想你的格式有问题.在我的设置上一切正常.


Bwv*_*all 28

@RequestParam足以在=符号后获取你提供的日期,但是,它作为一个方法进入方法@DateTimeFormat.这就是它抛出强制转换异常的原因.

做这样的事情会更好:

@GetMapping("/test")
public Page<User> get(@RequestParam(value="start", required = false) String start){

    //Create a DateTimeFormatter with your required format:
    DateTimeFormatter dateTimeFormat = 
            new DateTimeFormatter(DateTimeFormatter.BASIC_ISO_DATE);

    //Next parse the date from the @RequestParam, specifying the TO type as 
a TemporalQuery:
   LocalDateTime date = dateTimeFormat.parse(start, LocalDateTime::from);

    //Do the rest of your code...
}
Run Code Online (Sandbox Code Playgroud)

另请注意,如果您使用的是Spring Boot Web,则可能需要仔细检查是否是,@RequestParam或者String,如果您打算从HTTP请求执行此方法.

  • 您也可以在签名方法中使用此解决方案:`@ RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)LocalDateTime start` (20认同)

Lu5*_*u55 17

我找到了解决办法在这里.

Spring/Spring Boot仅支持BODY参数中的日期/日期时间格式.

此配置类在QUERY STRING中添加对日期/日期时间的支持:

// Since Spring Framwork 5.0 & Java 8+
@Configuration
public class DateTimeFormatConfiguration implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setUseIsoFormat(true);
        registrar.registerFormatters(registry);
    }
}
Run Code Online (Sandbox Code Playgroud)

即使您将多个请求参数绑定到某个类(@DateTimeFormat在这种情况下无助于注释),它仍然有效:

// Until Spring Framwork 4.+
@Configuration
public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setUseIsoFormat(true);
        registrar.registerFormatters(registry);
    }
}
Run Code Online (Sandbox Code Playgroud)


Ann*_*nna 16

就像我在评论中提到的那样,你也可以在签名方法中使用这个解决方案: @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start


Nik*_*las 7

SpringBoot 2.XX 及更新版本

如果您使用依赖spring-boot-starter-web版本2.0.0.RELEASE或更高版本,则不再需要显式包含jackson-datatype-jsr310依赖,这已经spring-boot-starter-web通过 through提供了spring-boot-starter-json

这被解析为春季启动问题#9297答案 依然有效并且切合实际:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
@RequestMapping(value = "datetime", method = RequestMethod.POST)
public void foo(@RequestParam("dateTime") 
                @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime ldt) {
    // IMPLEMENTATION
}
Run Code Online (Sandbox Code Playgroud)