Sol*_*lay 11 java servlets request http-headers servlet-filters
我正在尝试创建一个Java"过滤器"来检测自定义HTTP请求标头,并插入响应标头,以便文件自动下载.对此最重要的响应标头是"Content-Type = Attachment"响应标头.我创建了一个插入自定义标头的HTTP请求对象:
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());
}
Run Code Online (Sandbox Code Playgroud)
这会将X-Wria-Download标头插入请求中.然后我有一个Java过滤器,它查找该请求标头,并应将响应标头设置为"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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后当然web.xml有代码在所有jsp文件中包含Filter.
令我感到困惑的是,标题是在响应文件上设置的,但它不是应该下载的.如果我把res.setHeader("Content-Disposition","attachment; filename = success.pdf"); 在"if"语句之外的行,然后它将工作,但它将下载行为应用于我不想要的所有JSP.
当我在if语句中有res.setHeader时,为什么它应用了内容处理但没有工作; 然后在if语句之外工作?关于如何获得所需行为的任何想法(仅将内容处置应用于我已应用自定义请求标头的jsp)?
Ton*_*Rad 12
我认为您的问题与您Web Context在Web上下文中执行的过滤器顺序(即某些过滤器)有关,在过滤器后执行并覆盖标头.
所以你可以尝试:
.
...
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");
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您的代码将在调用Servlet之后执行,如下所述,如果您的过滤器是第一个在web.xml中声明的,那么setHeader代码将是最后执行的(见下图).

正如您所看到的,Filter1(在web.xml中声明的第一个)是在执行servlet之前执行的第一个,以及在执行servlet之后执行的最后一个.因此,如果您想确保最后一个Filter设置标题,则将其声明为Filter1.
执行顺序由Deployment Descriptor(web.xml)中的声明顺序决定:
Servlet规范(第6.2.4节):
"容器用于构建要应用于特定请求URI的过滤器链的顺序如下:
"1.首先,匹配过滤器的映射顺序与这些元素在部署描述符中出现的顺序相同.
"2.接下来,匹配过滤器的映射顺序与这些元素在部署描述符中出现的顺序相同."
所以要确保简单地将它声明为你的第一个过滤器web.xml.这样,它将是设置标题的最后一个过滤器.当然,如上所述,在调用后在代码中设置标题chain.doFilter.
小智 5
假设您使用其他人在此处描述的响应包装器,那么秘密就在于何时在原始响应上调用getWriter()!这是因为响应对象会忽略您要求作家之后添加的所有标头!
因此,请确保在调用getWriter()之前添加所有标头。这是我推荐的doFilter()序列:
创建响应包装
chain.doFilter(origRequest,包装器);
将所有必需的标题分配给原始(!)响应
从原始回复中获取作家
将包装器的内容复制到该作者
| 归档时间: |
|
| 查看次数: |
24109 次 |
| 最近记录: |