2016-12-06 97 views
1

我有一個控制器通知,處理我的應用程序拋出的所有驗證異常,如下所示。彈簧過濾器拋出自定義異常

@RestControllerAdvice 
public class RestApiExceptionController { 

    @ExceptionHandler(ValidationErrorException.class) 
    public ResponseEntity<?> appNotFoundException(ValidationErrorException exception) { 
     return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) 
      .body(new ErrorResponse(exception.getErrorCode(), exception.getMessage())); 
    } 
} 

以我的方式,我想創建一個篩選器,它將驗證每個請求並在必要時拋出自定義異常。但事情是,我不能拋出自定義的異常,如下所示。

public class ValidationFilter implements Filter { 
    ... 
    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
     throws IOException, ServletException { 
     throw new ValidationErrorException(); // This is impossible 
    } 
    ... 
} 

如何在這種情況下拋出ValidationErrorException或有其他更好的方法來處理此類任務。

+0

是的,你可以...它只是一個'RuntimeException'或一個'ServletException'。此外,這與Spring沒有關係,而是一般的Servlet API(甚至是一般的Java編程)。 –

回答

2

驗證通常在Controller圖層中的請求對象上完成,它們是從請求格式到服務器處理格式的transformed。例如JSON到Java對象。

因此,一旦通過完成整個filter鏈接來達到請求,就應該在Controller圖層上執行或觸發驗證。

然後拋出以後可以在以下處理器處理任何驗證異常,

@RestControllerAdvice 
public class RestApiExceptionController { 

    @ExceptionHandler(ValidationErrorException.class) 
    public ResponseEntity<?> appNotFoundException(ValidationErrorException exception) { 
     return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) 
      .body(new ErrorResponse(exception.getErrorCode(), exception.getMessage())); 
    } 
} 

的非常onefilters爲目的,

之前攔截來自客戶端的請求他們訪問 後端的資源。

因此,真實的過濾器沒有實際的資源尚未驗證。一旦控制達到糾正component,你的情況是它是Controller

所以更好的方法是不要在filter組件上執行任何基於resource的驗證。

+0

你是對的。但是,當我需要用戶將加密的密碼附加到HTTP Header時,我該如何驗證每個請求並拋出ValidationErrorException(如果密碼無效)呢? –

+0

@ChhornPonleu再次這是更多的設計決定。請查找Spring Security模塊。您正在嘗試根據請求進行授權/驗證。它具有所有這些與安全相關的功能。所以拋出安全性例外而不是驗證例外。 – ScanQR

+0

看起來Spring Security比我需要的功能更多。這就是爲什麼我尋求這種非常簡單的解決方案。 –