Как принять параметры даты в запросе GET к Spring MVC Controller?

122

У меня есть запрос GET, который отправляет дату в формате YYYY-MM-DD в Spring Controller. Код контроллера следующий:

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

Запрос отправлен правильно, так как я проверяю с помощью Firebug. Я получаю сообщение об ошибке:

Состояние HTTP 400: запрос, отправленный клиентом, был синтаксически неверным.

Как я могу заставить контроллер принимать этот формат даты? Пожалуйста помоги. Что я делаю не так?

LittleLebowski
источник

Ответы:

250

Хорошо, я решил. Написание для тех, кто устал после целого дня непрерывного программирования и пропустил такую ​​глупость.

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

Да все просто. Просто добавьте аннотацию DateTimeFormat.

LittleLebowski
источник
18
Я собирался написать ответ, но ты победил меня. Вы также можете использовать @DateTimeFormat (iso = ISO.DATE), который имеет тот же формат. Кстати, если вы можете, я предлагаю вам использовать библиотеку Joda DateTime. Spring очень хорошо это поддерживает.
Лучано
Ответ в целом ОК, НО! Есть ли способ настроить его по умолчанию на Spring? Это немного излишне вставлять @DateTimeFormatкаждый контроллер, который у вас есть ...
торинкор
3
@Luciano, конечно, вы также можете использовать @DateTimeFormat (iso = ISO.DATE_TIME)
kiedysktos
2
@thorinkor В Spring Boot вы можете установить spring.mvc.date-formatатрибут application.propertiesили добавить bean-компоненты, которые реализуют org.springframework.formatинтерфейс (расширение org.springframework.format.datetime.DateFormatter, вероятно, является выходом). В незагрузочном Spring вы можете метод и добавлять Formatter реализующих бобов там. @OverrideaddFormattersWebMvcConfigurerAdapter
UTF_or_Death
10

Это то, что я сделал, чтобы получить отформатированную дату из интерфейса.

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

Вы можете использовать его, чтобы получить то, что хотите.

Абдуссалама
источник
11
Не понял. Какой смысл добавлять @ DateTimeFormat в @ PathVariable, если вы получаете dateString как String, а не как Date?
ILya Cyclone
7

... или вы можете сделать это правильно и иметь согласованное правило для сериализации / десериализации дат во всем вашем приложении. поместите это в application.properties:

spring.mvc.date-format=yyyy-MM-dd
Пол Т
источник
Не работает с типами даты Java 8.
Деннис
3

Нижеприведенное решение отлично работает для приложения с весенней загрузкой.

контроллер:

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

Итак, в вызывающей программе (в моем случае это веб-поток) нам нужно передать дату и время в этом формате ( «гггг-ММ-дд ЧЧ: мм: сс» ).

Сторона звонящего:

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

Ура !!

Аман Гоэль
источник
2

Если вы хотите использовать PathVariable, вы можете использовать приведенный ниже пример метода (все методы действуют одинаково):

//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"
}
Давид Иисус
источник