2012-08-13 5 views
10

Google의 사전 조건 클래스를 사용하여 사용자 입력 데이터의 유효성을 검사하고 있습니다.
그러나 전제 조건 클래스를 사용하여 사용자의 입력 데이터를 확인하는 가장 좋은 시점이 어디인지 걱정됩니다.
첫째, 나는 다음과 같은 컨트롤러에 유효성 검사 코드를 썼다 :컨트롤러 또는 서비스 레이어의 전제 조건을 확인하십시오.

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

하지만 서비스 계층에서 register 방법은 다른 컨트롤러 방법을 아래와 같이 사용하게 될 것이라고 생각 : 한편

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

서비스 계층의 방법은 단 하나의 컨트롤러에서만 사용됩니다.
혼란 스러웠습니다. 컨트롤러 또는 서비스의 전제 조건을 확인하는 가장 좋은 방법은 무엇입니까?
미리 감사드립니다.

답변

17

두 곳에서 모두 사용하는 것이 가장 이상적입니다. 하지만 당신의 혼란 다른 두 가지 :

  • 검증
  • Defensivie 프로그래밍 (오류 처리 포함) (일명 주장, 계약에 의한 일명 디자인).

당신은 절대적으로 컨트롤러의 검증 및 서비스에 방어 프로그래밍을 수행해야합니다. 그리고 여기 왜 있습니다.

양식 및 REST 요청의 경우 의 유효성을 검사해야 합리적인 오류를 다시 클라이언트로 보낼 수 있습니다. 여기에는 어떤 필드가 좋지 않은지, 오류 메시지의 현지화 등이 포함됩니다 (현재 예제에서는 ProductInfo.name 속성이 null 인 경우 스택 추적이있는 끔찍한 500 오류 메시지를 보냅니다).

스프링의 컨트롤러에 solution for validating objects이 있습니다.

방어 프로그래밍는 서비스 계층에서 이루어집니다하지만 검증하면 적절한 오류 메시지를 생성하는 로케일에 액세스 할 수 없기 때문에. 어떤 사람들은 그렇지만 스프링은 당신을 정말로 돕지 않습니다.

서비스 계층에서 유효성 검사가 수행되지 않는 다른 이유는 ORM이 JSR Bean 유효성 검사 사양 (최대 절전 모드)을 통해 일반적으로 수행하지만 합리적인 오류 메시지를 생성하지 않기 때문입니다. 전략 사람이 할

하나는 사용자 지정 유효성 검사 오류로 변환 RuntimeException 대신 구아바의 (그리고 평민 LANG) IllegalArgumentExceptionIllegalStateException의의 다음 try ... 컨트롤러의 catch 예외를 파생 던졌습니다 거기에 자신의 전제 조건 유틸 라이브러리를 만드는 것입니다 메시지.

2

"더 나은"방법은 없습니다. 서비스가 여러 컨트롤러 (또는 다른 코드)에 의해 사용될 것이라고 생각한다면, 거기에서 체크하는 것이 합리적 일 것입니다. 응용 프로그램이 유효하지 않은 요청을 컨트롤러에있는 동안 검사하는 것이 중요하다면 검사를 수행하는 것이 좋습니다. 이 두 가지는 서로 알지 못하는 사이에 상호 배타적이지 않습니다. 두 시나리오를 모두 다루기 위해 두 번 확인해야 할 수도 있습니다.

다른 가능한 해결책 : Bean 유효성 검사 (JSR-303)를 사용하여 Check (전제 조건)를 ProductInfo bean 자체에 두십시오. 그렇게하면 한 번만 수표를 지정하고 필요하면 Bean의 유효성을 빠르게 확인할 수 있습니다.

+0

특히 DAO가 ORM을 사용하는 경우 bean 유효성 검사를 사용해야한다는 것에 동의하십시오. – hyness

0

데이터 무결성 오류의 경우 서비스 레이어에서 확인하고 예외를 컨트롤러로 반환해야한다고 생각합니다.

@controller 
public class MyController{ 

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

} 

또한 컨트롤러에서 수행중인 작업에 따라 다릅니다. 반환 여부에 관계없이보기 또는 그냥 @ResponseBody 주석 사용. Spring MVC는 입력/데이터 검증을위한 훌륭한 "out of the box"솔루션을 가지고있다.이 라이브러리를 체크 아웃 할 것을 권한다.

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

0

사전 조건, 유효성, 단순 또는 업체가 필터층 또는 인터셉터에 의해 처리되어야하는지, 제어기 또는 심지어 서비스 층에 도달한다.

컨트롤러 레이어에서 확인하면 위험한 요청과 응답을 위임하는 컨트롤러의 단일 책임 원칙을 위반하는 것입니다.

서비스 계층에 전제 조건을 두는 것은 핵심 비즈니스에 교차 절단 문제를 도입하는 것입니다.

필터 또는 인셉터는 이러한 목적으로 제작되었습니다. 또한 필터 레이어 나 인터셉터에 전제 조건을두면 서블릿 요청마다 스택에 배치 할 수있는 규칙을 "선택 및 일치"할 수 있으므로 특정 규칙을 하나의 서블릿 요청에만 한정하거나 중복을 도입하지 않아도됩니다.

관련 문제