2011-09-12 41 views
15

Trong ứng dụng web MVC của tôi, tôi có bộ điều khiển RESTful chung cho các hoạt động CRUD. Và mỗi bộ điều khiển cụ thể phải khai báo một số @RequestMapping, ví dụ: /foo. Bộ điều khiển chung xử lý mọi yêu cầu đến /foo/foo/{id}.Kế thừa và định tuyến bộ điều khiển MVC Spring

Nhưng bây giờ tôi cần viết một bộ điều khiển CRUD phức tạp hơn, sẽ nhận được các tham số yêu cầu bổ sung hoặc biến đường dẫn, ví dụ: /foo/{date}/foo/{id}/{date}. Vì vậy, tôi mở rộng bộ điều khiển CRUD chung của mình và viết phương thức quá tải fetch(id, date) sẽ xử lý cả hai số {id}{date}. Đó không phải là vấn đề.

Nhưng tôi cũng cần phải 'vô hiệu hóa' triển khai fetch(id) bắt nguồn từ lớp cơ sở (tài nguyên không được có sẵn tại /foo/{id} nữa, chỉ tại /foo/{id}/{date}). Ý tưởng duy nhất tôi đưa ra là để ghi đè lên phương pháp này trong bộ điều khiển cụ thể của tôi, để ánh xạ nó trên một uri giả và trả lại null. Nhưng điều này trông giống như hack bẩn xấu xí bởi vì chúng tôi phơi bày một số uri tài nguyên giả, thay vì vô hiệu hóa nó. Có thể có một thực hành tốt hơn?

Bất kỳ ý tưởng nào?

//My generic CRUD controller 
public abstract class AbstractCRUDControllerBean<E, PK extends Serializable> implements AbstractCRUDController<E, PK> { 

    @RequestMapping(method=RequestMethod.GET) 
    public @ResponseBody ResponseEntity<E[]> fetchAll() { ... } 

    @RequestMapping(value="/{id}", method=RequestMethod.GET) 
    public @ResponseBody ResponseEntity<E> fetch(@PathVariable("id") PK id) { ... } 

    @RequestMapping(method=RequestMethod.POST) 
    public @ResponseBody ResponseEntity<E> add(@RequestBody E entity) { ... } 

    @RequestMapping(value="/{id}", method=RequestMethod.PUT) 
    public @ResponseBody ResponseEntity<E> update(@PathVariable("id") PK id, @RequestBody E entity) { ... } 

    @RequestMapping(value="/{id}", method=RequestMethod.DELETE) 
    public @ResponseBody ResponseEntity<E> remove(@PathVariable("id") PK id) { .. } 
} 

.

//Concrete controller, working with Foo entities 
@Controller 
@RequestMapping("/foo") 
public class FooControllerImpl extends 
     AbstractCRUDControllerBean<Foo, Long> implements FooController { 

    //ugly overriding parent's method 
    @RequestMapping(value="/null",method=RequestMethod.GET) 
    public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id) { 
    return null; 
    } 

    //new fetch implementation 
    @RequestMapping(value="/{id}/{date}", method=RequestMethod.GET) 
    public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id, @PathVariable("date") Date date) { .... } 

} 

Trả lời

18

Bạn đang cố gắng đạt được loại tài nguyên, loại nguồn cấp dữ liệu của áo bằng cách sử dụng mùa xuân? Điều đó có thể không trực tiếp có thể. Thay vì khai báo dịch vụ RESTful chung làm bộ điều khiển, tại sao bạn không ủy thác nó cho họ?

//My generic CRUD Operations 
public abstract class AbstractCRUDControllerBean<E, PK extends Serializable> implements AbstractCRUDController<E, PK> { 

    public ResponseEntity<E[]> fetchAll() { ... } 

    public ResponseEntity<E> fetch(@PathVariable("id") PK id) { ... } 

    public ResponseEntity<E> add(@RequestBody E entity) { ... } 

    public ResponseEntity<E> update(@PathVariable("id") PK id, @RequestBody E entity) { ... } 

    public ResponseEntity<E> remove(@PathVariable("id") PK id) { .. } 
} 

và ủy quyền trong bộ điều khiển.

//Concrete controller, working with Foo entities 
@Controller 
@RequestMapping("/foo") 
public class FooControllerImpl extends 
     AbstractCRUDControllerBean<Foo, Long> implements FooController { 

    //we are interested in using fetchall but not others 
    @RequestMapping(method=RequestMethod.GET) 
    public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id) { 
    return fetchAll(); 
    } 

    //fetch with id and date 
    @RequestMapping(value="/{id}/{date}", method=RequestMethod.GET) 
    public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id, @PathVariable("date") Date date) { .... } 

} 

cũng có, bạn có thể lập bản đồ phương pháp dựa trên sự sẵn có của các thông số quá,

@RequestMapping(value="/{id}/{date}", params={"param1","param2","!param3"}) 
public @ResponseBody ResponseEntity<E> customFetch(@PathVariable("id") PK id, 
      @PathVariable("date") Date date, @RequestParam("param1") String param1,     
      @RequestParam("param2") String param2) {...} 

này bản đồ phương pháp/foo/id/ngày khi param1 và param2 tồn tại và param3 không tồn tại.

+0

Cảm ơn ý tưởng của bạn. Nó phù hợp rất tốt với nhu cầu của tôi. Đôi khi, khi bạn bị mắc kẹt, mọi thứ bạn cần là thay đổi quan điểm) – Nofate

+0

+1 câu trả lời hay và giải thích rõ ràng – andyb

Các vấn đề liên quan