JSF 2.2 - 文件上传不适用于 Ajax。表单的编码类型似乎不正确(仅通过 AJAX)
Posted
技术标签:
【中文标题】JSF 2.2 - 文件上传不适用于 Ajax。表单的编码类型似乎不正确(仅通过 AJAX)【英文标题】:JSF 2.2 - fileupload does not work with Ajax. Form appears to have incorrect enctype (only via AJAX) 【发布时间】:2013-04-26 13:14:22 【问题描述】:尝试实现 JSF 2.2 示例我有以下代码:
<h:form prependId="false" enctype="multipart/form-data">
<!-- Now it's the AJAX file upload component -->
<h:inputFile id="fileUpload" value="#someBean.file" >
<f:ajax />
</h:inputFile>
<h:commandButton value="Upload" />
</h:form>
根据一些 JSF 2.2 这应该可以工作,但在我的情况下它给了我以下错误:
请求不包含 multipart/form-data 或 multipart/mixed 流,内容类型标头是 应用程序/x-www-form-urlencoded;charset=UTF-8
查看请求虽然我已正确设置表单编码类型,但部分请求已提交:
内容类型:application/x-www-form-urlencoded;charset=UTF-8 Faces-Request:partial/ajax
注意,web.xml 也被修改为:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<multipart-config>
<location>c:\dotmp</location>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
我使用的是 Mojarra 2.2.0-m15,但也尝试过使用早期版本。有谁知道有关此问题的任何有用信息,我认为这是一个错误?
【问题讨论】:
【参考方案1】:我不确定发生了什么,因为我以前从未见过。当使用今天的 Mojarra 2.2.1 快照时,以下构造适用于我,您可以从 What's new in JSF 2.2? 中提到的“implementation jar”链接下载该快照
<h:form enctype="multipart/form-data">
<h:inputFile value="#bean.file" required="true">
<f:ajax listener="#bean.handleFileUpload" render="@form" />
</h:inputFile>
<h:messages />
</h:form>
与
private Part file;
public void handleFileUpload(AjaxBehaviorEvent event)
System.out.println("file size: " + file.getSize());
System.out.println("file type: " + file.getContentType());
System.out.println("file info: " + file.getHeader("Content-Disposition"));
// ...
我建议尝试较新的 Mojarra 版本。显然,在较旧的 Mojarra 版本中存在一个错误,该错误无法使用 <iframe>
hack 创建正确的 multipart/form-data
请求,最终导致此错误。 mXX
版本无论如何都是 beta 版本,不应依赖于生产。这个错误理论上也可能是特定于浏览器的,但它目前在 Chrome 26、Firefox 20 和 IE 10 中对我来说可以正常工作。
我看到的唯一问题是隐藏的<iframe>
在 Chrome 和 Firefox 中仍然可见,如下所示:
似乎他们忘记在生成的<iframe>
中将frameborder
属性设置为0
。我已经报告了issue 2861。
【讨论】:
感谢 BalusC 的回复。我对 JSF2.2 很恼火,所以切换回最新版本的 JSF2.1 并使用您的 Omnifaces 渲染工具包用于 html5。对于 filwdownload,我从 balusc.blogspot.co.uk/2009/12/… 遵循了您的教程,令人惊讶的是,我得到了完全相同的错误。原因:org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException:请求不包含 multipart/form-data 或 multipart/mixed 流,内容类型标头为 application/x-www-form-urlencoded ;charset=UTF-8 也许您正在嵌套表单?如果您曾经试图将问题隔离为一个完全值得的 SSCCE,那将是一个相当明显的错误。 希望我有那么幸运。我上面的内容是在它自己的页面上以及您的示例中的代码。这只是一种形式,只有在我使用 Ajax 提交时才会发生,否则它可以正常工作。 我博客中的 JSF 2.0 文件上传组件与 f:ajax 不兼容。 JSF 2.2 内置的文件上传组件是。 我试过你提供的罐子,效果很好。据我所知,javascript没有考虑表单类型,而是为表单类型做出了自己的决定。你知道有最新 jsf2.2.1-SNAPSHOT 的 maven 仓库吗?【参考方案2】:我修复了 JSF(和其他部分)的 JavaScript,以在 servlet 标准 2 上启用带和不带 AJAX 的多部分请求。
JSF 2.2 文件上传从 servlet 版本 3 开始工作。此外,称为“IFrame Transport”的负责传输层未处于发布状态。所以我添加了一个透明的Multipart请求,完成了传输层并将所有内容放在一起上传标签:
<e:inputFile id="file" value="#fileUpload.file" filename="#fileUpload.filename"
mimeType="#fileUpload.mimeType"/>
标签与 AJAX、传统页面提交和 servlet 标准 2 / 3 一起使用。不是最好的实现,但它的工作几乎是透明的。该解决方案可通过http://www.intersult.com/wiki/page/JSF%20Ext#section-JSF+Ext-FileUpload 访问(请使用翻译)。
欢迎评论。
【讨论】:
你向 JSF 的人报告过吗? 我在几周前提出了一个相关的错误,但仍在等待中。见:java.net/jira/browse/JAVASERVERFACES-2871【参考方案3】:我在 PrimeFaces <p:fileUpload mode="simple"
使用 javax.faces-2.2.6.jar 时遇到了同样的问题。当我从 <h:commandButton
禁用 ajax 时,问题消失了。在我的情况下,刷新整个页面是可以的。
【讨论】:
以上是关于JSF 2.2 - 文件上传不适用于 Ajax。表单的编码类型似乎不正确(仅通过 AJAX)的主要内容,如果未能解决你的问题,请参考以下文章
JSF 2.2 h:inputFile 不适用于漂亮的面孔[重复]
JSF 2.2 webapp适用于本地计算机,但不适用于服务器
Spring Security 3.1.4 taglib 授权/身份验证不适用于 Tomcat 7 上 JSF 2.2 中的角色层次结构