OncePerRequestFilter unable to set error code different than 404

纵饮孤独 提交于 2019-12-11 07:05:40

问题


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-

  1. 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.
  2. 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 called sendError().

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!