java - Spring GenericFilterBean 中的异常处理

标签 java exception-handling spring-boot

我已经实现了基于 token 的身份验证(没有 spring 安全性)。所以在 GenericFilterBean 中,它检查并声明 token 。

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);

    }

}

所以在这个过滤器中似乎一切正常。但是我需要用不同的 Http Statutes 和 json 发送响应。我可以将 ResponseEntitiyExceptionHandler 与 @ControllerAdvice 一起使用。所以我可以在我的 Controller 中处理异常。

@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);
    }
}

我知道它是如何工作的,以及过滤器和 Controller 及其异常的顺序(过滤器在 Controller 之前完成工作,因此它们与 Controller 的作用域不同)。所以我自然无法使用 ControllerAdvice 处理过滤器的异常。

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

最佳答案

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

关于java - Spring GenericFilterBean 中的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31496256/

相关文章:

java - 对字符串数组进行排序

java -version 不适用于 SSH

error-handling - 如何从grako/TatSu获取简洁的语法错误消息

java - 如何使此代码更干燥

docker - Kafka Docker、docker-maven-plugin、Spring Boot

java - 致命异常 : RxCachedThreadScheduler-1 when trigger dispose. 为什么?

java - Grails值得吗?

python - 抑制 Python 中捕获的异常的回溯(堆栈跟踪)

Java Spring Boot : Return only some attributs of an object

java - 如何通过url获取分页中的所有数据