尝试使用 Spring Boot 时出现以下异常。它无法转换请求参数。我在这里想念什么?如何在 Spring Boot 中自定义请求数据类型转换器?
2018-02-23 17:05:11.868 WARN 13976 --- [nio-9988-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@io.swagger.annotations.ApiParam @org.springframework.web.bind.annotation.RequestParam java.time.LocalDate] for value '2017-07-21'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2017-07-21]
2018-02-23 17:18:29.582 WARN 13976 --- [nio-9988-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.time.OffsetDateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@io.swagger.annotations.ApiParam @org.springframework.web.bind.annotation.RequestParam java.time.OffsetDateTime] for value '2017-07-21T17:32:28Z'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2017-07-21T17:32:28Z]
我的 Controller 方法如下所示。
@RequestMapping(value = "/mypath/status",
produces = { "application/json" },
method = RequestMethod.GET)
default ResponseEntity<MyStatusResponse> _getMyStatusByQuery(@RequestHeader(value="myId", required=true) Integer myId,
@Valid @RequestParam(value = "param1", required = false) String param1,
@Valid @RequestParam(value = "param2", required = false) String param2,
@Valid @RequestParam(value = "dueDateStart", required = false) LocalDate dueDateStart,
@Valid @RequestParam(value = "dueDateEnd", required = false) LocalDate dueDateEnd,
@Valid @RequestParam(value = "sentOnEnd", required = false) OffsetDateTime sentOnEnd) {
return getMyStatusByQuery(myId, param1, param2, dueDateStart, dueDateEnd, sentOnStart, sentOnEnd);
}
我还为 OffsetDateTime 添加了转换器(基本上这是由 swagger 生成的)
public class RFC3339DateFormat extends ISO8601DateFormat {
// Same as ISO8601DateFormat but serializing milliseconds.
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
String value = ISO8601Utils.format(date, true);
toAppendTo.append(value);
return toAppendTo;
}
}
应用程序属性
spring.jackson.date-format=my.test.RFC3339DateFormat
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
以下是我的 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.jigarshah.api</groupId>
<artifactId>test-me</artifactId>
<packaging>jar</packaging>
<name>test-me</name>
<version>1.0.0</version>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<springfox-version>2.8.0</springfox-version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!--SpringFox dependencies -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-version}</version>
</dependency>
<!-- XML processing: Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>