¿Cómo aceptar parámetros de fecha en una solicitud GET a Spring MVC Controller?


122

Tengo una solicitud GET que envía una fecha en formato AAAA-MM-DD a un controlador Spring. El código del controlador es el siguiente:

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

La solicitud se envía correctamente ya que estoy comprobando con Firebug. Me sale el error:

Estado HTTP 400: la solicitud enviada por el cliente era sintácticamente incorrecta.

¿Cómo puedo hacer que el controlador acepte este formato de fecha? Por favor ayuda. ¿Qué estoy haciendo mal?

Respuestas:


250

Ok, lo resolví. Escribiéndolo para cualquiera que pueda estar cansado después de un día completo de codificación sin parar y perderse una cosa tan tonta.

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

Si, es simple. Simplemente agregue la anotación DateTimeFormat.


18
Iba a escribir una respuesta pero me ganaste. También puede usar @DateTimeFormat (iso = ISO.DATE), que es el mismo formato. Por cierto, si puede, le sugiero que use la biblioteca Joda DateTime. Spring lo soporta realmente bien.
— Luciano

La respuesta es generalmente buena, ¡PERO! ¿Hay alguna forma de configurarlo como predeterminado en Spring? Es un poco exagerado para poner @DateTimeFormaten cada controlador tiene ...
— thorinkor

3
@Luciano, por supuesto, también puede hacer @DateTimeFormat (iso = ISO.DATE_TIME)
— kiedysktos

2
@thorinkor En Spring Boot puede establecer el spring.mvc.date-formatatributo application.propertieso agregar beans que implementen la org.springframework.formatinterfaz (extender org.springframework.format.datetime.DateFormatteres probablemente el camino a seguir). En no Boot Spring, puede usar @Overrideel addFormattersmétodo WebMvcConfigurerAdaptery agregar sus beans de implementación del formateador allí.
— UTF_or_Death

10

Esto es lo que hice para obtener la fecha formateada desde la interfaz

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

Puedes usarlo para conseguir lo que quieras.


11
No lo entendí. ¿Cuál es el punto de agregar @ DateTimeFormat a @ PathVariable si recibe dateString como String, no como Date?
— ILya Cyclone

7

... o puede hacerlo de la manera correcta y tener una regla coherente para la serialización / deserialización de fechas en toda su aplicación. poner esto en application.properties:

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

No funciona con los tipos de fecha de Java 8.
— Dennis hace

3

La siguiente solución funciona perfectamente para la aplicación de arranque de primavera.

Controlador:

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

Entonces, en la persona que llama (en mi caso es un flujo web), necesitamos pasar la fecha y hora en este formato ( "aaaa-MM-dd HH: mm: ss" ).

Lado de la persona que llama:

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

Repositorio:

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

¡¡Salud!!


2

Si desea usar una PathVariable, puede usar un método de ejemplo a continuación (todos los métodos son y hacen lo mismo):

//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"
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.