我在尝试使用Spring启动时遇到异常。它无法转换请求参数。我在这里错过了什么?如何在Spring启动中自定义请求数据类型转换器?
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]
我的控制器方法看起来像这样。
@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;
}
}
application.properties
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>
答案 0 :(得分:0)
您可以通过创建实现JsonDeserializer的类然后将它们添加到Jackson的ObjectMapper来实现此目的。
此配置类的示例:
@Configuration
public class JacksonConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(LocalDate.class, new JsonDateDeserializer());
simpleModule.addDeserializer(OffsetDateTime.class, new JsonDateTimeDeserializer());
objectMapper.registerModule(simpleModule);
return objectMapper;
}
}
JsonDateDeserializer和JsonDateTimeDeserializer是您的类,您使用正确的模式格式实现转换。
答案 1 :(得分:-1)