147

I've a GET request that sends a date in YYYY-MM-DD format to a Spring Controller. The controller code is as follows:

@RequestMapping(value="/fetch" , method=RequestMethod.GET)
    public @ResponseBody String fetchResult(@RequestParam("from") Date fromDate) {
        //Content goes here
    }

The request is sent correctly as I'm checking with Firebug. I get the error:

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

How can I make the controller accept this format of Date? Please help. What am I doing wrong?

MD XF
  • 7,860
  • 7
  • 40
  • 71
LittleLebowski
  • 7,691
  • 13
  • 47
  • 72
  • 1
    I guess your Date is from java.util.Date because provided answers so not work with Java.sql.Date – pixel Oct 31 '21 at 14:39

7 Answers7

289

Ok, I solved it. Writing it for anyone who might be tired after a full day of non-stop coding & miss such a silly thing.

@RequestMapping(value="/fetch" , method=RequestMethod.GET)
    public @ResponseBody String fetchResult(@RequestParam("from") @DateTimeFormat(pattern="yyyy-MM-dd") Date fromDate) {
        //Content goes here
    }

Yes, it's simple. Just add the DateTimeFormat annotation.

LittleLebowski
  • 7,691
  • 13
  • 47
  • 72
  • 23
    I was going to write an answer but you beat me. You can also use @DateTimeFormat(iso=ISO.DATE), which is the same format. BTW, if you can I suggest that you use the Joda DateTime library. Spring supports it really well. – Luciano Mar 01 '13 at 19:06
  • 1
    The answer is generally ok, BUT! Is there a way to configure it as a default to Spring? It's a little bit overkill to put `@DateTimeFormat` in every controller you have... – thorinkor Dec 09 '16 at 12:23
  • 3
    @Luciano of course you can do @DateTimeFormat(iso = ISO.DATE_TIME) as well – kiedysktos Jan 23 '17 at 11:44
  • 2
    @thorinkor In Spring Boot you can set the `spring.mvc.date-format` attribute in `application.properties` or add beans that implement the `org.springframework.format` interface (extending `org.springframework.format.datetime.DateFormatter` is probably the way to go). In non-Boot Spring you can `@Override` the `addFormatters` method of `WebMvcConfigurerAdapter` and add your Formatter-implementing beans there. – UTF_or_Death Feb 17 '17 at 15:59
  • People should be aware that :@DateTimeFormat' does not work with 'java.sql.Date' but with 'java.util' dates – pixel Nov 01 '21 at 12:23
15

... or you can do it the right way and have a coherent rule for serialisation/deserialisation of dates all across your application. put this in application.properties:

spring.mvc.date-format=yyyy-MM-dd
Paul T
  • 396
  • 3
  • 7
  • It doesn't work, tried it using pattern, iso, sane issue, cannot convert string to date – pixel Oct 31 '21 at 14:31
  • Btw, are you using java.util.Date or kava.sql.Date? This is not working with Java.sql.Date – pixel Oct 31 '21 at 14:34
14

This is what I did to get formatted date from front end

  @RequestMapping(value = "/{dateString}", method = RequestMethod.GET)
  @ResponseBody
  public HttpStatus getSomething(@PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String dateString) {
   return OK;
  }

You can use it to get what you want.

AbdusSalam
  • 485
  • 5
  • 13
  • 11
    Didn't get it. What's the point of adding @​DateTimeFormat to @​PathVariable if you receive dateString as String, not as Date? – ILya Cyclone Nov 27 '17 at 16:13
7

Below solution perfectly works for spring boot application.

Controller:

@GetMapping("user/getAllInactiveUsers")
List<User> getAllInactiveUsers(@RequestParam("date") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") Date dateTime) {
    return userRepository.getAllInactiveUsers(dateTime);
}

So in the caller (in my case its a web flux), we need to pass date time in this("yyyy-MM-dd HH:mm:ss") format.

Caller Side:

public Flux<UserDto> getAllInactiveUsers(String dateTime) {
    Flux<UserDto> userDto = RegistryDBService.getDbWebClient(dbServiceUrl).get()
            .uri("/user/getAllInactiveUsers?date={dateTime}", dateTime).retrieve()
            .bodyToFlux(User.class).map(UserDto::of);
    return userDto;
}

Repository:

@Query("SELECT u from User u  where u.validLoginDate < ?1 AND u.invalidLoginDate < ?1 and u.status!='LOCKED'")
List<User> getAllInactiveUsers(Date dateTime);

Cheers!!

Aman Goel
  • 3,351
  • 1
  • 21
  • 17
4

If you want to use a PathVariable, you can use an example method below (all methods are and do the same):

//You can consume the path .../users/added-since1/2019-04-25
@GetMapping("/users/added-since1/{since}")
public String userAddedSince1(@PathVariable("since") @DateTimeFormat(pattern = "yyyy-MM-dd") Date since) {
    return "Date: " + since.toString(); //The output is "Date: Thu Apr 25 00:00:00 COT 2019"
}

//You can consume the path .../users/added-since2/2019-04-25
@RequestMapping("/users/added-since2/{since}")
public String userAddedSince2(@PathVariable("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date since) {
    return "Date: " + since.toString(); //The output is "Date: Wed Apr 24 19:00:00 COT 2019"
}

//You can consume the path .../users/added-since3/2019-04-25
@RequestMapping("/users/added-since3/{since}")
public String userAddedSince3(@PathVariable("since") @DateTimeFormat(pattern = "yyyy-MM-dd") Date since) {
    return "Date: " + since.toString(); //The output is "Date: Thu Apr 25 00:00:00 COT 2019"
}
David Jesus
  • 1,981
  • 2
  • 29
  • 34
1

You can use :

public @ResponseBody String fetchResult(@RequestParam("from")@DateTimeFormat(pattern="yyyy-MM-dd") Date fromDate) { //Your code...

}
Sourabh Bhavsar
  • 301
  • 3
  • 3
1

2000-10-31T01:30:00.000-05:00 convert to Datetime (Joda)

@GetMapping("test/{dateTimeStart}")
public void getCheckDaily2(
        @PathVariable(value = "dateTimeStart", required = false)
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
                DateTime dateTimeStart){

body here...
}