3

I'm trying to get an ISO String with @RequestParam and parse it to a Date.

Using code below, I tried to test with http://localhost:8989/api/v1/test?date=2019-08-19%2000:00:00.000+0000

But the result was 400 Bad Request, When I changed the type of date value to String, it was 2019-08-19 00:00:00.000 0000.

public class myController {

    @GetMapping(value = "/api/{version}/test", produces = "application/json")
    public ResponseEntity<MyList> getFreeList(
        @PathVariable
        String version,
        @RequestParam("date")
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSZ")
        Optional<Date> date) {
            return new ResponseEntity<>(myService.getList(
                date.orElse(null)),
                HttpStatus.OK);
    }
}

I can't change the URL format. How to get the plus sign properly?

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
PythonQQ
  • 101
  • 1
  • 2
  • 8

3 Answers3

3

Url parameters must be encoded

It's the caller's responsibility to do so. If the caller uses Java, he can simply set the value to be:

URLEncoder.encode("2019-08-19 000:00:00.000+0000", "UTF-8");

Which will be resolved to

2019-08-19%2000:00:00.000%2B0000
Eyal
  • 1,748
  • 2
  • 17
  • 31
2

This is a known behavior, you can send %2B instead of +

http://localhost:8989/api/v1/test?date=2019-08-19%2000:00:00.000%2B0000

embedded tomcat server which does this translation and spring doesn't even participate in this. There is no config to change this behaviour as seen in the class code. So you have to live with it

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • It's not a "known issue", it's by spec: https://en.wikipedia.org/wiki/Percent-encoding – Eyal Aug 20 '19 at 07:00
0

Here is a quick test on my laptop. My Controller

 @GetMapping(value = "/api/{version}/test", produces = "application/json")
    public SuccessResult getFreeList(@PathVariable String version,
            @RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Date date) {
        System.out.println(date);
        SuccessResult result = new SuccessResult();
        result.setDate(date);
        return result;
    }

My Output object

public class SuccessResult {

    String message = "success";

    Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

The url to hit the endpoint

http://localhost:8080/api/v1/test?date=2019-08-19T00:00:00.000%2B00:00

The result

{"message":"success","date":1566172800000}
Shailendra
  • 8,874
  • 2
  • 28
  • 37