2015-07-18 865 views
12

我已經實現了基於令牌的認證(沒有spring安全性)。所以在GenericFilterBean中,它檢查並聲明令牌。Spring中的異常處理GenericFilterBean

public class MyTokenFilter extends GenericFilterBean { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws MyAuthException { 

     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

     if (!"OPTIONS".equals(request.getMethod())) { 

      String authHeader = request.getHeader("Authorization"); 

      if (authHeader == null || !authHeader.startsWith("Token ")) { 
       throw new MyAuthException("Authorization header needed"); // Should return custom http status response like 400 
      } 

      String token = authHeader.substring(6); 

      try { 
       claimToken(token); 
      } catch (Exception e) { 
       throw new MyAuthException("Invalid token."); // Should return custom http status response like 401 
      } 

     } 

     chain.doFilter(req, res); 

    } 

} 

所以在這個過濾器看起來好吧。但我需要用json發送不同的Http Statutes的響應。我可以在@ControllerAdvice中使用ResponseEntitiyExceptionHandler。所以我可以在我的控制器中處理異常。

@ControllerAdvice 
public class MyPrettyExceptionHandler extends ResponseEntityExceptionHandler { 

    @ExceptionHandler(MyAuthException.class) 
    @ResponseBody 
    public ResponseEntity<Object> handleCustomException(HttpServletRequest req, MyAuthException ex) { 
     Map<String, String> responseBody = new HashMap<>(); 
     responseBody.put("error", "true"); 
     responseBody.put("message", ex.getMessage()); 
     return new ResponseEntity<Object>(responseBody, HttpStatus.INTERNAL_SERVER_ERROR); 
    } 
} 

我知道它是如何工作以及階濾波器和控制器及其例外(過濾器做他們的工作控制器之前,所以他們不一樣的範圍與控制器)。所以自然我無法用ControllerAdvice處理過濾器的異常。

那麼什麼是有效的方式來處理過濾器中的異常(就像我的示例方式)?你能否以另一種方式向我提出建議?

回答

7

您應該使用response.sendError用於發送錯誤代碼和狀態:

public class MyTokenFilter extends GenericFilterBean { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

     if (!"OPTIONS".equals(request.getMethod())) { 

      String authHeader = request.getHeader("Authorization"); 
      if (authHeader == null || !authHeader.startsWith("Token ")) { 
       //throw new MyAuthException("Authorization header needed"); // Should return custom http status response like 400 
       response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Authorization header needed"); 
       return ; 
      } 

      String token = authHeader.substring(6); 
      try { 
       claimToken(token); 
      } catch (Exception e) { 
       //throw new MyAuthException("Invalid token."); // Should return custom http status response like 401 
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token."); 
       return ; 
      } 
     } 
     chain.doFilter(req, res); 
    } 
}