2014-03-06 52 views
1

我正在試圖實現一個RESTful API和Spring MVC。而我的編碼在使用AOP Aspect的時候搞砸了。我需要在源代碼的每個請求中檢查一個authToken,以便我可以授權並且還需要它進行日誌記錄。在Spring Framework MVC中實現AOP

在我的代碼中,我有幾個custom exception classes從另一個主要customized exception class繼承,這是從Exception擴展。當引發自定義異常時,我需要那個等待異常的方法在我的Aspect類中工作,以便我可以返回適當的錯誤JSON響應。

但是,在我的代碼中,兩個方法都在等待異常,我不知道我是否以正確的方式編寫了我的異常類。還有一件事,我不知道如何說我的方面班不適合我定義的某些行爲。

這裏是我的代碼:

@Aspect 
public class SowLoggerAOP { 

    protected Logger logger = Logger.getLogger("SowLoggerAOP"); 
    @Autowired(required = true) 
    private HttpServletRequest request; 
    @Resource(name = "personService") 
    private PersonService personService; 

    @Pointcut("execution(* sow.webservice.controllers..*.*(..))") 
    private void selectAll(){} 

    @Before("execution(* sow.webservice.controllers.PersonController.*(..))") 
    public void logBeforeReq(JoinPoint jp) throws Exception{ 
     String personId = request.getParameter(Consts.AUTH_TOKEN); 
     if (personService.isUserValid(personId)) { 
      logger.debug("Spring AOP! Before invocation SUCCESFULL!!!: "); 
     } 
     else { 
      logger.error("Person not found for the " + Consts.AUTH_TOKEN + " : " + personId); 
      throw new PersonNotFoundException(
       "Person not found for the " + Consts.AUTH_TOKEN + " : " + personId, 
       ErrorCodes.PERSON_NOT_FOUND); 
     } 
    } 

    @AfterThrowing(pointcut = "selectAll()", throwing = "sowEx") 
    public SowResult throwingSowException(SowCustomException sowEx){ 
     int errorCode = ErrorCodes.GENERAL_SYSTEM_ERROR; 
     if(sowEx.getErrorCode() != 0) 
      errorCode = sowEx.getErrorCode(); 
     SowResult result = new SowResult(Consts.SOW_RESULT_ERROR, 
             errorCode, 
             sowEx.getMessage(), 
             "islem hata almistir!!"); 

     System.out.println("There has been an exception: " + sowEx.toString()); 
     return result; 
    } 

    @AfterThrowing(pointcut = "selectAll()", throwing = "ex") 
    public void throwingJavaException(Exception ex){ 
     System.out.println("JAVA EXCEPTION IS THROWN :"); 
    } 
} 

public class SowCustomException extends Exception{ 

    private int errorCode; 

    public SowCustomException(){ 
     super(); 
    } 

    public SowCustomException(String errMsg){ 
     super(errMsg); 
    } 
    public SowCustomException(String errMsg, int errorCode){ 
     super(errMsg); 
     this.errorCode = errorCode; 
    } 

    public SowCustomException(int errorCode){ 
     super(); 
     this.errorCode = errorCode; 
    } 

    public int getErrorCode() { 
     return errorCode; 
    } 
    public void setErrorCode(int errorCode) { 
     this.errorCode = errorCode; 
    } 
} 
public class PersonNotFoundException extends SowCustomException{ 

    public PersonNotFoundException(){ 
     super(); 
    } 

    public PersonNotFoundException(String errMsg){ 
     super(errMsg); 
    } 

    public PersonNotFoundException(String errMsg, int errorCode){ 
     super(errMsg); 
     super.setErrorCode(errorCode); 
    } 

    public PersonNotFoundException(int errorCode){ 
     super(); 
     super.setErrorCode(errorCode); 
    } 
} 

預期JSON必須從類創建:

public class SowResult { 

    public int resultCode; // 1- Succesfull, 0- Fail 
    public int errorCode; 
    public String errorString; 
    public String message; 
    public Date date; 
    public SowResult(int resultCode, int errorCode, String errorString, 
      String message) { 
     this.resultCode = resultCode; 
     this.errorCode = errorCode; // 0 - No Error 
     this.errorString = errorString; 
     this.message = message; 
     this.date = new Date(); 
    } 
} 
+0

你還沒有告訴我們什麼是或不是與此代碼工作 –

+0

對不起!我在這裏添加了一些額外的信息 – Emilla

回答

0

不幸的是,Spring的AOP堆棧忽略從@AfterThrowing通知方法任何返回值。它只是執行它,然後通過拋出最初拋出的異常繼續。

您可能想要使用@Around建議,將proceed呼叫包裝在try-catch區塊中,生成SowResult並將其返回。

+0

我做了你所說的。我應該從實現@Around註解的方法返回什麼?因爲它現在返回此異常: SEVERE:servlet [spring]在path [/ sow]上下文中的Servlet.service()拋出異常[Request processing failed;嵌套的異常是java.lang.ClassCastException:shoponway.webservice.common.SowResult不能轉換爲java.util.List]帶有根本原因 – Emilla

+0

@Emilla AOP並不神奇。如果你的方法是要返回一個'List'(這就是你指定的調用),那麼這就是你的方法應該返回的內容(即使它是通過AOP反射)。你試圖讓它返回一個'SowResult'。 –

+0

是的,我知道了。據我所知,春天在這裏沒有給我提供解決方案。因爲我可能有很多動作,其中一些可能會返回List對象,有些返回對象,有些甚至只返回一個字符串。那麼如何定製一個可以處理我的異常並返回適當的錯誤json的方法(在我的情況SowResult obj中)。 也許我錯了,然後請澄清我! – Emilla

1

由於Sotirios Delimanolis說,如果您想在攔截引發異常的方法後返回某些內容,則應該使用@Around。像這樣的東西(我相信,你的切入點是正確的):

@Around("selectAll()") 
    public Object handleException(ProceedingJoinPoint pjp) throws Throwable { 
     int errorCode = ErrorCodes.GENERAL_SYSTEM_ERROR; 
     if(sowEx.getErrorCode() != 0) 
     errorCode = sowEx.getErrorCode(); 
     SowResult retVal = null; 

     try { 
     retVal = (SowResult) pjp.proceed(); 
     } catch (RequestValidationException sowEx) { 
     //now return the error response 
     return new SowResult(Consts.SOW_RESULT_ERROR, 
            errorCode, 
            sowEx.getMessage(), 
            "islem hata almistir!!"); 
     } 

    return retVal; 
}