【问题标题】:Spring - Changing Order of Global Error handler and FilterSpring - 更改全局错误处理程序和过滤器的顺序
【发布时间】:2019-02-17 12:39:48
【问题描述】:

我有一个过滤器,例如:

@Component
@Order(8)
public class LogReqFilter extends OncePerRequestFilter
{
@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException 
{...}
}

it basically logs all requests and responses. When there is a 400 error however the response is blank. There is a global exception handler that replaces the body with the custom error:

@RestControllerAdvice
public class GlobalExceptHandler extends ResponseEntityExceptionHandler {
    @Override
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    protected ResponseEntity<Object> handleArgNotValid(MethodArgumentNotValidException ex
            , HttpHeaders headers, HttpStatus status, WebRequest request) {...}
}

我注意到在过滤器之后调用了全局异常处理程序,我认为这就是过滤器中响应为空白的原因。有没有办法在全局异常处理程序之后调用过滤器?

【问题讨论】:

  • 你应该使用AOP而不是过滤器

标签: spring spring-boot


【解决方案1】:

已编辑:

TLDR

不,您不能根据 OP 标题更改顺序,因为您的 GlobalError 处理程序始终位于包含 ControllerAdvices 的层中,并且始终位于 RequestFilter 层和控制器之间。

加长版

你说的有点对。

我建议你参考这个答案:https://stackoverflow.com/a/17716298/405749

对此进行扩展:

  • 请注意,之前和之后取决于您查看的对象,即。
    • 入站(在到达您的控制器代码之前)或
    • 出站(控制器完成后)
  • 现在您可以在此路径上插入不同的组件,例如这里 RequestFilter 和 Controller Advice
  • 根据您实施的方法,它仅在入站或出站轨道或两者上调用,此处:
    • doFilterInternal() 称为入站。仅当您调用 filterChain.doFilter(request, response); 时,请求才会在入站轨道上继续,否则它会在此处停止并返回响应,其中包含其输出流中已有的内容或将由此过滤器添加或在出路时仍会遇到过滤器
  • 这是假设我们只有这个过滤器和建议的调用序列
    1. 'inbound' - 来自请求过滤器的方法
    2. 'inbound' - 来自控制器建议的方法
    3. “出站”-来自控制器建议的方法
    4. 'outbound' - 来自请求过滤器的方法

现在,handleArgNotValid() 仅在抛出此类异常并可能将内容添加到 Response-Output 流时才被调用。您的示例未显示您是否在此处返回对象,但我从您的 OP 中猜测您没有。因此输出流是空的。

还请注意,除非您包装它,否则没有简单的方法可以转储/查看输出流,但这是另一个主题。

【讨论】:

    猜你喜欢
    • 2013-03-06
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多