Java filter cannot set response headers

I am trying to create a Java filter that detects a custom HTTP request header and inserts response headers so that the file loads automatically. Most important for this is the response header - the response header is "Content-Type = Attachment". I created an HTTP request object that inserts a custom header:

function myHttpObject(filePath){ function makeHttpObject() { return new XMLHttpRequest(); } var request = makeHttpObject(); request.open("GET", filePath, false); request.setRequestHeader("X-Wria-Download", "PDFdownload"); request.send(null); window.open(filePath); console.log(request.getAllResponseHeaders()); } 

This will include the X-Wria-Download header in the request. Then I have a Java filter that searches for this request header and should set the response header to "Content-Type = attachment"

 import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class Contenttypefilter implements Filter { protected FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { //noop } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 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"); } chain.doFilter(req,res); } } 

And then, of course, web.xml has the code to include the filter in all jsp files.

The thing that puzzles me is that the header is set in the answer file, but it does not load as it should. If I put res.setHeader ("Content-Disposition", "attachment; filename = success.pdf"); line outside the if statement, then it will work, but it will apply the loading behavior to all JSPs that I don't want.

Why does it apply content placement, but does not work when I have res.setHeader in an if statement; and then it works when it is outside the if statement? Any ideas on how I can get the desired behavior (only by applying content placement to jsp to which I applied the custom request header)?

+8
java servlets servlet-filters request
source share
4 answers

I think your problem is with the filter order of your Web Context , i.e. some filters, in your web context, run after your filter and override the title.

The Servlet Filter is an implementation of the Responsibility Chain template.

So you can try:

  • Set the headers after calling 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"); } 

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

  • make sure your filter runs last 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 one declared in web.xml) is the first one that was executed before the servlet was executed, and the last one was executed after the servlet was executed. Therefore, if you want to be the last filter, select the header and then declare it as Filter1.

The order of execution is determined by the order of declaration in the deployment descriptor (web.xml):

Servlet specification (section 6.2.4):

"The order that the container uses when creating the filter chain is applied to a specific URI request as follows:

"1. First, matching matching filters is the same so that these items appear in the deployment descriptor.

"2. Then the corresponding filter mappings are the same so that these items appear in the deployment descriptor."

So, just declare it as the first filter in web.xml . Thus, this is the most recent header filter. And, of course, set the title to your code after calling chain.doFilter , as already mentioned.

+11
source share

Assuming you are using the response wrapper as described here by others, the whole secret is when to call getWriter () in the original answer! This is because the response object ignores all headers added AFTER you asked the author!

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

  • Create response wrapper

  • chain.doFilter (origRequest, wrapper);

  • Assign all necessary headers to the original (!) Response

  • Get a record from the original answer

  • Copy the contents of the wrapper to this writer.

+2
source share

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

0
source share

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

I think a better idea would be to use a dedicated servlet to handle your ajax request .

0
source share

All Articles