จะยอมรับพารามิเตอร์วันที่ในคำขอ 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 Status 400: คำร้องขอที่ไคลเอ็นต์ส่งไปนั้นไม่ถูกต้องตามหลักไวยากรณ์

ฉันจะทำให้คอนโทรลเลอร์ยอมรับรูปแบบของวันที่นี้ได้อย่างไร กรุณาช่วย. ผมทำอะไรผิดหรือเปล่า?

คำตอบ:


250

โอเคฉันแก้ไขแล้ว เขียนไว้เผื่อใครอาจจะเหนื่อยหลังจากเขียนโค้ดแบบไม่หยุดมาทั้งวันและพลาดเรื่องโง่ ๆ แบบนี้

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

ใช่มันง่าย เพียงเพิ่มคำอธิบายประกอบ DateTimeFormat


18
ฉันกำลังจะเขียนคำตอบ แต่คุณเอาชนะฉัน คุณยังสามารถใช้ @DateTimeFormat (iso = ISO.DATE) ซึ่งเป็นรูปแบบเดียวกัน BTW ถ้าคุณสามารถแนะนำให้คุณใช้ไลบรารี Joda DateTime สปริงรองรับได้ดีจริงๆ
Luciano

คำตอบคือโอเค แต่! มีวิธีกำหนดค่าเป็นค่าเริ่มต้นของ Spring หรือไม่? มันเกินความสามารถเล็กน้อยที่จะใส่@DateTimeFormatคอนโทรลเลอร์ทุกตัวที่คุณมี ...
thorinkor

3
@Luciano แน่นอนคุณสามารถทำได้ @DateTimeFormat (iso = ISO.DATE_TIME) เช่นกัน
kiedysktos

2
@thorinkor ใน Spring Boot คุณสามารถตั้งค่าspring.mvc.date-formatแอตทริบิวต์ในapplication.propertiesหรือเพิ่มถั่วที่ใช้org.springframework.formatอินเทอร์เฟซได้ (การขยายorg.springframework.format.datetime.DateFormatterอาจเป็นวิธีที่จะไป) ใน non-Boot Spring คุณสามารถ@Overrideใช้addFormattersวิธีการWebMvcConfigurerAdapterและเพิ่มถั่วที่ใช้ฟอร์แมตเตอร์ได้ที่นั่น
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 Date
เดนนิส

3

โซลูชันด้านล่างทำงานได้อย่างสมบูรณ์แบบสำหรับการใช้งานสปริงบูต

ควบคุม:

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

ดังนั้นในผู้โทร (ในกรณีของฉันคือเว็บฟลักซ์) เราต้องส่งวันเวลาในรูปแบบนี้ ( "yyyy-MM-dd HH: mm: ss" )

ด้านผู้โทร:

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

พื้นที่เก็บข้อมูล:

@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"
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.