在JSF中使用dropzone [英] Use dropzone with JSF
问题描述
我想知道如何在JSF上使用dropzone.js来上传文件。在文档中( http://www.dropzonejs.com/#usage ),它表示使用dropzone就像使用:
< input type =filename =file/>
但是我不知道如何在JSF中实现服务器端部分来获取文件将它存储在磁盘中。
看来你并没有完全意识到JSF只是在这个问题的背景下HTML代码生成器。 JSF提供了 < h:inputFile>
组件,它生成一个HTML < input type =file>
元素。
< h:form id = uploadFormenctype =multipart / form-data>
< h:inputFile id =filevalue =#{bean.file}/>
< h:commandButton id =submitvalue =submit/>
< / h:表格>
如果您在浏览器中打开JSF页面并右键单击
$ p $
< form id =uploadFormname =uploadFormmethod = postaction =/ playground / test.xhtmlenctype =multipart / form-data>
< input type =hiddenname =uploadFormvalue =uploadForm/>
< input id =uploadForm:filetype =filename =uploadForm:file/>
< input type =submitname =uploadForm:submitvalue =submit/>
< input type =hiddenname =javax.faces.ViewStateid =j_id1:javax.faces.ViewState:0value =3646344859491704387:-5449990057208847169autocomplete =off/>
< / form>
请看< input type =file> 元素!
现在,如果我们将Dropzone配置为它的文档(并且根据 dropzone.js 如何在Facelets模板中引用CSS / JS /图像资源? ,那么我们最终应该在JSF页面中找到这样的内容:
< h:head>
...
< h:outputScript name =dropzone.js/>
< h:outputScript> Dropzone.options.uploadForm = {paramName:uploadForm:file};< / h:outputScript>
< / h:头>
< h:body>
< h:form id =uploadFormenctype =multipart / form-datastyleClass =dropzone>
< div class =fallback>
< h:inputFile id =filevalue =#{bean.file}/>
< h:commandButton id =submitvalue =submit/>
< / div>
< / h:表格>
< / h:body>
这个bean看起来就像这样:
<$ @
@RequestScoped
public class Bean {
private private file;
$ b $ 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;
$ b $ public void setFile(Part file)throws IOException {
this.file = file;
save();
$ b $ / code $ / pre
有三件事情要考虑使用JSF帐户:
- Dropzone
paramName
选项必须设置为< code>< code>< code>< $ $ c $元素> :
- JSF输入文件和命令按钮组件必须包含在一个Dropzone特有的
类的元素中=fallback
以便隐藏(并提供JavaScript / Ajax缺陷客户端的后备)。不要不要删除它们,否则JSF将拒绝处理上传的文件,因为它需要根据组件树来执行它的工作。save()
方法由setter直接调用。这有点可疑,但是由于Dropzone没有提供直接触发支持bean操作方法的机会,所以这是最简单的解决方法。另一个解决方法是在< h:inputFile>
上附加valueChangeListener
,并将事件排队到INVOKE_APPLICATION
阶段根据如何在valueChangeListener方法中获取更新的模型值?
- JSF输入文件和命令按钮组件必须包含在一个Dropzone特有的
您的下一个问题可能是我应该如何保存它?。在这种情况下,继续在这里:
I would like to know how to use dropzone.js with JSF for upload a file. In the documentation (http://www.dropzonejs.com/#usage) it says that using dropzone is like using:
<input type="file" name="file" />
But I don't know how to implement the server-side part in JSF to get the file and store it in disk.
It appears that you don't exactly realize that JSF is in the context of this question merely a HTML code generator. JSF offers a <h:inputFile>
component which generates a HTML <input type="file">
element.
Try it yourself:
<h:form id="uploadForm" enctype="multipart/form-data">
<h:inputFile id="file" value="#{bean.file}" />
<h:commandButton id="submit" value="submit" />
</h:form>
If you open the JSF page in a webbrowser and do rightclick and View Page Source, then you should see something like this:
<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>
Look, there is your <input type="file">
element!
Now, if we configure Dropzone as per 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?), then we should end up in the JSF page with something like this:
<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>
The bean looks just like this:
@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();
}
}
There are 3 things to take into account with JSF:
- The Dropzone
paramName
option must be set to exactly thename
of the generated<input type="file">
element, which isuploadForm:file
in the above example. - The JSF input file and command button components must be wrapped in an element with Dropzone-specific
class="fallback"
in order to be hidden (and provide a fallback for JavaScript/Ajax-deficient clients). Do not remove them, otherwise JSF will refuse to process the uploaded file, because it needs to perform its job based on the component tree. - The
save()
method is invoked directly by the setter. This is kind of fishy, but as Dropzone doesn't offer an opportunity to directly trigger a backing bean action method, this is the easiest workaround. Another workaround is to attach avalueChangeListener
on the<h:inputFile>
and queue the event to theINVOKE_APPLICATION
phase as per How to get updated model values in a valueChangeListener method?
Your next question shall probably be "How should I save it?". In that case, continue here:
这篇关于在JSF中使用dropzone的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!