Làm thế nào để chấp nhận các tham số Ngày trong một yêu cầu GET tới Bộ điều khiển Spring MVC?


122

Tôi đã yêu cầu GET gửi một ngày tháng ở định dạng YYYY-MM-DD tới Bộ điều khiển mùa xuân. Mã bộ điều khiển như sau:

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

Yêu cầu được gửi chính xác khi tôi đang kiểm tra bằng Firebug. Tôi gặp lỗi:

Trạng thái HTTP 400: Yêu cầu do khách hàng gửi không chính xác về mặt cú pháp.

Làm cách nào để tôi có thể làm cho bộ điều khiển chấp nhận định dạng Ngày này? Xin vui lòng giúp đỡ. Tôi đang làm gì sai?

Câu trả lời:


250

Ok, tôi đã giải quyết nó. Viết nó cho bất kỳ ai có thể cảm thấy mệt mỏi sau một ngày viết mã không ngừng nghỉ và bỏ lỡ một điều ngớ ngẩn như vậy.

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

Vâng, nó đơn giản. Chỉ cần thêm chú thích DateTimeFormat.


18
Tôi đã định viết một câu trả lời nhưng bạn đã đánh bại tôi. Bạn cũng có thể sử dụng @DateTimeFormat (iso = ISO.DATE), có định dạng tương tự. BTW, nếu bạn có thể, tôi đề nghị bạn sử dụng thư viện Joda DateTime. Mùa xuân hỗ trợ nó thực sự tốt.
Luciano

Câu trả lời nói chung là ok, NHƯNG! Có cách nào để cấu hình nó làm mặc định cho Spring không? Đó là một chút quá mức cần thiết để đặt @DateTimeFormattrong mỗi bộ điều khiển bạn có ...
thorinkor

3
@Luciano tất nhiên bạn có thể làm @DateTimeFormat (iso = ISO.DATE_TIME) cũng
kiedysktos

2
@thorinkor Trong Spring Boot, bạn có thể đặt spring.mvc.date-formatthuộc tính trong application.propertieshoặc thêm các bean triển khai org.springframework.formatgiao diện (mở rộng org.springframework.format.datetime.DateFormattercó lẽ là cách để thực hiện). Trong Non-Boot Spring, bạn có thể @Overridesử dụng addFormattersphương thức WebMvcConfigurerAdaptervà thêm các bean triển khai Formatter của mình vào đó.
UTF_or_Death

10

Đây là những gì tôi đã làm để có được ngày được định dạng từ giao diện người dùng

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

Bạn có thể sử dụng nó để đạt được những gì bạn muốn.


11
Không hiểu. Việc thêm @ DateTimeFormat vào @ PathVariable nếu bạn nhận dateString là String, không phải Date thì có ích gì?
Lốc xoáy ILya

7

... hoặc bạn có thể làm đúng cách và có một quy tắc nhất quán để tuần tự hóa / xác định ngày tháng trên toàn bộ ứng dụng của bạn. đưa cái này vào application.properties:

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

3

Giải pháp dưới đây hoạt động hoàn hảo cho ứng dụng khởi động mùa xuân.

Bộ điều khiển:

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

Vì vậy, trong trình gọi (trong trường hợp của tôi là thông lượng web), chúng ta cần chuyển thời gian ngày ở định dạng ( "yyyy-MM-dd HH: mm: ss" ).

Bên người gọi:

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

Kho:

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

Chúc mừng !!


2

Nếu bạn muốn sử dụng PathVariable, bạn có thể sử dụng một phương pháp ví dụ bên dưới (tất cả các phương pháp đều giống nhau):

//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"
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.