Jsf h:未调用commandButton操作方法

Jsf h:未调用commandButton操作方法,jsf,jsf-2.2,Jsf,Jsf 2.2,我有下面的按钮: <h:commandButton value="Download" action="#{listFiles.downloadFile}" /> 但当我按下按钮时,什么也没发生。不调用操作方法 在服务器日志中,我看到: 表单组件需要在其祖先中具有UIForm。建议:在 这是我的工作 文件夹路径中的我的文件 WEB-INF\pages\forms xhtml文件中的cod <h:commandLink value="Download" action="#{fo

我有下面的按钮:

<h:commandButton value="Download" action="#{listFiles.downloadFile}" />
但当我按下按钮时,什么也没发生。不调用操作方法

在服务器日志中,我看到:

表单组件需要在其祖先中具有UIForm。建议:在

这是我的工作

文件夹路径中的我的文件

WEB-INF\pages\forms
xhtml
文件中的cod

<h:commandLink value="Download" action="#{formBean.downloadFile('FileName.doc')}" styleClass="link"/>

是的,但我的文件在应用程序包之外。对此有什么解决方案吗?没问题此报告路径更改:String reportPath=“C:/report”+File.separator+文件名;出于某种原因,我得到
表单组件需要在其祖先中有一个UIForm。建议:将必要的组件封装在
中,尽量包括
<h:commandLink value="Download" action="#{formBean.downloadFile('FileName.doc')}" styleClass="link"/>
public String downloadFile(String fileName) {
        try {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpServletResponse response = ((HttpServletResponse) facesContext.getExternalContext().getResponse());
            String reportPath = facesContext.getExternalContext().getRealPath("\\pages\\forms") + File.separator + fileName;

            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName+ "\"");

            File file = new File(reportPath);

            BufferedInputStream bIn = new BufferedInputStream(new FileInputStream(file));

            int rLength = -1;

            byte[] buffer = new byte[1000];

            while ((rLength = bIn.read(buffer, 0, 100)) != -1) {
                response.getOutputStream().write(buffer, 0, rLength);
            }

            FacesContext.getCurrentInstance().responseComplete();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }