java - OncePerRequestFilter 无法设置不同于 404 的错误代码

标签 java spring servlet-filters error-code

我有一个 Spring 应用程序(不使用 Spring boot)部署到 tomcat

我尝试使用 OncePerRequestFilter 在给定条件下的特定 URL 上返回错误 401 (HttpServletResponse.SC_UNAUTHORIZED),

但我不断收到“未找到”错误:

Response code: 404

我的过滤器(已删除条件):

@Component
public class MyFilter extends OncePerRequestFilter {

    private static final Logger logger = Logger.getLogger(MyFilter.class);
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Not autorized");           
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            try {
                PrintWriter out = response.getWriter();
                out.write(""); // Empty
                out.flush();
            } catch (IOException e) {
                logger.error("error filtering", e);
            }
            return; // stop chain
    }    
}

我尝试使用类似的代码 previous similar answer

I believe you can response.sendError inside do Filter method.

编辑

如果我只是抛出异常,我会得到一个通用错误代码 500

Response code: 500

编辑2

我在覆盖WebApplicationInitializeronStartup方法中添加过滤器

FilterRegistration myFilter = servletContext.addFilter("myFilter ", MyFilter.class);
myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint/*");

编辑3

还有我在 @Componenet 中的过滤器及其包包含在组件扫描中

@ComponentScan(basePackages = { "my.parent.pacakge"})

最佳答案

我尝试了你的代码,它有效。成功返回不同的错误代码。不过,我想指出一些事情 -

  1. sendError() 方法将响应发送到客户端,并清除响应缓冲区。因此,您在其后的响应中写入的任何内容都是没有用的。
  2. 调用setStatus()也没有用。当您调用 sendError() 时,上面这行中的 HTTP 响应和 HTTP 响应代码已经发送到客户端。

现在,这是我的假设,为什么你的代码不适合你,但它适合我 -

您收到 HTTP 404 的原因可能是您的 API 不存在。这可能是由于拼写错误,也可能是由于简单的无知,例如像 /foo/bar/ 一样调用名为 /foo/bar 的 API,即带有额外的尾部正斜杠。我相信您的过滤器已成功执行,您必须在那里做一些有用的事情,而不是您在问题中解释的 sendError() 示例代码。

此外,当您在过滤器中引发异常时,控件不会到达 API,并且不会发生 API 查找。因此,由于未处理的异常,默认的 HTTP 500 响应而不是 HTTP 404 被发送到客户端。

关于java - OncePerRequestFilter 无法设置不同于 404 的错误代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55456982/

相关文章:

java - 使用 jackson-dataformat-xml 库将 XML 中的空标记转换为 java 属性

java - 比较数组之间的所有元素并返回所有可能的匹配项

java - Jackson 根据字段值添加包装器

java - Spring框架问题

java - 如何在 Hibernate/JPA 中的映射/子表上删除现有记录并插入新记录

java - jax-ws 更改或包装 WSServlet

java - 引用不同 Java 文件中的方法

java - spring-cloud-config-aws-kms NoUniqueBeanDefinitionException : defaultTextEncryptor, kmsTextEncryptor

java - 有没有办法确定 Servlet Filter 执行的优先级?

spring - 如何使用 Spring Security 为微服务创建自定义安全过滤器