前提・実現したいこと
Spring Bootで、クエリストリングで受け取った日時の値をLocalDateTime型で受け取ろうとしていますが、値を受け取れず、BindExceptionが発生します。
同じように実装しているLocalDate型の変数は日付を受け取ることができます。
LocalDateTimeの場合は特別なやり方があるのでしょうか。
発生している問題・エラーメッセージ
アクセスしたURL: http://localhost:9080/?dateTime=2016/05/11%2012:34:56
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'sampleParameter' on field 'dateTime': rejected value [2016/05/11 12:34:56]; codes [typeMismatch.sampleParameter.dateTime,typeMismatch.dateTime,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [sampleParameter.dateTime,dateTime]; arguments []; default message [dateTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'dateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2016/05/11 12:34:56'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2016/05/11 12:34:56]] at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:164) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.19.jar:9.0.19] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.19.jar:9.0.19] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.19.jar:9.0.19] // 中略 at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 2019-08-15 15:51:15.354 WARN 7076 --- [nio-9080-exec-6] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'sampleParameter' on field 'dateTime': rejected value [2016/05/11 12:34:56]; codes [typeMismatch.sampleParameter.dateTime,typeMismatch.dateTime,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [sampleParameter.dateTime,dateTime]; arguments []; default message [dateTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'dateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2016/05/11 12:34:56'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2016/05/11 12:34:56]]]
該当のソースコード
JsonComponents.java
java
1package sample.components; 2 3import java.io.IOException; 4import java.time.LocalDate; 5import java.time.LocalDateTime; 6import java.time.format.DateTimeFormatter; 7 8import org.springframework.boot.jackson.JsonComponent; 9 10import com.fasterxml.jackson.core.JsonGenerator; 11import com.fasterxml.jackson.core.JsonParser; 12import com.fasterxml.jackson.core.JsonProcessingException; 13import com.fasterxml.jackson.databind.DeserializationContext; 14import com.fasterxml.jackson.databind.JsonDeserializer; 15import com.fasterxml.jackson.databind.JsonSerializer; 16import com.fasterxml.jackson.databind.SerializerProvider; 17 18@JsonComponent 19public class JsonComponents { 20 21 // 22 // LocalDateTime 23 // 24 25 static final DateTimeFormatter dateTimePattern = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); 26 27 public static class LocalDateTimeJsonSerializer extends JsonSerializer<LocalDateTime> { 28 29 @Override 30 public void serialize(LocalDateTime value, JsonGenerator generator, SerializerProvider serializers) 31 throws IOException { 32 33 if (value == null) { 34 generator.writeNull(); 35 } else { 36 generator.writeString(dateTimePattern.format(value)); 37 } 38 } 39 } 40 41 public static class LocalDateTimeJsonDeserializer extends JsonDeserializer<LocalDateTime> { 42 43 @Override 44 public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) 45 throws IOException, JsonProcessingException { 46 47 var value = parser.getValueAsString(); 48 49 return value == null ? null : LocalDateTime.parse(value, dateTimePattern); 50 } 51 } 52 53 // 54 // LocalDate 55 // 56 57 static final DateTimeFormatter datePattern = DateTimeFormatter.ofPattern("yyyy/MM/dd"); 58 59 public static class LocalDateJsonSerializer extends JsonSerializer<LocalDate> { 60 61 @Override 62 public void serialize(LocalDate value, JsonGenerator generator, SerializerProvider serializers) 63 throws IOException { 64 65 if (value == null) { 66 generator.writeNull(); 67 } else { 68 generator.writeString(datePattern.format(value)); 69 } 70 } 71 } 72 73 public static class LocalDateJsonDeserializer extends JsonDeserializer<LocalDate> { 74 75 @Override 76 public LocalDate deserialize(JsonParser parser, DeserializationContext context) 77 throws IOException, JsonProcessingException { 78 79 var value = parser.getValueAsString(); 80 81 return value == null ? null : LocalDate.parse(value, datePattern); 82 } 83 } 84}
SampleController.java
java
1package sample.controllers; 2 3import java.time.LocalDate; 4import java.time.LocalDateTime; 5import java.util.LinkedHashMap; 6import java.util.Map; 7 8import org.springframework.web.bind.annotation.GetMapping; 9import org.springframework.web.bind.annotation.ModelAttribute; 10import org.springframework.web.bind.annotation.RestController; 11 12import lombok.Data; 13import lombok.extern.slf4j.Slf4j; 14 15@RestController 16@Slf4j 17public class SampleController { 18 @GetMapping(path = "/") 19 public Map<String, Object> getContents(@ModelAttribute SampleParameter param) { 20 21 log.info("param={}", param); 22 23 var responseBody = new LinkedHashMap<String, Object>(); 24 responseBody.put("succeeded", true); 25 return responseBody; 26 } 27 28 @Data 29 public static class SampleParameter { 30 LocalDateTime dateTime; 31 LocalDate date; 32 } 33}
試したこと
LocalDate型の変数dateもLocalDateTimeと同じように書いていますが、dateの方は問題なく値を受け取れます。
日付を受け取るときのURL: http://localhost:9080/?date=2016/05/11
そのときのレスポンスボディ {"succeeded":true}
補足情報(FW/ツールのバージョンなど)
Spring Boot 2.1.5.RELEASE, Java 11

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/15 10:48