MyFaces
ExtensionsFilter显然将_整个_响应缓冲在服务器的内存中,直到最后一位为止。因此,您基本上有2个选择:
摆脱MyFaces
ExtensionsFilter
。不要让请求点击MyFaces
ExtensionsFilter
。
如果您实际上需要Web应用程序中的某些功能要求,那么选项1可能会非常激烈,但是如果可以找到替代方法,则可行。例如,如果您仅需要它来处理文件上传,则可以考虑为此使用替代组件库,甚至是标准JSF
2.2。
选项2可以通过两种方式实现:
- 更改过滤器的URL模式,以使下载请求不会被点击。如果您可以确定您真正需要哪个URL
ExtensionsFilter
,则可以相应地对其<filter-mapping>
进行更改,以使其仅在那些URL上完全起作用,而不是在URL上全局起作用FacesServlet
。
例如,当仅应调用它时
/upload.jsf,请替换
<servlet-name>为
<url-pattern>:
<filter-mapping> <filter-name>MyFacesExtensionsFilter</filter-name> <url-pattern>/upload.jsf</url-pattern></filter-mapping>
仅当您实际上从同一页面执行下载操作时,这才很麻烦。
- 更改下载请求URL,以免其到达过滤器。如果您不仅可以将这些文件放在公共Web内容中,也不能将带有文件的文件夹添加为另一个上下文,则一种方法是将所有下载服务代码从将JSF管理的bean转换为普通的servlet。然后,只需让链接URL或表单操作指向该servlet。由于该请求将不会被点击
FacesServlet
,因此ExtensionsFilter
也不会被点击。
例如
@WebServlet("/files/*")public class FileServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String filename = request.getPathInfo().substring(1); // Just do your job to get the File or InputStream, depending on the functional requirements. // This kickoff example just allocates a file in the file system. File file = new File("/path/to/files", filename); response.setHeader("Content-Type", getServletContext().getMimetype(filename)); response.setHeader("Content-Length", String.valueOf(file.length())); response.setHeader("Content-Disposition", "attachment; filename="" + filename + """); Files.copy(file.toPath(), response.getOutputStream()); }}(注意:如果您仍未使用Servlet 3.0,请替换@WebServlet
为;中的常规Servlet映射web.xml
;如果您仍不在Java
7上,请替换Files#copy()
为常规的InputStream
/ OutputStream
循环样板)
调用它的方式如下(假设您已链接到JSF1.2的Tomahawk的源代码;因此不支持模板文本中的EL,那么请假设在JSP上使用旧版JSF 1.2)。
<h:outputlink value="#{request.contextPath}/files/#{bean.filename}"> <h:outputText value="Download #{bean.filename}" /></h:outputlink>如果下载需要其他参数,请使用传递它们
<f:param>:
<h:outputlink value="#{request.contextPath}/files/#{bean.filename}"> <f:param name="foo" value="#{bean.foo}" /> <f:param name="bar" value="#{bean.bar}" /> <h:outputText value="Download #{bean.filename}" /></h:outputlink>然后可以在servlet中获得,如下所示:
String foo = request.getParameter("foo");String bar = request.getParameter("bar");// ...


