将 dropzone 与 JSF 结合使用
Use dropzone with JSF
我想知道如何使用 dropzone.js 和 JSF 上传文件。在文档中 (http://www.dropzonejs.com/#usage) 它说使用 dropzone 就像使用:
<input type="file" name="file" />
但我不知道如何在JSF中实现服务器端部分来获取文件并将其存储在磁盘中。
看来您没有完全意识到 JSF 在这个问题的上下文中仅仅是一个 HTML 代码生成器。 JSF 提供了一个 <h:inputFile>
组件,它生成一个 HTML <input type="file">
元素。
亲自尝试一下:
<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>
看,有你的<input type="file">
元素!
现在,如果我们按照 its documentation (and you install the dropzone.js
file in your JSF project as per the instructions in How to reference CSS / JS / image resource in Facelets template?) 配置 Dropzone,那么我们最终应该在 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 需要考虑三件事:
- Dropzone
paramName
选项必须设置为生成的 <input type="file">
元素的 name
,即上例中的 uploadForm:file
。
- JSF 输入文件和命令按钮组件必须包装在具有 Dropzone 特定
class="fallback"
的元素中才能隐藏(并为 JavaScript/Ajax-deficient 客户端提供回退)。 不要删除它们,否则 JSF 将拒绝处理上传的文件,因为它需要根据组件树执行其工作。
save()
方法由setter 直接调用。这有点可疑,但由于 Dropzone 不提供直接触发支持 bean 操作方法的机会,因此这是最简单的解决方法。另一种解决方法是在 <h:inputFile>
上附加一个 valueChangeListener
并根据 How to get updated model values in a valueChangeListener method? 将事件排队到 INVOKE_APPLICATION
阶段
你的下一个问题应该是"How should I save it?"。既然如此,请继续:
- How to save uploaded file in JSF
- Recommended way to save uploaded files in a servlet application
我想知道如何使用 dropzone.js 和 JSF 上传文件。在文档中 (http://www.dropzonejs.com/#usage) 它说使用 dropzone 就像使用:
<input type="file" name="file" />
但我不知道如何在JSF中实现服务器端部分来获取文件并将其存储在磁盘中。
看来您没有完全意识到 JSF 在这个问题的上下文中仅仅是一个 HTML 代码生成器。 JSF 提供了一个 <h:inputFile>
组件,它生成一个 HTML <input type="file">
元素。
亲自尝试一下:
<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>
看,有你的<input type="file">
元素!
现在,如果我们按照 its documentation (and you install the dropzone.js
file in your JSF project as per the instructions in How to reference CSS / JS / image resource in Facelets template?) 配置 Dropzone,那么我们最终应该在 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 需要考虑三件事:
- Dropzone
paramName
选项必须设置为生成的<input type="file">
元素的name
,即上例中的uploadForm:file
。 - JSF 输入文件和命令按钮组件必须包装在具有 Dropzone 特定
class="fallback"
的元素中才能隐藏(并为 JavaScript/Ajax-deficient 客户端提供回退)。 不要删除它们,否则 JSF 将拒绝处理上传的文件,因为它需要根据组件树执行其工作。 save()
方法由setter 直接调用。这有点可疑,但由于 Dropzone 不提供直接触发支持 bean 操作方法的机会,因此这是最简单的解决方法。另一种解决方法是在<h:inputFile>
上附加一个valueChangeListener
并根据 How to get updated model values in a valueChangeListener method? 将事件排队到
INVOKE_APPLICATION
阶段
你的下一个问题应该是"How should I save it?"。既然如此,请继续:
- How to save uploaded file in JSF
- Recommended way to save uploaded files in a servlet application