java OncePerRequestFilter无法设置与404不同的错误代码
我在tomcat上部署了一个Spring应用程序(不使用Spring boot)
我试图在给定条件下使用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
我正在onStartup
方法重写WebApplicationInitializer
的内部添加过滤器
FilterRegistration myFilter = servletContext.addFilter("myFilter ", MyFilter.class);
myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint/*");
编辑3
此外,我的过滤器在@Componenet
和它的包中包括在组件扫描中
@ComponentScan(basePackages = { "my.parent.pacakge"})
# 1 楼答案
只有在
out.write
之后执行setStatus
时,它才会像预期的那样返回401# 2 楼答案
我试过你的代码,效果很好。已成功返回不同的错误代码。不过我想指出几件事
sendError()
将响应发送到客户端,并清除响应缓冲区。所以,你在它后面写的任何东西都没有用李>setStatus()
也没有用。当您调用sendError()
时,HTTP响应和HTTP响应代码已经发送到上面一行中的客户端李>现在,这是我的假设,为什么你的代码不适合你,但它适合我-
您可能获得HTTP 404的原因是您的API不存在。这可能是由于拼写错误,也可能是由于简单的无知,比如调用名为
/foo/bar
的API,比如/foo/bar/
,即使用额外的尾部正斜杠。我相信您的过滤器正在成功执行,您一定在做一些有用的事情,而不是您在问题中解释的sendError()
的示例代码。此外,当您在过滤器中抛出异常时,控件不会到达API,也不会进行API查找。因此,由于未处理的异常而不是HTTP 404,默认HTTP 500响应被发送到客户端