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

发布于 2024-12-14 03:34:40 字数 6319 浏览 1 评论 0原文

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

我的 bean

@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>

I have a tree (tree2 tomahawk 1.1.11) that shows a list of dirs and files. When I click on a file I would like to show the download dialog to let the client download the file. My page looks like

    ...
    <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>
    ...

And my bean is

@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";
    }
}

Everything works fine except I don't know how to achieve the download action when click on the h:commandLink

The only type of files I have are txt or csv.

UPDATE:

Now as I have the code, this exception is thrown.

javax.servlet.ServletException
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:422)
    org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:349)

UPDATE:

I'll post my 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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

本宫微胖 2024-12-21 03:34:40

基本上,您需要传递物理 文件或至少File#getAbsolutePath() 作为值,以便下载操作方法可以从磁盘读取它。我从未使用过 所以我检查了TreeNodeBase< /a> 并且它似乎不支持除 String description 作为节点值之外的任何内容。无法使用 File 来设置它。所以你真的需要通过 < code>File#getAbsolutePath() 进入其中。我认为您可以为此使用 Stringidentifier 参数:

tnb = new TreeNodeBase("file", f.getName(), f.getAbsolutePath(), false);

然后,在视图中,只需将其传递给操作方法:

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

Basically, you'd need to pass the physical File or at least File#getAbsolutePath() around as value so that the download action method can read it from disk. I've never used <t:tree2> so I checked the Javadoc of TreeNodeBase and it doesn't seem to support anything else than String description as node value. It's not possible to set it with a File. So you really need to pass File#getAbsolutePath() down into it. I think you can use the String identifier argument for this:

tnb = new TreeNodeBase("file", f.getName(), f.getAbsolutePath(), false);

Then, in the view, just pass it to the action method:

<h:commandLink action="#{listFiles.download(node.identifier)}" >

Finally, stream it as follows:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文