2010-07-11 37 views
8

Chỉnh sửa: Tôi đã xem chú thích @ExceptionHandler của Spring 3 và kết hợp điều này với Tùy chọn 1 bên dưới có vẻ là một giải pháp khá sạch sẽ.Lỗi quay lại chế độ xem từ lớp dịch vụ

Xem http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

Tôi cũng thấy đây là một đọc tốt: http://blog.decaresystems.ie/index.php/2006/04/07/difficult-choices-in-handling-exceptions-in-enterprise-java-applications/


Tôi đã được phát triển bằng cách sử dụng framework Spring MVC trong một thời gian hiện nay tuy nhiên tôi đang đấu tranh để tìm ra một cách 'đẹp' để truyền các lỗi được đưa ra trong lớp dịch vụ trở lại JSP. Về cơ bản, tôi không tin rằng logic nghiệp vụ (ngoài "trường này là bắt buộc") phải ở trong Trình xác thực, đặc biệt là bất kỳ logic nào yêu cầu quyền truy cập vào DB. Vì vậy, những gì tôi đã làm là đặt thêm, xác nhận phức tạp hơn và logic kinh doanh trong lớp dịch vụ.

Ví dụ: giả sử tôi có trang cho phép người dùng mua Sách. Họ nhấp vào "Mua" trên JSP và bộ điều khiển gọi dịch vụ để làm cho tất cả xảy ra ... Bây giờ, điều gì sẽ xảy ra nếu dịch vụ thấy rằng họ không có đủ tiền - làm cách nào để nhận lại thông báo này cho JSP Thông báo "Không đủ tiền" có thể được hiển thị cho người dùng? Tôi đã xem xét hai cách và tôi không chắc chắn đó là chính xác ...

Lựa chọn 1: Exceptions

Cách đầu tiên tôi nghĩ là để nâng cao một ngoại lệ trong các lớp dịch vụ, bẫy nó trong điều khiển và thêm một tin nhắn vào BindingResult.

dịch vụ:

public void pay(Book book) throws InsufficientFundsException { 
    // Some logic goes here, which ends up throwing the above exception 
} 

Bộ điều khiển:

public ModelAndView(@ModelAttribute("book") Book book, BindingResult errors) { 
    try { 
     pay(book); 
    } catch (InsufficientFundsException ex) { 
     errors.reject("insufficient.funds"); 
    } 
    return new ModelAndView(blahblahblah); 
} 

Phương án 2: đèo BindingResult đến dịch vụ lớp

Cách thứ hai là để vượt qua các đối tượng BindingResult đến lớp dịch vụ và tăng thêm lỗi chống lại nó.

dịch vụ:

public void pay(Book book, BindingResult errors) { 
    // User has insufficient funds, so... 
    errors.reject("insufficient.funds); 
} 

tôi có thể thấy vấn đề với cả hai cách. Tùy chọn 1 cảm thấy khó xử bởi vì không chỉ làm tôi phải bắt ngoại lệ, sau đó tôi phải thêm lỗi vào kết quả ràng buộc vì vậy nó cảm thấy như tôi đang làm điều tương tự hai lần. Và Option 2 dường như ràng buộc lớp dịch vụ quá chặt chẽ với bộ điều khiển.

Cuối cùng, tôi nhận ra đó là SimpleMappingExceptionResolver mà có thể được sử dụng kết hợp với Phương án 1, nhưng tôi không chắc chắn như thế nào phù hợp đó là (có lẽ tôi đã không nhìn thấy một ví dụ thích hợp?). Trong ví dụ trên, chỉ cho phép vì lý do của đối số mà tôi muốn người dùng quay trở lại biểu mẫu ban đầu có lỗi màu đỏ phía trên biểu mẫu, không được chuyển hướng đến một trang hoàn toàn khác. SimpleMappingExceptionResolver dường như cho tôi hữu ích khi bạn muốn chuyển hướng người dùng đến trang lỗi chuẩn khi một ngoại lệ nhất định được nâng lên (điều này không hoàn toàn là những gì tôi muốn biết cách thực hiện).

+1

Tôi nghĩ tùy chọn 1 sẽ là đặt cược tốt nhất của bạn – skaffman

Trả lời

4

Java sử dụng ngoại lệ để xử lý tự nhiên loại điều này. Cuối cùng, nó thường đơn giản hóa logic của bạn và làm giảm cơ hội mắc lỗi bằng cách quên kiểm tra xem có lỗi nào đó không. Bạn cũng có thể di chuyển logic lỗi ra khỏi luồng chính của mã.

Tôi không thấy lý do tại sao trường hợp bạn hiển thị khác với bất kỳ trường hợp nào khác mà tôi sẽ sử dụng xử lý ngoại lệ để xử lý lỗi.

+0

Cảm ơn bạn. Điều tra thêm về trình xử lý ngoại lệ của Spring 3 cho thấy rằng tôi có thể xử lý các ngoại lệ được nêu ra trong bộ điều khiển thông qua chú thích @ExceptionHandler, trong đó tôi có thể xử lý nó theo cùng một cách như tôi yêu cầu. Điều này đối với tôi có vẻ đẹp hơn thử/bắt trong phương pháp rqeuest bình thường. –

+1

@Ben J: Tôi không chắc liệu các phương thức '@ ExceptionHandler' có truy cập vào' BindingResult' hay không. – skaffman

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