2016-12-06 103 views
1

我有一个控制器通知,处理我的应用程序抛出的所有验证异常,如下所示。弹簧过滤器抛出自定义异常

@RestControllerAdvice 
public class RestApiExceptionController { 

    @ExceptionHandler(ValidationErrorException.class) 
    public ResponseEntity<?> appNotFoundException(ValidationErrorException exception) { 
     return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) 
      .body(new ErrorResponse(exception.getErrorCode(), exception.getMessage())); 
    } 
} 

以我的方式,我想创建一个筛选器,它将验证每个请求并在必要时抛出自定义异常。但事情是,我不能抛出自定义的异常,如下所示。

public class ValidationFilter implements Filter { 
    ... 
    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
     throws IOException, ServletException { 
     throw new ValidationErrorException(); // This is impossible 
    } 
    ... 
} 

如何在这种情况下抛出ValidationErrorException或有其他更好的方法来处理此类任务。

+0

是的,你可以...它只是一个'RuntimeException'或一个'ServletException'。此外,这与Spring没有关系,而是一般的Servlet API(甚至是一般的Java编程)。 –

回答

2

验证通常在Controller图层中的请求对象上完成,它们是从请求格式到服务器处理格式的transformed。例如JSON到Java对象。

因此,一旦通过完成整个filter链接来达到请求,就应该在Controller图层上执行或触发验证。

然后抛出以后可以在以下处理器处理任何验证异常,

@RestControllerAdvice 
public class RestApiExceptionController { 

    @ExceptionHandler(ValidationErrorException.class) 
    public ResponseEntity<?> appNotFoundException(ValidationErrorException exception) { 
     return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) 
      .body(new ErrorResponse(exception.getErrorCode(), exception.getMessage())); 
    } 
} 

的非常onefilters为目的,

之前拦截来自客户端的请求他们访问 后端的资源。

因此,真实的过滤器没有实际的资源尚未验证。一旦控制达到纠正component,你的情况是它是Controller

所以更好的方法是不要在filter组件上执行任何基于resource的验证。

+0

你是对的。但是,当我需要用户将加密的密码附加到HTTP Header时,我该如何验证每个请求并抛出ValidationErrorException(如果密码无效)呢? –

+0

@ChhornPonleu再次这是更多的设计决定。请查找Spring Security模块。您正在尝试根据请求进行授权/验证。它具有所有这些与安全相关的功能。所以抛出安全性例外而不是验证例外。 – ScanQR

+0

看起来Spring Security比我需要的功能更多。这就是为什么我寻求这种非常简单的解决方案。 –