我已经实现了基于令牌的身份验证(没有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的响应。我能够将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来处理过滤器的异常。
那么在Filters中处理异常的有效方法是什么(比如我的示例方式)?你能用另一种方式建议我吗?
答案 0 :(得分:10)
您应该使用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);
}
}