Java filter failing to set response headers

前端 未结 4 1849
太阳男子
太阳男子 2021-01-11 15:14

I am trying to create a Java \"Filter\" which detects a custom HTTP Request Header, and inserts response headers so that the file will download automatically. The response

相关标签:
4条回答
  • 2021-01-11 15:50

    Assuming you use a response wrapper as described here by others, the whole secret is when to call getWriter() on the original response! That's because the response object ignores all headers added AFTER you asked for a writer!

    So, make sure you add all your headers Before you call getWriter(). Here is my recommended sequence for doFilter():

    1. Create a response wrapper

    2. chain.doFilter (origRequest, wrapper);

    3. Assign all required headers to the original (!) Response

    4. Get writer from original response

    5. Copy the wrapper's content to this writer

    0 讨论(0)
  • 2021-01-11 16:00

    The problem is the header(X-Wria-Download) of your AjaxRequest (here XMLHttpRequest) is not being set in your HttpServletRequest object before the filter is being served.

    I think better Idea will be to use a Dedicated Servlet to handle your ajax request.

    0 讨论(0)
  • 2021-01-11 16:07

    I think your issue is related to the Filter order of execution of your Web Context, i.e. some filters, in you web context, executes after your filter and override the header.

    The Servlet Filter is an implementation of the Chain of Responsibility pattern

    So you may try to:

    • Set the headers after the call to chain.doFilter:

    .

    ...
    
    chain.doFilter(req,res);
    
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    
    //get the headers we placed in the request
    //based on those request headers, set some response headers
    
    if(req.getHeader("X-Wria-Download") != null){
        res.setHeader("Content-Type", "application/pdf");
        res.setHeader("Content-Disposition", "attachment; filename=success.pdf");
    }
    

    In this way your code will be executed after that the Servlet is called and, as explained below, if your filter is the first declared in web.xml, then the setHeader code will be the last executed (see image below).

    • make sure that your filter is the last to be executed after the Servlet is executed, i.e. it should be the first servlet Filter declared as explained here:

    enter image description here

    As you can see Filter1 (the first declared in web.xml) is the first one executed before the servlet is executed and the last one executed after the servlet is executed. So if you want to be sure to be the last Filter setting the header then declare it as Filter1.

    The order of execution is determined by the order of declaration in your Deployment Descriptor (web.xml):

    Servlet spec (section 6.2.4):

    "The order the container uses in building the chain of filters to be applied for a particular request URI is as follows:

    "1. First, the matching filter mappings in the same order that these elements appear in the deployment descriptor.

    "2. Next, the matching filter mappings in the same order that these elements appear in the deployment descriptor."

    So to be sure simply declare it as the first filter in your web.xml. In this way it will be the very last filter setting the header. And, of course, set the header in your code after calling chain.doFilter, as already said.

    0 讨论(0)
  • 2021-01-11 16:07

    Try this: set an attribute on the request if the request header is present. Then, check for the attribute after the chain.doFilter(...) and set the response headers then.

    0 讨论(0)
提交回复
热议问题