我有一棵树(tree2 tomahawk 1.1.11),它显示了目录和文件列表。当我点击一个文件时,我想显示下载对话框,让客户端下载文件。我的页面看起来像
...
<h:form>
<t:tree2 id="tree" value="#{listFiles.treeData}"
var="node" varNodeToggler="t" >
<f:facet name="folder">
<h:panelGroup>
<f:facet name="expand">
<t:graphicImage value="images/folderOpen.png"
rendered="#{t.nodeExpanded}}"
border="0" />
</f:facet>
<f:facet name="collapse">
<t:graphicImage value="images/folderClose.png"
rendere="#{t.nodeExpanded}}"
border="0" />
</f:facet>
<h:outputText value="#{node.description}"
styleClass="nodeFolder" />
</h:panelGroup>
</f:facet>
<f:facet name="file">
<h:panelGroup>
<h:commandLink action="#{listFiles.download()}" >
<t:graphicImage value="images/file.png" border="0" />
<h:outputText value="#{node.description}" />
</h:commandLink>
</h:panelGroup>
</f:facet>
</t:tree2>
</h:form>
...
我的豆是
@ManagedBean
@RequestScoped
public class ListFiles implements Serializable {
private String path = "C:\\";
private TreeNode treeRoot;
private File dirRoot;
@ManagedProperty("#{userVerifier}")
private UserVerifier userVerifier;
public void setUserVerifier(UserVerifier userVerifier) {
this.userVerifier = userVerifier;
}
public UserVerifier getUserVerifier() {
return userVerifier;
}
public TreeNode getTreeData() {
path = loadConfiguredPath();
String dependencia = userVerifier.getDependencia();
if (dependencia.equals("DESARROLLO")) {
path = path + "dataFiles";
treeRoot = new TreeNodeBase("folder", "SRC", false);
} else {
path = path + "dataFiles\\" + dependencia;
treeRoot = new TreeNodeBase("folder", dependencia, false);
}
dirRoot = new File(path);
createTree(dirRoot, treeRoot);
return treeRoot;
}
private void createTree(File fileRoot, TreeNode treeRoot) {
File[] files = fileRoot.listFiles();
TreeNodeBase tnb;
for (File f : files) {
if (f.isDirectory()) {
tnb = new TreeNodeBase("folder", f.getName(), false);
treeRoot.getChildren().add(tnb);
createTree(f, tnb);
}
if (f.isFile()) {
tnb = new TreeNodeBase("file", f.getName(), false);
treeRoot.getChildren().add(tnb);
}
}
return;
}
private String loadConfiguredPath() {
String dir;
ReadXML reader = new ReadXML(".\\webapps\\SRC\\configFiles\\confSRC.xml");
dir = reader.getValue("baseDir");
if (dir == null) {
return path;
} else {
return dir;
}
}
public String download(){
System.out.println("Yes we are downloading");
return "ok";
}
}
一切正常,但是当我点击 h:commandLink
时我不知道如何实现下载操作我拥有的唯一文件类型是txt或csv。
更新
现在我有了代码,抛出了这个异常。
javax.servlet.ServletException
javax.faces.webapp.FacesServlet.service(FacesServlet.java:422)
org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:349)
更新
我会发布我的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>MyFacesExtensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
<init-param>
<param-name>uploadMaxFileSize</param-name>
<param-value>5g</param-value>
</init-param>
<init-param>
<param-name>uploadThresholdSize</param-name>
<param-value>500m</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>/faces/*</servlet-name>
</filter-mapping>
<context-param>
<param-name>org.apache.myfaces.CHECK_EXTENSIONS_FILTER</param-name>
<param-value>false</param-value>
</context-param>
</web-app>
答案 0 :(得分:1)
基本上,您需要将物理File
或至少File#getAbsolutePath()
作为值传递,以便下载操作方法可以从磁盘读取它。我从未使用<t:tree2>
所以我检查了TreeNodeBase
的Javadoc,它似乎不支持String description
以外的任何其他节点值。无法使用File
进行设置。所以你真的需要将File#getAbsolutePath()
传递给它。我认为您可以使用String identifier
参数:
tnb = new TreeNodeBase("file", f.getName(), f.getAbsolutePath(), false);
然后,在视图中,只需将其传递给action方法:
<h:commandLink action="#{listFiles.download(node.identifier)}" >
最后,按如下方式流式传输:
public String download(String absolutePath) throws IOException {
File file = new File(absolutePath);
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.setResponseHeader("Content-Type", externalContext.getMimeType(file.getName()));
externalContext.setResponseHeader("Content-Length", String.valueOf(file.length()));
externalContext.setResponseHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");
InputStream input = null;
OutputStream output = null;;
try {
input = new FileInputStream(file);
output = externalContext.getResponseOutputStream();
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}
facesContext.responseComplete();
}