问题
I have a Spring application (not using Spring boot) deployed to tomcat
I'm trying to return error 401 (HttpServletResponse.SC_UNAUTHORIZED
) on specific URLs in given condition using OncePerRequestFilter
,
But I keep getting Not found error:
Response code: 404
My Filter(removed conditions):
@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
}
}
I tried using similar code to previous similar answer
I believe you can response.sendError inside do Filter method.
EDIT
If I just throw an exception instead I get a generic error code 500
Response code: 500
EDIT 2
I'm adding filter inside onStartup
method overriden WebApplicationInitializer
's
FilterRegistration myFilter = servletContext.addFilter("myFilter ", MyFilter.class);
myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint/*");
EDIT 3
Also my filter in @Componenet
and its package include in component scan
@ComponentScan(basePackages = { "my.parent.pacakge"})
回答1:
I tried your code and it works. Different error codes were getting successfully returned. Although, I wanna point out a couple of things-
- The method
sendError()
sends the response to the client and also clears the response buffer. So, anything you write after it into the response after that is of no use. - Calling
setStatus()
is of no use either. The HTTP response and HTTP response code has already been sent to the client in the above line when you calledsendError()
.
Now, this is my hypothesis why your code is not working for you, but it is for me-
The reason that you might be getting HTTP 404 is that your API is not present. This can be due to a spelling error or maybe due to a simple ignorance like calling your API named /foo/bar
like /foo/bar/
i.e. with extra trailing forward slash. I believe that your filter is getting executed successfully and you must be doing something useful there, not the sample code of sendError()
that you have explained in the question.
Also, when you throw an Exception in your filter, the control does not reach to the API and API lookup does not happen. Hence, the default HTTP 500 response is sent to the client due to the unhandled exception instead of HTTP 404.
回答2:
It return 401 as expected only if setStatus
is executed after out.write
PrintWriter out = response.getWriter();
out.write("");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
来源:https://stackoverflow.com/questions/55456982/onceperrequestfilter-unable-to-set-error-code-different-than-404