【问题标题】:Spring boot @ExceptionHandler isn't catching relevant exceptionSpring boot @ExceptionHandler 没有捕获相关异常
【发布时间】:2016-12-16 21:33:00
【问题描述】:

我正在使用 Spring Boot 构建 API。我已经设置了一个身份验证过滤器来从请求标头中获取一个令牌并对其进行身份验证。如果无法使用令牌找到用户,则会引发 InvalidWSUserException。

我创建了一个类来保存许多 @ExceptionHandlers,以便我可以捕获 InvalidWSUserException 并使用 JSON 字符串进行响应,告知请求客户端其请求中的令牌无效。

我已经在另一个项目中使用了这个,但我似乎无法在这个新项目中使用它。

InvalidWSUserException 为空,因为 Handler 应该处理响应;

public class InvalidWSUserException extends RuntimeException {
}

我已经这样定义了处理程序类;

@ControllerAdvice
public class ExceptionController {

    @ExceptionHandler(value=InvalidWSUserException.class)
    public ResponseEntity invalidWSUserException(InvalidWSUserException exception) {
        return new WSResponse().send(HttpStatus.UNAUTHORIZED, "Invalid token.");
    }

}

我在以前的项目中遇到了一个问题,其中引发异常的类没有被 Spring 通过 Bean 实例化,但我已经检查过这个类,并且引发异常的类被实例化通过@Autowired 注释。

我很难理解为什么 @ExceptionHandler 没有做我认为应该做的事情。

确认一下,我在浏览器中看到的输出是error 500 json response;应该是来自@ExceptionHandler 的EntityResponse

{
  "timestamp": 1470833849289,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "digital.sheppard.exceptions.InvalidWSUserException",
  "message": "No message available",
  "path": "/api/product"
}

【问题讨论】:

  • 你找到什么好的解决办法了吗?

标签: java spring spring-mvc


【解决方案1】:

我正在使用JSON Web Token for Java 库,正如您在上面所说的,我在身份验证服务中遇到了同样的错误。我试过@ControllerAdvice,但没有解决方案。

经过长时间的研究,我找到了解决方案。你必须实现你的JwtFilter,而不是启动一个异常,你必须修改你的HttpServletResponse值以添加以下内容:

if (authHeader == null || !authHeader.startsWith("Bearer ")) {
   //throw new UnauthorizedErrorException(UnauthorizedErrorException.ErrorCodes.INVALID_TOKEN);

   response.addHeader("Content-Type", "application/json");
   response.getWriter().print(getErrorJson());    
   response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

   return;
}

final String token = authHeader.substring(7);

try {
   final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
   request.setAttribute("claims", claims);
} catch (final SignatureException e) {
   //throw new UnauthorizedErrorException(UnauthorizedErrorException.ErrorCodes.INVALID_TOKEN);

   response.addHeader("Content-Type", "application/json");
   response.getWriter().print(getErrorJson());           
   response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

   return;
}

chain.doFilter(req, res);

如您所见,我已对异常启动进行了注释,并将其更改为响应标头覆盖。 getErrorJson() 将 JSON 值作为字符串返回(或者您只能将字符串作为正文)。

我希望这对你有用。

P.D.:我已关注此 instructions 以实施身份验证。

【讨论】:

    猜你喜欢
    • 2020-06-05
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多