英文:
SpringBoot @ControllerAdvice is working partially
问题
我已经尝试了所有为这个问题提供的解决方案,但对我没有起作用。
抛出异常的位置。
```java
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (Exception e) {
throw new MyException("过期或无效的JWT令牌");
}
}
调用位置
public class JwtTokenFilter extends GenericFilterBean {
JwtTokenProvider jwtTokenProvider;
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String token = jwtTokenProvider.resolveToken((HttpServletRequest) servletRequest);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
CustomExceptionHandler
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ MyException.class })
public ResponseEntity<Object> handleJwtException(MyException e) {
String message = e.getMessage();
ErrorResponse errorResponse = new ErrorResponse(message);
return new ResponseEntity<>(errorResponse, HttpStatus.UNAUTHORIZED);
}
@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
String message = ex.getMessage();
ErrorResponse errorResponse = new ErrorResponse(message);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
CustomException 类
public class MyException extends RuntimeException {
public MyException(String message) {
super(message);
}
}
handleHttpRequestMethodNotSupported
运行良好,但 handleJwtException
没有触发,而是得到了
java.lang.RuntimeException: 过期或无效的JWT令牌
com.imoney.adapters.JwtTokenProvider.validateToken(JwtTokenProvider.java:74)
感谢您的帮助。
<details>
<summary>英文:</summary>
I have tried all the solution provided for this question and didn't worked for me.
Place from where I am throwing exception.
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (Exception e) {
throw new MyException("Expired or invalid JWT token");
}
}
Where it is called
public class JwtTokenFilter extends GenericFilterBean {
JwtTokenProvider jwtTokenProvider;
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String token = jwtTokenProvider.resolveToken((HttpServletRequest) servletRequest);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
CustomExceptionHandler
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ MyException.class })
public ResponseEntity<Object> handleJwtException(MyException e) {
String message = e.getMessage();
ErrorResponse errorResponse = new ErrorResponse(message);
return new ResponseEntity<>(errorResponse, HttpStatus.UNAUTHORIZED);
}
@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
String message = ex.getMessage();
ErrorResponse errorResponse = new ErrorResponse(message);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
CustomException class
public class MyException extends RuntimeException {
public MyException(String message) {
super(message);
}
}
`handleHttpRequestMethodNotSupported` is working fine but `handleJwtException` is not triggered but instead I get
java.lang.RuntimeException: Expired or invalid JWT token
com.imoney.adapters.JwtTokenProvider.validateToken(JwtTokenProvider.java:74)
I appreciate the help.
</details>
# 答案1
**得分**: 2
尝试在 `@ControllerAdvice` 上面添加 `@Order(Ordered.HIGHEST_PRECEDENCE)` - 可能有其他错误处理程序在 `CustomExceptionHandler` 之前捕获了您的 `IMoneyException`。
另外,`IMoneyException` 这个命名暗示您的异常是一个接口。您可能希望将其更改,以避免将来产生混淆。
编辑:
我找不到支持这一点的任何文献,但问题可能在于您的异常继承自 `RuntimeException`,这使其成为了未检查的异常。
尝试将其更改为:
```java
public class MyException extends Exception {
public MyException(String message) { super(message); }
}
英文:
Try adding @Order(Ordered.HIGHEST_PRECEDENCE)
above @ControllerAdvice
- it's possible some other error handler is catching your IMoneyException
before it reaches CustomExceptionHandler
.
On a side note name IMoneyException
suggests that your exception is an interface. You may want to change that to avoid confusion in the future.
Edit:
I can't find any literature to support this, but the issue may be that your exception inherits from RuntimeException
, which makes it an unchecked exception.
Try changing it to:
public class MyException extends Exception {
public MyException(String message) { super(message); }
}
答案2
得分: -2
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid");
}
}
public class JwtAuthenticationException extends AuthenticationException {
public JwtAuthenticationException(String message) {
super(message);
}
}
英文:
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid");
}
}
public class JwtAuthenticationException extends AuthenticationException {
public JwtAuthenticationException(String message) {
super(message);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论