Come accettare i parametri della data in una richiesta GET a Spring MVC Controller?


122

Ho una richiesta GET che invia una data nel formato AAAA-MM-GG a uno Spring Controller. Il codice del controller è il seguente:

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

La richiesta viene inviata correttamente mentre sto controllando con Firebug. Ottengo l'errore:

Stato HTTP 400: la richiesta inviata dal client non era sintatticamente corretta.

Come posso fare in modo che il controller accetti questo formato di data? Per favore aiuto. Che cosa sto facendo di sbagliato?

Risposte:


250

Ok, l'ho risolto. Scriverlo per chiunque potrebbe essere stanco dopo un'intera giornata di programmazione senza interruzioni e perdere una cosa così sciocca.

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

Sì, è semplice. Basta aggiungere l'annotazione DateTimeFormat.


18
Stavo per scrivere una risposta ma mi hai battuto. Puoi anche usare @DateTimeFormat (iso = ISO.DATE), che è lo stesso formato. A proposito, se puoi ti suggerisco di utilizzare la libreria Joda DateTime. La primavera lo sostiene molto bene.
Luciano

La risposta è generalmente ok, MA! C'è un modo per configurarlo come predefinito per la primavera? È un po 'eccessivo inserire @DateTimeFormattutti i controller che hai ...
thorinkor

3
@Luciano ovviamente puoi fare anche @DateTimeFormat (iso = ISO.DATE_TIME)
kiedysktos

2
@thorinkor In Spring Boot è possibile impostare l' spring.mvc.date-formatattributo application.propertieso aggiungere bean che implementano l' org.springframework.formatinterfaccia (l'estensione org.springframework.format.datetime.DateFormatterè probabilmente la strada da percorrere). In non Boot Spring è possibile utilizzare @Overrideil addFormattersmetodo WebMvcConfigurerAdaptere aggiungere lì i bean che implementano il formattatore.
UTF_or_Death

10

Questo è quello che ho fatto per ottenere la data formattata dal front-end

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

Puoi usarlo per ottenere quello che vuoi.


11
Non ho capito. Qual è il punto di aggiungere @ DateTimeFormat a @ PathVariable se ricevi dateString come String, non come Date?
ILya Cyclone

7

... oppure puoi farlo nel modo giusto e avere una regola coerente per la serializzazione / deserializzazione delle date in tutta l'applicazione. mettilo in application.properties:

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

3

La soluzione sottostante funziona perfettamente per l'applicazione di avvio a molla.

controller:

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

Quindi nel chiamante (nel mio caso è un flusso web), dobbiamo passare la data e l'ora in questo formato ( "aaaa-MM-gg HH: mm: ss" ).

Lato chiamante:

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

Saluti!!


2

Se desideri utilizzare una variabile PathVariable, puoi utilizzare un metodo di esempio di seguito (tutti i metodi sono e fanno lo stesso):

//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"
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.