SpringBoot的@ControllerAdvice部分地起作用

huangapple go评论68阅读模式
英文:

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&#39;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 &amp;&amp; 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&lt;Object&gt; handleJwtException(MyException e) {
    String message = e.getMessage();
    ErrorResponse errorResponse = new ErrorResponse(message);
    return new ResponseEntity&lt;&gt;(errorResponse, HttpStatus.UNAUTHORIZED);
}

@Override
protected ResponseEntity&lt;Object&gt; handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    String message = ex.getMessage();
    ErrorResponse errorResponse = new ErrorResponse(message);
    return new ResponseEntity&lt;&gt;(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&lt;Claims&gt; claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);

            return !claims.getBody().getExpiration().before(new Date());

        } catch (JwtException | IllegalArgumentException e) {
            throw new JwtAuthenticationException(&quot;JWT token is expired or invalid&quot;);
        }
    }
public class JwtAuthenticationException extends AuthenticationException {

    public JwtAuthenticationException(String message) {
        super(message);
    }
}

huangapple
  • 本文由 发表于 2020年8月23日 01:31:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63539132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定