Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将JSR303 JavaBean验证异常转换为自定义异常_Java_Aspectj_Bean Validation_Custom Exceptions - Fatal编程技术网

将JSR303 JavaBean验证异常转换为自定义异常

将JSR303 JavaBean验证异常转换为自定义异常,java,aspectj,bean-validation,custom-exceptions,Java,Aspectj,Bean Validation,Custom Exceptions,我已经在web应用程序的服务层中实现了JSR303 JavaBean验证(根据)。现在我想将所有验证异常(例如javax.validation.ConstraintViolationException)转换为我的自定义异常 我创建了一个方面,每当在服务层中引发异常时都会调用该方面: @Aspect public class ExceptionConversionAspect { @AfterThrowing(pointcut="execution(* com.myexample.ser

我已经在web应用程序的服务层中实现了JSR303 JavaBean验证(根据)。现在我想将所有验证异常(例如javax.validation.ConstraintViolationException)转换为我的自定义异常

我创建了一个方面,每当在服务层中引发异常时都会调用该方面:

@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
    ....
}

如何以正确的顺序链接我的方面?首先是ValidateSpect,然后是ExceptionTransversionSpect?

当多个方面共享一个公共连接点时,您可以使用@DeclareRecessence语句手动设置执行顺序。在您的情况下,您可以创建一个新方面:

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

如果未指定优先级,则执行顺序默认为定义的规则。Raul Bertone几乎正确,但不完全正确。逻辑必须颠倒,并且
异常转换spect
必须优先

Java SE的完全工作示例(我只是模拟Java EE异常):

助手类:

package javax.validation;
公共类ConstraintViolationException扩展了RuntimeException{
私有静态最终长serialVersionUID=-8041265519275356912L;
public ConstraintViolationException(字符串arg0){
超级(arg0);
}
}
package com.myexample.validator.annotation;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
@保留(RetentionPolicy.RUNTIME)
public@interface Validate{}
package com.myexample.service;
公共类InvalidServiceInputException扩展RuntimeException{
公共InvalidServiceInputException(字符串arg0,可丢弃的arg1){
超级(arg0,arg1);
}
}
示例驱动程序应用程序:

驱动程序应用程序由
@Validate
注释,并模拟服务-请参阅包名。它循环10个方法调用,捕捉异常并将它们打印到标准输出,以显示它们确实按照需要进行了转换

package com.myexample.service;
导入com.myexample.validator.annotation.Validate;
@证实
公共类应用程序{
公共无效剂量测定(int i){
System.out.printf(“做某事#%d%n”,i);
}
公共静态void main(字符串[]args){
应用程序=新应用程序();
对于(int i=0;i<10;i++){
试一试{
应用剂量测定法(i+1);
}
捕获(例外e){
系统输出打印ln(e);
System.out.println(“原因:+e.getCause());
}
}
}
}
方面:

出于演示目的,验证方面随机抛出一个
ConstraintViolationException

package com.myexample.aspect;
导入java.util.Random;
导入javax.validation.ConstraintViolationException;
导入org.aspectj.lang.ProceedingJoinPoint;
导入org.aspectj.lang.annotation.Around;
导入org.aspectj.lang.annotation.Aspect;
@面貌
公共类ValidateSpect{
私有静态最终随机=新随机();
@大约((com.myexample.validator.annotation.Validate)中的(“执行(public!static**(..)&&&&&@”)
公共对象验证方法调用(ProceedingJoinPoint thisJoinPoint)抛出Throwable{
对象结果=thisJoinPoint.Procedure();
if(RANDOM.nextBoolean())
抛出新的ConstraintViolationException(“uh-oh”);
返回结果;
}
}
异常转换特性现在有一个额外的
@declareReceidence
注释

package com.myexample.aspect;
导入javax.validation.ConstraintViolationException;
导入org.aspectj.lang.annotation.afterhrowing;
导入org.aspectj.lang.annotation.Aspect;
导入org.aspectj.lang.annotation.declareReceidence;
导入com.myexample.service.InvalidServiceInputException;
@面貌
@声明接收(“例外转换方面,*”)
公共类例外转换spect{
@后throwing(pointcut=“execution(*com.myexample.service…*(…)”),throwing=“e”)
公共无效convertServiceException(异常e){
if(例如ConstraintViolationException的实例){
抛出新的InvalidServiceInputException(“服务输入验证失败”,e);
}
}
}
控制台输出:

做事#1
做点什么#2
com.myexample.service.InvalidServiceInputException:服务输入验证失败
原因:javax.validation.ConstraintViolationException:噢
做点什么#3
com.myexample.service.InvalidServiceInputException:服务输入验证失败
原因:javax.validation.ConstraintViolationException:噢
做点什么
做点什么
做点什么
com.myexample.service.InvalidServiceInputException:服务输入验证失败
原因:javax.validation.ConstraintViolationException:噢
做点什么
做点什么
做某事
做某事

也许它有助于为validateMethodInvocation方法创建方面-它将由该方法引发的异常触发,或者重写ValidateSpect,以便引发正确的异常?