【问题标题】:Exception handling in Spring GenericFilterBeanSpring GenericFilterBean 中的异常处理
【发布时间】:2015-10-08 09:08:33
【问题描述】:

我已经实现了基于令牌的身份验证(没有弹簧安全性)。所以在 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 的响应。我可以将 ResponseEntitiyExceptionHandler 与@ControllerAdvice 一起使用。所以我可以在我的控制器中处理异常。

@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 处理过滤器的异常。

那么在过滤器中处理异常的有效方法是什么(就像我的示例方式)?你能建议我另一种方法吗?

【问题讨论】:

    标签: java exception-handling spring-boot


    【解决方案1】:

    您应该使用 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-27
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 2023-03-28
      相关资源
      最近更新 更多