Java 在WebFilter类中引发异常,并在ControllerAdvice类中处理它

Java 在WebFilter类中引发异常,并在ControllerAdvice类中处理它,java,spring-webflux,Java,Spring Webflux,我试图实现一个WebFilter,它检查JWT,如果检查失败或结果无效,则抛出异常。我有一个@ControllerAdvice类来处理这些异常。但它不起作用 这是WebFilter类: 我认为,@ControllerAdvice类不能处理WebFilter抛出的异常。因为,如果我将异常移动到控制器,它就会工作 我已为此更改了代码(目前): @覆盖 公共Mono筛选器(服务器WebExchange exchange、WebFilterChain链){ 可选authJwt=Optional.ofNu

我试图实现一个
WebFilter
,它检查JWT,如果检查失败或结果无效,则抛出异常。我有一个
@ControllerAdvice
类来处理这些异常。但它不起作用

这是
WebFilter
类: 我认为,
@ControllerAdvice
类不能处理
WebFilter
抛出的异常。因为,如果我将异常移动到控制器,它就会工作

我已为此更改了代码(目前):
@覆盖
公共Mono筛选器(服务器WebExchange exchange、WebFilterChain链){
可选authJwt=Optional.ofNullable(exchange.getRequest().getHeaders().get(“授权”))
.flatMap(list->list.stream().findFirst())
.filter(authHeader->!authHeader.isEmpty()&&authHeader.startsWith(“承载者”))
.map(authHeader->authHeader.replaceFirst(“^Bearer”,”);
if(authJwt.isPresent()){
String jwtString=authJwt.get();
试一试{
解码访问令牌(jwtString);
}捕获(JoseeException e){
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
返回exchange.getResponse().writeWith(Mono.empty());
}
}否则{
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
返回exchange.getResponse().writeWith(Mono.empty());
}
返回链。过滤器(交换);
}

你觉得这个问题怎么样?您知道实现它的另一种方法吗?

您可以尝试为
@ControllerAdvice
@WebFilter
bean定义
@Order()
,并赋予
@ControllerAdvice
更高的优先级


但是,我不认为这是正确的做法,主要原因是
@ControllerAdvice
异常处理程序不返回反应类型。相反,我将定义一个实现
ErrorWebExceptionHandler
的bean。这个处理程序是由`SpringWebFlux'添加到反应流的,所以您不必担心优先级。有关详细信息,请参阅。

我在webflux中遇到了相同的问题,您不希望在webfilter中引发直接异常或返回mono错误),但是您希望将响应设置为包含异常的mono错误(与您所做的操作接近)。这将允许在请求工作流的正确部分抛出异常,因此它将冒泡到您的rest控制器建议中

public class YourFilter implements WebFilter{

    @Override
    public Mono<Void> filter(final ServerWebExchange exchange, final WebFilterChain chain){
        exchange.getResponse().writeWith(Mono.error(new YouException()));

        return chain.filter(exchange);
    }
}
public类YourFilter实现WebFilter{
@凌驾
公共Mono筛选器(最终服务器WebExchange exchange、最终WebFilterChain链){
exchange.getResponse().writeWith(Mono.error(newyouexception());
返回链。过滤器(交换);
}
}

我已经尝试过了,但我遇到了一个CORS错误 以下是错误:


访问位于“”的XMLHttpRequesthttp://localhost:8084/users/files“起源”http://localhost:4200'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在'access control Allow Origin'标头。

谢谢!我实施了第二种方法,效果很好。
@ControllerAdvice
public class SecurityExceptionHandler {

  @ExceptionHandler(AuthorizationException.class)
  public ResponseEntity authorizationExceptionHandler(AuthorizationException ex) {

    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();

  }

  @ExceptionHandler(DecodeAccessTokenException.class)
  public ResponseEntity decodeAccessTokenExceptionHandler(DecodeAccessTokenException ex) {

    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();

  }

}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

    Optional<String> authJwt = Optional.ofNullable(exchange.getRequest().getHeaders().get("Authorization"))
            .flatMap(list -> list.stream().findFirst())
            .filter(authHeader -> !authHeader.isEmpty() && authHeader.startsWith("Bearer "))
            .map(authHeader -> authHeader.replaceFirst("^Bearer", ""));

    if (authJwt.isPresent()) {
        String jwtString = authJwt.get();
        try {
            jwtVerifier.decodeAccessToken(jwtString);
        } catch (JoseException e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().writeWith(Mono.empty());
        }
    } else {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().writeWith(Mono.empty());
    }

    return chain.filter(exchange);
}
public class YourFilter implements WebFilter{

    @Override
    public Mono<Void> filter(final ServerWebExchange exchange, final WebFilterChain chain){
        exchange.getResponse().writeWith(Mono.error(new YouException()));

        return chain.filter(exchange);
    }
}