OncePerRequestFilter无法设置与404不同的错误代码

时间:2019-04-01 14:00:40

标签: java spring servlet-filters error-code

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

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

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

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类似的代码

  

我相信您可以在Filter方法中使用response.sendError。

编辑

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

Response code: 500

编辑2

我在onStartup的{​​{1}}方法内添加过滤器

WebApplicationInitializer

编辑3

我在FilterRegistration myFilter = servletContext.addFilter("myFilter ", MyFilter.class); myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint/*"); 中的过滤器及其软件包也包含在组件扫描中

@Componenet

2 个答案:

答案 0 :(得分:1)

我尝试了您的代码,它可以工作。不同的错误代码已成功返回。虽然,我想指出几件事-

  1. 方法sendError()将响应发送到客户端,并清除响应缓冲区。因此,之后写到响应中的任何内容都是没有用的。
  2. 呼叫setStatus()也没有用。调用sendError()时,上一行中的HTTP响应和HTTP响应代码已发送给客户端。

现在,这就是我的假设,为什么您的代码对您不起作用,但对我却有效-

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

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

答案 1 :(得分:0)

仅在out.write之后执行PrintWriter out = response.getWriter(); out.write(""); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 时,它才按预期返回401。

{{1}}