2015-07-18 866 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); 
    } 
}