我有一个 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
我在覆盖WebApplicationInitializer
的onStartup
方法中添加过滤器
FilterRegistration myFilter = servletContext.addFilter("myFilter ", MyFilter.class);
myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint/*");
编辑3
还有我在 @Componenet
中的过滤器及其包包含在组件扫描中
@ComponentScan(basePackages = { "my.parent.pacakge"})
最佳答案
我尝试了你的代码,它有效。成功返回不同的错误代码。不过,我想指出一些事情 -
sendError()
方法将响应发送到客户端,并清除响应缓冲区。因此,您在其后的响应中写入的任何内容都是没有用的。- 调用
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/