OncePerRequestFilter 无法设置不同于 404 的错误代码
OncePerRequestFilter unable to set error code different than 404
我有一个 Spring 应用程序(不使用 Spring 启动)部署到 tomcat
我正在尝试 return 错误 401 (HttpServletResponse.SC_UNAUTHORIZED
) 在特定条件下使用 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
类似的代码
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"})
只有在 out.write
之后执行 setStatus
时,才会 return 401
PrintWriter out = response.getWriter();
out.write("");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
我试过你的代码,它有效。成功返回了不同的错误代码。虽然,我想指出几件事-
- 方法
sendError()
向客户端发送响应并清除响应缓冲区。所以,你在它之后写到响应中的任何东西都是没有用的。
- 叫
setStatus()
也没用。当您调用 sendError()
. 时,HTTP 响应和 HTTP 响应代码已在上面的行中发送给客户端
现在,这就是我的假设,为什么你的代码不适合你,但它适合我——
您收到 HTTP 404 的原因可能是您的 API 不存在。这可能是由于拼写错误或可能是由于简单的无知,例如将您的 API 命名为 /foo/bar
称为 /foo/bar/
,即带有额外的尾部正斜杠。我相信您的过滤器已成功执行,并且您必须在那里做一些有用的事情,而不是您在问题中解释的 sendError()
示例代码。
此外,当您在过滤器中抛出异常时,控件不会到达 API 并且 API 查找不会发生。因此,由于未处理的异常而不是 HTTP 404,默认的 HTTP 500 响应被发送到客户端。
我有一个 Spring 应用程序(不使用 Spring 启动)部署到 tomcat
我正在尝试 return 错误 401 (HttpServletResponse.SC_UNAUTHORIZED
) 在特定条件下使用 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
类似的代码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"})
只有在 out.write
setStatus
时,才会 return 401
PrintWriter out = response.getWriter();
out.write("");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
我试过你的代码,它有效。成功返回了不同的错误代码。虽然,我想指出几件事-
- 方法
sendError()
向客户端发送响应并清除响应缓冲区。所以,你在它之后写到响应中的任何东西都是没有用的。 - 叫
setStatus()
也没用。当您调用sendError()
. 时,HTTP 响应和 HTTP 响应代码已在上面的行中发送给客户端
现在,这就是我的假设,为什么你的代码不适合你,但它适合我——
您收到 HTTP 404 的原因可能是您的 API 不存在。这可能是由于拼写错误或可能是由于简单的无知,例如将您的 API 命名为 /foo/bar
称为 /foo/bar/
,即带有额外的尾部正斜杠。我相信您的过滤器已成功执行,并且您必须在那里做一些有用的事情,而不是您在问题中解释的 sendError()
示例代码。
此外,当您在过滤器中抛出异常时,控件不会到达 API 并且 API 查找不会发生。因此,由于未处理的异常而不是 HTTP 404,默认的 HTTP 500 响应被发送到客户端。