2012-08-13 39 views
10

Tôi đang sử dụng lớp Preconditions của Google để xác thực dữ liệu đầu vào của người dùng.
Nhưng tôi lo lắng về đâu là điểm tốt nhất để kiểm tra dữ liệu đầu vào của người dùng bằng cách sử dụng lớp Điều kiện tiên quyết.
Trước tiên, tôi đã viết xác nhận mã kiểm tra trong điều khiển như dưới đây:Kiểm tra điều kiện tiên quyết trong Bộ điều khiển hoặc Lớp dịch vụ

@Controller 
... 
public void register(ProductInfo data) { 
    Preconditions.checkArgument(StringUtils.hasText(data.getName()), 
     "Empty name parameter."); 
    productService.register(data); 
} 

@Service 
... 
public void register(ProductInfo data) { 
    productDao.register(data); 
} 

Nhưng tôi nghĩ rằng register phương pháp trong lớp dịch vụ sẽ sử dụng một phương pháp điều khiển như dưới đây:

@Controller 
... 
public void register(ProductInfo data) { 
    productService.register(data); 
} 
public void anotherRegister(ProductInfo data) { 
    productService.register(data); 
} 

@Service 
... 
public void register(ProductInfo data) { 
    Preconditions.checkArgument(StringUtils.hasText(data.getName()), 
     "Empty name parameter."); 
    productDao.register(data); 
} 

Mặt khác , phương thức của lớp dịch vụ sẽ được sử dụng chỉ trong một bộ điều khiển.
Tôi đã nhầm lẫn. Đó là cách tốt hơn để kiểm tra điều kiện tiên quyết trong bộ điều khiển hoặc dịch vụ?
Cảm ơn bạn trước.

Trả lời

17

Lý tưởng nhất là bạn sẽ làm điều đó ở cả hai nơi. Nhưng khó hiểu hai điều bạn khác nhau:

  • Validation (với xử lý lỗi)
  • Defensivie Lập trình (hay còn gọi là khẳng định, hay còn gọi là thiết kế theo hợp đồng).

Bạn hoàn toàn nên làm xác nhận trong bộ điều khiển và chương trình phòng thủ trong dịch vụ của bạn. Và đây là lý do tại sao.

Bạn cần phải Validate cho các hình thức và yêu cầu REST của để bạn có thể gửi một lỗi hợp lý lại cho khách hàng. Điều này bao gồm các trường nào là xấu và sau đó làm nội địa hóa các thông báo lỗi ... vv ... (ví dụ hiện tại của bạn sẽ gửi cho tôi một thông báo lỗi khủng khiếp 500 với một dấu vết ngăn xếp nếu thuộc tính ProductInfo.name là null).

Mùa xuân có solution for validating objects trong bộ điều khiển.

Phòng thủ lập trình được thực hiện trong các lớp dịch vụ NHƯNG KHÔNG xác nhận bởi vì bạn không có quyền truy cập đối với ngôn ngữ để tạo ra các thông báo lỗi thích hợp. Một số người làm nhưng mùa xuân không thực sự giúp bạn ở đó.

Lý do khác tại sao xác thực không được thực hiện trong lớp dịch vụ là ORM đã thường thực hiện điều này thông qua thông số xác thực bean JSR (ngủ đông) nhưng không tạo ra thông báo lỗi hợp lý.

Một chiến lược người làm là để tạo riêng có điều kiện tiên quyết utils thư viện mà ném tùy biến bắt nguồn RuntimeException s thay vì ổi (và commons lang) IllegalArgumentExceptionIllegalStateException và sau đó try ... catch các trường hợp ngoại lệ trong bộ điều khiển chuyển đổi chúng sang xác nhận lỗi tin nhắn.

2

Không có cách nào "tốt hơn". Nếu bạn nghĩ rằng dịch vụ này sẽ được sử dụng bởi nhiều bộ điều khiển (hoặc các phần mã khác), thì bạn có thể thực hiện các kiểm tra ở đó một cách hợp lý. Nếu điều quan trọng đối với ứng dụng của bạn là kiểm tra các yêu cầu không hợp lệ trong khi chúng vẫn còn trong bộ điều khiển, thì việc kiểm tra ở đó cũng có ý nghĩa. Hai điều này, như bạn đã thấy, không loại trừ lẫn nhau. Bạn có thể phải kiểm tra hai lần để trang trải cả hai trường hợp.

Một giải pháp khả thi khác: sử dụng Xác thực Bean (JSR-303) để đặt các kiểm tra (điều kiện tiên quyết) vào chính hạt ProductInfo. Bằng cách đó bạn chỉ xác định các kiểm tra một lần, và bất cứ điều gì cần để có thể nhanh chóng xác nhận đậu.

+0

Chắc chắn đồng ý rằng bạn nên sử dụng xác thực bean, đặc biệt nếu DAO của bạn đang sử dụng ORM. – hyness

0

Tôi nghĩ trong trường hợp đặc biệt của bạn, bạn cần phải kiểm tra nó trên lớp Dịch vụ và trả về ngoại lệ cho Bộ điều khiển trong trường hợp lỗi toàn vẹn dữ liệu.

@controller 
public class MyController{ 

@ExceptionHandler(MyDataIntegrityExcpetion.class) 
public String handleException(MyDataIntegrityExcpetion ex, HttpServletRequest request) { 
    //do someting on exception or return some view. 
} 

} 

Nó cũng phụ thuộc vào những gì bạn đang làm trong bộ điều khiển. cho dù bạn trả lại View hay chỉ sử dụng @ResponseBody Chú thích. Spring MVC có giải pháp "out of the box" tốt cho kiểm tra đầu vào/dat Tôi khuyên bạn nên kiểm tra thư viện này.

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html

0

điều kiện tiên quyết, kiểm chứng thực, cho dù đơn giản hay kinh doanh nên được xử lý ở lớp lọc hoặc bằng cách chặn, thậm chí trước khi đến bộ điều khiển hoặc dịch vụ lớp.

Sự nguy hiểm nếu bạn kiểm tra nó trong lớp điều khiển, bạn đang vi phạm nguyên tắc trách nhiệm duy nhất của bộ điều khiển, với mục đích duy nhất là ủy quyền yêu cầu và phản hồi.

Đưa điều kiện tiên quyết vào lớp dịch vụ là giới thiệu các mối quan tâm cắt ngang cho hoạt động kinh doanh cốt lõi.

Bộ lọc hoặc inceptor được xây dựng cho mục đích này. Đặt điều kiện tiên quyết ở lớp lọc hoặc trong bộ chặn cũng cho phép bạn "chọn và khớp" quy tắc bạn có thể đặt trong ngăn xếp cho mỗi yêu cầu servlet, do đó không giới hạn quy tắc cụ thể chỉ với một yêu cầu servlet hoặc giới thiệu sao chép.

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