如何让JSF使用Apache Commons FileUpload上传文件

时间:2012-02-07 04:01:45

标签: jsf file-upload jsf-2 apache-commons-fileupload

我知道如何使用Primefaces或使用Tomahawk进行文件上传,但是,我正在尝试使用Apache Commons FileUpload进行文件上传,到目前为止我遇到了一些障碍。即使我的表单使用multipart/form-data,当我提交表单时,内容类型也会变为application/x-www-form-urlencoded。这是我的代码

<h:body>
    <h:form enctype="multipart/form-data">
        Upload File
        <input type="file" name="file"/>
        <p:commandButton value="Submit" action="#{viewBean.submit}"/>
    </h:form>
</h:body>

这是我的ViewBean

@ManagedBean
@ViewScoped
public class ViewBean implements Serializable {
    public void submit() {
        String url = "/FileUploadServlet";
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            String contentType = context.getExternalContext().getRequestContentType();
            context.getExternalContext().dispatch(url);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Exception when calling Servlet", e);
        } finally {
            context.responseComplete();
        }
    }
}

因此,当我尝试打印上面的内容类型时,它显示application/x-www-form-urlencoded。如果我将ajax="false"添加到p:commandButton,那么甚至不会调用submit()方法,但如果我取出enctype="multipart/form-data"(仍然保留ajax="false"),那么submit()被调用但它不是多部分,它是application/x-www-form-urlencoded,所以apache commons fileupload抛出异常,因为它不是多部分。似乎无论我做什么,我似乎无法获得多部分要求。请帮忙

1 个答案:

答案 0 :(得分:12)

  

因此,当我尝试打印上面的内容类型时,它显示了application / x-www-form-urlencoded。

<p:commandButton>默认发送级别为1 {1}的ajax请求。这样做支持XMLHttpRequest。只有level 2 XMLHttpRequest支持它,但它只支持最新的浏览器(那些也支持HTML5),而不是在JSF JS API和PrimeFaces JS API中实现。


  

如果我把ajax =“false”放到我的p:commandButton中,那么甚至不会调用submit()方法

但是这样会发送一个值得信赖的multipart/form-data 。不调用submit方法只是因为2.2版之前的JSF不支持multipart/form-data个请求。默认情况下,JSF使用基础HTTP servlet请求上的multipart/form-datarequest.getParameter()来收集提交的数据。但是,当使用getParameterMap()以外的编码时,这将返回null。由于JSF根据提交的数据确定要调用的操作方法,因此当数据为application/x-www-form-urlencoded时,它将无法找到并调用它。

理论上,如果您创建null使用Apache Commons FileUpload或新的Servlet 3.0 request.getPart() / getParts()方法从Filter请求中提取数据,使用自定义实现包装当前的HTTP servlet请求,该实现覆盖multipart/form-data调用,其中提供了提取数据的映射,然后JSF将能够根据getParameter()调用的结果执行所需的工作。您可以在this article中找到一个使用Servlet 3.0 API的具体示例,以及稍微更改的相同示例,以便在this answer中使用Apache Commons FileUpload。

即将推出的JSF 2.2将有一个新的getParameter()组件,该组件可绑定到Servlet 3.0 Part属性。

<h:inputFile>

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

JSF 2.2最终版本计划在第一季度末发布,但目前可作为快照发布。