2011-01-14 33 views
7

Tôi đang cố gắng để có được đôi chân của tôi ướt với Spring MVC 3.0, và trong khi tôi có thể làm cho nó hoạt động, tôi dường như không thể xử lý kịch bản này một cách hiệu quả.Spring MVC 3.0: Làm cách nào để xác thực biến đường dẫn toàn cầu cho tất cả các ánh xạ yêu cầu một cách hiệu quả?

Tôi có một bộ điều khiển với xử lý "/ {studyName}/mô-đun" tiền tố, và nó trông giống như sau: -

@Controller 
@RequestMapping(value = "/{studyName}/module") 
public class ModuleController { 

    @RequestMapping(...) 
    public ModelAndView getA(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 

    @RequestMapping(...) 
    public ModelAndView getB(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 

    @RequestMapping(...) 
    public ModelAndView getC(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 

    @RequestMapping(...) 
    public ModelAndView getD(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 
} 

Vấn đề với mã này được, tôi phải xác nhận studyName rải rác tất cả qua các phương pháp và có thể trong các phương pháp của Bộ điều khiển khác. Có cách nào tôi có thể thực hiện xác nhận trên biến đường dẫn studyName tất cả trong một chỗ mà không sử dụng một cái gì đó như AOP? Làm thế nào để bạn xử lý xác nhận như thế này?

Cảm ơn.

Trả lời

2

Hiện tại, hơi khó để thực hiện điều này tự động, nhưng có thể. Bạn nên sử dụng một nhà cung cấp xác nhận Bean (JSR-303) thực hiện phụ lục C. Hiện tại đó là Apache BeanValidation hoặc Hibernate Validator 4.2 (đang trong giai đoạn thử nghiệm).

Thêm triển khai xác thực bean đã chọn của bạn vào đường dẫn lớp. Đây sẽ là việc thực hiện JSR-303 mà Spring MVC sử dụng.

Thứ hai, chú thích tham số phương thức với @Valid và bất kỳ chú thích ràng buộc nào, như @NonNull.

này sẽ giống như thế:

public ModelAndView getB(@Valid @NonNull @PathVariable String studyName, ...) { 

Điều đó sẽ làm việc. Sau đó bạn sẽ cần phải kiểm tra lỗi mùa xuân của bạn cho bất kỳ vấn đề.

Ngoài ra, nếu bạn không sử dụng bất kỳ thông số mùa xuân khác, bạn có thể đăng ký một validator với một InitBinder như vậy:

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    binder.setValidator(new StudyNameValidator()); 
} 
+0

+1 cho bạn. Tôi đã xem xét @valid, nhưng trong trường hợp của tôi, tôi có thể phải tạo chú thích xác nhận tùy chỉnh của mình vì tôi cần kiểm tra xem studyName có được đăng ký trong cơ sở dữ liệu của tôi hay không, vì vậy tôi không thể sử dụng tính năng xác thực được tích hợp từ trình xác thực hibernate. Đối với ràng buộc một validator, tôi vẫn cần phải kiểm tra "if (binder.hasErrors()) {làm cái gì đó}" trong mọi phương pháp của bộ điều khiển, đó là chính xác vấn đề tôi hiện đang phải đối mặt. Có lẽ, đó là giải pháp thanh lịch duy nhất có sẵn ngay bây giờ, nhưng nó thực sự lỗi tôi thấy rằng cùng một kiểm tra lặp đi lặp lại trong mọi phương pháp. – limc

+0

Nếu xác thực của bạn là kiểm tra xem có gì đó tồn tại trong DB hay không, giả sử nó có khả năng, tôi chỉ cần thực hiện truy vấn và đăng ký phương thức @ExceptionHandler để xử lý trường hợp không xảy ra. – GaryF

+1

Theo như tôi có thể nói, bạn không thể sử dụng chú thích hợp lệ với PathVariable: https://jira.springsource.org/browse/SPR-6380 –

0

Tạo một lớp xác nhận đơn giản:

public class StudyValidator { 
    public boolean validateStudy(String studyName) { 
     //your validate logic here 
    } 
} 

sau đó tiêm nó vào ModuleController:

class ModuleController { 
    private StudyValidator sv = new StudyValidator(); //use spring injection to populate. 
    boolean validStudy(String studyName) { 
     return sv.validateStudy(studyName); 
    } 
} 

Simples.

+0

Có, nhưng tôi vẫn cần gọi validStudy() trong mọi phương pháp, đó chính xác là vấn đề tôi gặp phải bây giờ. – limc

+0

Tôi nghĩ rằng việc gọi một phương pháp kém hơn nhiều, hơn là trải qua sự điên rồ cấu hình Spring và thiết lập toàn bộ một lớp học điên rồ để giảm một cuộc gọi đó. Tại sao chúng ta làm cho cuộc sống của mình quá phức tạp trong cái tên đơn giản? –

+0

Tôi hiểu sai mục tiêu của câu hỏi là mô đun hóa mã phổ biến để sử dụng trong nhiều bộ điều khiển. Bean Validation ở trên trông rất đẹp! :) – DrUseful

0

Hmmm, không chắc chắn nếu nó sẽ làm việc, nhưng bạn có thể có thể chú thích @Valid như briefly mentioned in this link on validators.

Good Luck!

+0

Tôi đã xem @Valid, dường như chỉ xác thực mô hình bằng cách sử dụng trình xác thực hibernate 4 hoặc lớp trình xác thực tùy chỉnh của tôi. – limc

1

Tạo một lớp học StudyName sau đó có một WebArgumentResolver đăng ký cho StudyName và có xác nhận của bạn diễn ra ở đó.

public ModelAndView getA(@PathVariable StudyName studyName){ 
     ... 
    } 

    public class StudyNameResolver implements WebArgumentResolver{ 
     //have resolveArgument method do validation if resolved to a StudyName 
    } 
+0

+1 để làm cho tôi biết về WebArgumentResolver. Tôi đã xem xét điều này trước đây, nhưng tôi miễn cưỡng sử dụng điều này là bởi vì tôi có thể phải tạo ra một vài giải quyết tùy chỉnh cho dự án cụ thể này. – limc

1

Tôi bắt đầu sử dụng lò xo 3 và tôi làm như giải pháp của bạn xác nhận theo cách này: công khai ModelAndView getB (@Valid @NonNull @PathVariable String studyName, ...) {

Tuy nhiên, khi pathvariable không hợp lệ (trong trường hợp này studyName = null) cách bạn bắt và hiển thị lỗi đó?

Tôi đã cố gắng sử dụng kết quả ràng buộc nhưng nó không hoạt động. Ngoài ra, bạn có biết cách hiển thị lỗi trên jsp không?

Cảm ơn

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