Wie akzeptiere ich Datumsparameter in einer GET-Anfrage an Spring MVC Controller?


122

Ich habe eine GET-Anfrage, die ein Datum im Format JJJJ-MM-TT an einen Spring Controller sendet. Der Controller-Code lautet wie folgt:

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

Die Anfrage wird korrekt gesendet, da ich mich bei Firebug erkundige. Ich bekomme den Fehler:

HTTP-Status 400: Die vom Client gesendete Anforderung war syntaktisch falsch.

Wie kann ich den Controller dazu bringen, dieses Datumsformat zu akzeptieren? Bitte helfen Sie. Was mache ich falsch?

Antworten:


250

Ok, ich habe es gelöst. Schreiben Sie es für alle, die nach einem ganzen Tag ununterbrochener Codierung müde sein könnten und eine so dumme Sache verpassen.

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

Ja, das ist einfach. Fügen Sie einfach die DateTimeFormat-Annotation hinzu.


18
Ich wollte eine Antwort schreiben, aber du hast mich geschlagen. Sie können auch @DateTimeFormat (iso = ISO.DATE) verwenden, das das gleiche Format hat. Übrigens, wenn Sie können, schlage ich vor, dass Sie die Joda DateTime-Bibliothek verwenden. Der Frühling unterstützt es sehr gut.
— Luciano

Die Antwort ist im Allgemeinen in Ordnung, ABER! Gibt es eine Möglichkeit, es als Standard für Spring zu konfigurieren? Es ist ein bisschen übertrieben, @DateTimeFormatjeden Controller
— einzubauen, den

3
@ Luciano natürlich können Sie auch @DateTimeFormat (iso = ISO.DATE_TIME) tun
— kiedysktos

2
@thorinkor In Spring Boot können Sie das spring.mvc.date-formatAttribut in festlegen application.propertiesoder Beans hinzufügen, die die org.springframework.formatSchnittstelle implementieren (Erweiterung org.springframework.format.datetime.DateFormatterist wahrscheinlich der richtige Weg). In Nicht-Boot Spring können Sie @Overridedie addFormattersMethode WebMvcConfigurerAdapterund Hinzufügen Ihrer Formatter-implementierenden Beans dort.
— UTF_or_Death

10

Dies ist, was ich getan habe, um ein formatiertes Datum vom Frontend zu erhalten

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

Sie können es verwenden, um zu bekommen, was Sie wollen.


11
Ich habe es nicht verstanden. Was bringt es, @ DateTimeFormat zu @ PathVariable hinzuzufügen, wenn Sie dateString als String und nicht als Date erhalten?
— ILya Cyclone

7

... oder Sie können es richtig machen und eine kohärente Regel für die Serialisierung / Deserialisierung von Daten in Ihrer gesamten Anwendung festlegen. Fügen Sie dies in application.properties ein:

spring.mvc.date-format=yyyy-MM-dd

3

Die folgende Lösung funktioniert perfekt für die Federstiefelanwendung.

Regler:

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

Im Aufrufer (in meinem Fall handelt es sich um einen Web-Flux) müssen wir also die Datums- und Uhrzeitangabe in diesem Format ( "JJJJ-MM-TT HH: MM: SS" ) übergeben.

Anruferseite:

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);

Prost!!


2

Wenn Sie eine PathVariable verwenden möchten, können Sie unten eine Beispielmethode verwenden (alle Methoden sind und tun dasselbe):

//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"
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.