2012-09-05 115 views
3

跟隨我之前的問題的comment。我試圖從@Around建議中拋出異常,並在被調用類和/或方法中捕獲它。但我發現了這個錯誤:如何捕捉從@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 
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()

回答

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

注意,它會顯示與出現每次捕獲的異常錯誤信息的對話框窗口。這只是針對你的用戶界面的建議,對於你的建築的特殊情況,對於用戶授權的開火方法,使用嘗試,如果用戶是開放方法,則應使用開火未經授權。在這種情況下,如果授權失敗,授權方法應該拋出異常。然後錯誤將不會被打印,但特定的方法將被解僱。

這就是我想要添加到您的代碼:

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

做什麼你的意思是「捕獲任何未捕獲的異常」?來自Application Layer和以下的任何異常? – Khosrow

+0

中斷UI類的任何異常 – lebryant

+0

在執行ui方法之前拋出此異常。不是嗎?但它肯定會打斷它。你會介意提供你的建議代碼嗎? – Khosrow

2

要處理捕獲的異常像MyCustomException你需要的Struts 2,定義一個全局異常處理程序請查閱本指南:http://struts.apache.org/2.3.4.1/docs/exception-handling.html

+0

感謝您的回覆。我已經設法做到這一點,但事情是我不能對全局異常執行特定於操作的捕獲異常。沒有辦法在指定的類中捕獲它嗎?因爲除了Struts的基礎之外,我也有Jersey類型的接口。 – Khosrow

+0

由於你的代碼在'@ Around'建議中拋出了一個異常,你可以在'@ AfterThrowing'建議中將自定義代碼陷入其中。 – anubhava