8

I'm not able to let this work:

@RequestMapping(value = "/people", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody
    List<IPerson> searchPerson(@RequestParam(value = "birthDay", required = false) @DateTimeFormat(pattern="yyyy-MM-dd") Date birthDay) {

with the request:

http://localhost:8080/rest/people?birthDay=2014-05-25

The error is always :

"HTTP Status 400 - The request sent by the client was syntactically incorrect".

I can't find any resource that give me a clear answer/guide to understand the underlying problem... could someone help me? Thanks!

Edit: Exception is:

Caused by: 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.util.Date for value '2010-10-10'; nested exception is java.lang.IllegalArgumentException
    at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:78)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:168)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:161)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:93)
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:61)

... 40 more
Caused by: java.lang.IllegalArgumentException
    at java.util.Date.parse(Date.java:615)
    at java.util.Date.<init>(Date.java:272)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:73)
    ... 45 more
Paolof76
  • 889
  • 1
  • 9
  • 23
  • Can you give an example request? If you call it from code, can you log or intercept the call? – GeertPt May 11 '15 at 09:01
  • Hi @greyfairer modified the code and added the request. Basically it's the Date that is causing my headaches... Thanks! – Paolof76 May 11 '15 at 09:04
  • Can you add a custom exception handler to see the full exception? E.g: @ControllerAdvice public class DefaultExceptionsControllerAdvice extends ResponseEntityExceptionHandler { – GeertPt May 11 '15 at 09:12
  • It's the same thing [here](http://stackoverflow.com/questions/20616319/the-request-sent-by-the-client-was-syntactically-incorrect-spring-mvc-jdbc-te). – cнŝdk May 11 '15 at 12:48
  • @chsdk not the same, I want to use \@DateTimeFormat(pattern=“yyyy-MM-dd”) or ISO but there is no way to let it work, while loads of people says it work, e.g.: http://codingexplained.com/coding/java/spring-framework/date-parameter-in-spring-mvc-controller – Paolof76 May 11 '15 at 13:18
  • @Paolof76 Maybe because it's `@RequestParam` and not `@PathVariable`, and as a parameter Spring parse it as String. – cнŝdk May 11 '15 at 13:23
  • See also: See also:http://stackoverflow.com/questions/23702041/failed-to-convert-property-value-of-type-java-lang-string-to-required-type-java/26533665#26533665 – borjab May 11 '15 at 14:22

2 Answers2

2

Finally I found the solution, maybe could be of use for others with the same issue. Just add this method to the controller:

@InitBinder
public void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setLenient(false);
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}

right in the documentation: http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-ann-webdatabinder

But still don't understand why @DateTimeFormat(pattern="yyyy-MM-dd") doesn't work... With this solution there is no need of DateTimeFormat, so I annotated the param like the others:

@RequestParam(required = false) Date birthDay
Paolof76
  • 889
  • 1
  • 9
  • 23
2

In the spring forum they said that you need to have a conversion service initialized in your configuration in order to use the Formatter automátically. Something like:

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"/>  

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="conversionService" ref="conversionService" />
        </bean>
    </property>
</bean> 
borjab
  • 11,149
  • 6
  • 71
  • 98
  • OK I'm glad I'm not the first to go through this ;) Thanks very useful the link, as it shows me the underlying (not well documented??) logic, +1 – Paolof76 May 11 '15 at 14:52