使用commandLink和Tree2 tomahawk JSF显示/下载txt或csv文件

时间:2011-11-08 19:09:12

标签: jsf tree download commandlink

我有一棵树(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>

1 个答案:

答案 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();
}