2012-04-17 3 views
3

내 웹 응용 프로그램의 서비스 계층에 JSR303 JavaBean 유효성 검사를 구현했습니다 (this article에 따라). 이제 모든 유효성 검사 예외 (예 : javax.validation.ConstraintViolationException)를 내 사용자 정의 예외로 변환하려고합니다. JSR303 JavaBean 유효성 검사 예외를 사용자 지정 예외로 변환

나는 예외가 서비스 계층에서 발생 될 때마다 호출되는 화면 생성 :

@Aspect 
public class ExceptionConversionAspect { 

    @AfterThrowing(pointcut="execution(* com.myexample.service.*.*(..))", throwing="e") 
    public void convertServiceException(Exception e) { 

     if (e instanceof ConstraintViolationException) { 
      // this is my custom exception 
      throw new InvalidServiceInputException("The service inputs failed validation", e); 
     } 
    } 
} 

을하지만 내 서비스 ConstraintViolationException와 검증을 실패했을 때 내 예외 변환 측면은 트리거되지 않습니다.

@Aspect 
public class ValidateAspect { 

    @Autowired 
    private Validator validator; 

    // Match any public methods in a class annotated with @AutoValidating 
    @Around("execution(public * *(..)) && @within(com.myexample.validator.annotation.Validate)") 
    public Object validateMethodInvocation(ProceedingJoinPoint pjp) throws Throwable { 

    // some code here 
    .... 
} 

가 어떻게 올바른 순서로 내 측면을 체인 않습니다 검증 예외가 자체가 화면에 의해 트리거 때문에이 의심? 먼저 ExceptionConversionAspect가 오는 ValidateAspect?

+0

는 어쩌면 그것은 validateMethodInvocation 방법에 대한 측면을 만드는 데 도움이 될 것이다 -이 예외에 의해 트리거하는 방법으로 던져 질 것 또는 적절한 예외를 던지고 있도록 ValidateAspect를 대체? –

답변

0

여러 측면이 공통된 joinpoint를 공유 할 때 @DeclarePrecedence 문을 사용하여 수동으로 실행 순서를 설정할 수 있습니다. 귀하의 경우에는 새로운 측면 만들 수 있습니다 : 우선 순위를 지정하지 않으면

@Aspect 
@DeclarePrecedence("ValidateAspect, ExceptionConversionAspect") 
    public class SystemArchitecture { 
     // ... 
    } 

을, 규칙의 실행 순서는 기본적으로하지만, 확실히, here

0

라울 베르토네 거의 맞다 정의. 로직을 반대로하고 ExceptionConversionAspect이 우선되어야합니다. 자바 SE에 대한

완전 작업 샘플 (난 그냥 자바 EE 예외를 에뮬레이트) :

도우미 클래스 :

package javax.validation; 

public class ConstraintViolationException extends RuntimeException { 
    private static final long serialVersionUID = -8041265519275356912L; 

    public ConstraintViolationException(String arg0) { 
     super(arg0); 
    } 
} 
package com.myexample.validator.annotation; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Validate {} 
package com.myexample.service; 

public class InvalidServiceInputException extends RuntimeException { 
    public InvalidServiceInputException(String arg0, Throwable arg1) { 
     super(arg0, arg1); 
    } 
} 

샘플 드라이버 응용 프로그램 :

드라이버 응용 프로그램은 @Validate으로 주석을 달고 서비스를 에뮬레이트합니다 (패키지 이름 참조). 이것은 10 개의 메소드 호출을 반복하고, 예외를 잡아 내고 표준 출력으로 출력하여 실제로 원하는대로 변환되었음을 보여줍니다.

package com.myexample.service; 

import com.myexample.validator.annotation.Validate; 

@Validate 
public class Application { 
    public void doSomething(int i) { 
     System.out.printf("Doing something #%d%n", i); 
    } 

    public static void main(String[] args) { 
     Application application = new Application(); 
     for (int i = 0; i < 10; i++) { 
      try { 
       application.doSomething(i + 1); 
      } 
      catch (Exception e) { 
       System.out.println(e); 
       System.out.println(" cause: " + e.getCause()); 
      } 
     } 
    } 
} 

양태 :

검증 양태 임의로 데모 목적으로 ConstraintViolationException을 던진다.

package com.myexample.aspect; 

import java.util.Random; 
import javax.validation.ConstraintViolationException; 
import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 

@Aspect 
public class ValidateAspect { 
    private static final Random RANDOM = new Random(); 

    @Around("execution(public !static * *(..)) && @within(com.myexample.validator.annotation.Validate)") 
    public Object validateMethodInvocation(ProceedingJoinPoint thisJoinPoint) throws Throwable { 
     Object result = thisJoinPoint.proceed(); 
     if (RANDOM.nextBoolean()) 
      throw new ConstraintViolationException("uh-oh"); 
     return result; 
    } 
} 

예외 변환 형태는 이제 추가적인 @DeclarePrecedence 주석을 갖는다.

package com.myexample.aspect; 

import javax.validation.ConstraintViolationException; 
import org.aspectj.lang.annotation.AfterThrowing; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.DeclarePrecedence; 
import com.myexample.service.InvalidServiceInputException; 

@Aspect 
@DeclarePrecedence("ExceptionConversionAspect, *") 
public class ExceptionConversionAspect { 
    @AfterThrowing(pointcut = "execution(* com.myexample.service..*(..))", throwing = "e") 
    public void convertServiceException(Exception e) { 
     if (e instanceof ConstraintViolationException) { 
      throw new InvalidServiceInputException("The service inputs failed validation", e); 
     } 
    } 
} 

콘솔 출력 :

Doing something #1 
Doing something #2 
com.myexample.service.InvalidServiceInputException: The service inputs failed validation 
    cause: javax.validation.ConstraintViolationException: uh-oh 
Doing something #3 
com.myexample.service.InvalidServiceInputException: The service inputs failed validation 
    cause: javax.validation.ConstraintViolationException: uh-oh 
Doing something #4 
Doing something #5 
Doing something #6 
com.myexample.service.InvalidServiceInputException: The service inputs failed validation 
    cause: javax.validation.ConstraintViolationException: uh-oh 
Doing something #7 
Doing something #8 
Doing something #9 
Doing something #10 
관련 문제