简体   繁体   English

Spring GenericFilterBean中的异常处理

[英]Exception handling in Spring GenericFilterBean

I have implemented token based authentication(without spring security). 我已经实现了基于令牌的身份验证(没有spring安全性)。 So in GenericFilterBean, it checks and claims token. 因此,在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);

    }

}

So in this filter it seems all okay. 所以在这个过滤器中似乎一切都好。 But I need to send response with different Http Statutes with a json. 但是我需要用json发送不同Http Statutes的响应。 I am able to use ResponseEntitiyExceptionHandler with @ControllerAdvice. 我能够将ResponseEntitiyExceptionHandler与@ControllerAdvice一起使用。 So I can handle exceptions in my controllers. 所以我可以在我的控制器中处理异常。

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

I know how it works and which order Filter and controllers and their exceptions(filters do their job before controllers, so they're not same scope with controllers). 我知道它是如何工作的以及哪个顺序过滤器和控制器及其异常(过滤器在控制器之前完成它们的工作,所以它们与控制器的范围不同)。 So naturally I can't handle filter's exceptions with ControllerAdvice. 所以我自然无法使用ControllerAdvice处理过滤器的异常。

So what is the efficient way to handle exceptions in Filters(like my example way)? 那么在Filter中处理异常的有效方法是什么(比如我的例子)? Can you suggest me another way about it? 你能用另一种方式建议我吗?

You should use response.sendError for send error code and status : 您应该使用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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM