【问题标题】:Use dropzone with JSF将 dropzone 与 JSF 一起使用
【发布时间】:2016-10-27 09:10:31
【问题描述】:

我想知道如何使用带有 JSF 的 dropzone.js 来上传文件。在文档 (http://www.dropzonejs.com/#usage) 中,它说使用 dropzone 就像使用:

   <input type="file" name="file" />

但我不知道如何在 JSF 中实现服务器端部分来获取文件并将其存储在磁盘中。

【问题讨论】:

标签: jsf file-upload dropzone.js


【解决方案1】:

您似乎并没有完全意识到 JSF 在这个问题的上下文中仅仅是一个 HTML 代码生成器。 JSF 提供了一个&lt;h:inputFile&gt; 组件,它生成一个HTML &lt;input type="file"&gt; 元素。

自己试试吧:

<h:form id="uploadForm" enctype="multipart/form-data">
    <h:inputFile id="file" value="#{bean.file}" />
    <h:commandButton id="submit" value="submit" />
</h:form>

如果您在网络浏览器中打开 JSF 页面并右键单击并查看页面源代码,那么您应该会看到如下内容:

<form id="uploadForm" name="uploadForm" method="post" action="/playground/test.xhtml" enctype="multipart/form-data">
    <input type="hidden" name="uploadForm" value="uploadForm" />
    <input id="uploadForm:file" type="file" name="uploadForm:file" />
    <input type="submit" name="uploadForm:submit" value="submit" />
    <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="3646344859491704387:-5449990057208847169" autocomplete="off" />
</form>

看,有你的&lt;input type="file"&gt; 元素!

现在,如果我们按照 its documentation 配置 Dropzone(并且您按照 How to reference CSS / JS / image resource in Facelets template? 中的说明在您的 JSF 项目中安装 dropzone.js 文件),那么我们最终应该会在 JSF 页面中显示类似这样的内容:

<h:head>
    ...
    <h:outputScript name="dropzone.js" />
    <h:outputScript>Dropzone.options.uploadForm = { paramName: "uploadForm:file" };</h:outputScript>
</h:head>
<h:body>
    <h:form id="uploadForm" enctype="multipart/form-data" styleClass="dropzone">
        <div class="fallback">
            <h:inputFile id="file" value="#{bean.file}" />
            <h:commandButton id="submit" value="submit" />
        </div>
    </h:form>
</h:body>

bean 看起来像这样:

@Named
@RequestScoped
public class Bean {

    private Part file;

    public void save() throws IOException {
        String fileName = file.getSubmittedFileName();
        String contentType = file.getContentType();
        long size = file.getSize();
        InputStream content = file.getInputStream();
        // ...
    }

    public Part getFile() {
        return file;
    }

    public void setFile(Part file) throws IOException {
        this.file = file;
        save();
    }

}

使用 JSF 需要考虑 3 件事:

  1. Dropzone paramName 选项必须设置为生成的&lt;input type="file"&gt; 元素的name,在上面的示例中为uploadForm:file
  2. JSF 输入文件和命令按钮组件必须包含在具有 Dropzone 特定 class="fallback" 的元素中才能隐藏(并为缺乏 JavaScript/Ajax 的客户端提供回退)。 不要删除它们,否则 JSF 将拒绝处理上传的文件,因为它需要根据组件树执行其工作。
  3. save() 方法由 setter 直接调用。这有点可疑,但由于 Dropzone 不提供直接触发支持 bean 操作方法的机会,因此这是最简单的解决方法。另一种解决方法是在&lt;h:inputFile&gt; 上附加valueChangeListener,并按照How to get updated model values in a valueChangeListener method? 将事件排队到INVOKE_APPLICATION 阶段

您的下一个问题可能是“我应该如何保存它?”。在这种情况下,请在此处继续:

【讨论】:

  • 如果我需要向save方法传递一个参数,我该怎么做?我需要通过#{album.id}
  • 照常添加&lt;h:inputHidden value="#{album.id}" /&gt;即可。
  • 很抱歉,我无法获取专辑 ID。我正在使用这个: 和 String albumId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("hiddenAlbumId") ;但它不起作用我总是收到 null
  • 问一个新问题。当前形式的问题中没有涵盖此细节。我不知道你在说什么背景。答案适用于当前形式的问题。还是没有?
  • @BalusC 我按照上面提到的步骤进行操作,但是当我将文件放到 dropzone 中时,会在 bean 中调用 getter,而不是 setter。实际上 setter 永远不会被调用。你知道什么会导致这种行为吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2012-12-30
  • 2016-01-29
相关资源
最近更新 更多