如何捕获从@Around抛出的Join点中的异常

时间:2012-09-05 09:06:22

标签: java spring security aspectj spring-aop

跟进我前一个问题的comment。我试图从@Around建议中抛出异常,并在被调用者类和/或方法中捕获它。但是我收到了这个错误:

Stacktraces

java.lang.Exception: User not authorized
    com.company.aspect.AuthorizeUserAspect.isAuthorized(AuthorizeUserAspect.java:77)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:616)
    ...

Aspect代码是:

@Aspect
public class AuthorizeUserAspect {
    @AuthoWired
    private UserService service;

    @Pointcut("@annotation(module)")
    public void authorizeBeforeExecution(AuthorizeUser module) {}

    @Around(value = "authorizeBeforeExecution(module)", argNames="module")
    public Object isAuthorized(ProceddingJoinPoint jp, AuthorizeUser module) throws Throwable {
        // Check if the user has permission or not
        service.checkUser();

        if ( /* User has NOT permission */ ) {
            throw new MyCustomException("User not authorized"); // => this is line 77
        }

        return jp.proceed();
    }
}

和Struts基于UI的动作代码是:

@Component
public class DashboardAction extends ActionSupport {
    @Override
    @AuthorizeUser
    public String execute() {
        ...
    }

    private void showAccessDenied() {
       ...
    }
}

问题是我如何或在哪里可以捕获该异常以执行showAccessDenied()

2 个答案:

答案 0 :(得分:2)

要处理未被捕获的异常,例如MyCustomException,您需要在Struts 2中定义全局异常处理程序。请查看本指南:http://struts.apache.org/2.3.4.1/docs/exception-handling.html

答案 1 :(得分:0)

对于用户界面,我建议编写一个短代码来捕获任何未捕获的异常。

class EventQueueProxy extends EventQueue {
    @Override
    protected void dispatchEvent(AWTEvent newEvent) {
        try {
            super.dispatchEvent(newEvent);
        } catch (Throwable t) {
            String message = t.getMessage();
            if (message == null || message.length() == 0) {
                message = "Fatal: " + t.getClass();
            }
            JOptionPane.showMessageDialog(null, message, "Unhandled Exception Caught!", JOptionPane.ERROR_MESSAGE);
        }
    }
}

然后在ui班:

public static void main(String args[]) {

    EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    queue.push(new EventQueueProxy());

    //your code goes here...
}

注意,每次出现未捕获的异常时,它都会显示带有错误信息的对话框窗口。这只是你的ui的建议,对于你的ploblem的特殊情况,请使用尝试用于授权用户的触发方法和捕获用于触发方法( s)如果用户未经授权,应执行该操作。在这种情况下,如果授权失败,授权方法应抛出异常。然后不会打印错误,但会触发特定的方法。

这就是我要添加到您的代码中的内容:

@Component 
public class DashboardAction extends ActionSupport {
    @Override
    try {
        @AuthorizeUser
        public String execute() {
                 ...     
        }
    } catch (Exception e) {
        private void showAccessDenied() {
                ...
        }
    }
}