【问题标题】:JSF File Upload in WebSphere 8.5WebSphere 8.5 中的 JSF 文件上传
【发布时间】:2014-04-21 19:37:32
【问题描述】:

我正在开发一个 JSF 2.2 应用程序,我们需要通过网页上传一些 .csv 文件。当我们部署到 Tomcat 时它运行良好,但由于某种原因它不适用于 WebSphere。以下是我正在尝试使用的示例:

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<ui:composition template="/WEB-INF/templates/template.xhtml">
    <ui:define name="header">
        Header
    </ui:define>
    <ui:define name="content">
        <h:messages></h:messages>
        <h:form enctype="multipart/form-data">
            <h:inputFile id="file" value="#{fileUploadManagedBean.file}">
            </h:inputFile>
            <h:commandButton value="Upload"
                action="#{fileUploadManagedBean.upload()}" />
        </h:form>
        <h:outputLabel>JSF Implementation: #{fileUploadManagedBean.jsfImplementation}</h:outputLabel>
        <br />
        <h:outputLabel>JSF Version: #{fileUploadManagedBean.jsfVersion}</h:outputLabel>
    </ui:define>
    <ui:define name="footer">
        Footer
    </ui:define>
</ui:composition>
</html>

这是我的支持 bean,FileUploadManagedBean.java

package com.mycomp.test;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.Part;

import org.apache.log4j.Logger;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
    public static Logger logger = Logger.getLogger(FileUploadManagedBean.class);
    private Part file;                      // The file being uploaded

    public String upload() {
        logger.info("Initiating bulk upload...");      
        logger.debug("content-type: "+ file.getContentType());
        logger.debug("filename: "+ file.getName());
        logger.debug("size: "+ file.getSize());

        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Uploaded", "Uploaded"));

        return null;
    }
    public Part getFile() {
        return file;
    }
    public void setFile(Part file) {
        this.file = file;
    }


    public String getJsfImplementation() {
        return  FacesContext.class.getPackage().getImplementationTitle();
    }
    public String getJsfVersion() {
        return  FacesContext.class.getPackage().getImplementationVersion();
    }
}

当我打开页面时,它会打印出“Mojarra”和“JSF 2.2”,所以我知道正在访问支持 bean 并且正在使用 JSF 2.2,但是当我单击“上传”时,Java 是从未调用过且 WebSphere 日志中没有条目;页面刚刚刷新。当我查看(从浏览器端)发送的 HTTP 数据包时,我看到在 POST 请求中发送的文件,然后我得到 200 OK 响应。

有什么想法吗?

【问题讨论】:

    标签: jsf file-upload websphere jsf-2.2 servlet-3.0


    【解决方案1】:

    经过几天的调试和尝试替代方案,我们发现问题在于 WebSphere 8.5.5 要求任何尝试读取多部分数据的 servlet 要么将 multipart-config 元素添加到其在 web.xml 文件中的定义中,要么使用 @MultipartConfig 注释。 JSF 2.2 servlet 似乎没有正确实现这一点,因为一旦我们将 multipart-config 元素添加到我们的 web.xml 文件中,WebSphere 上的一切都运行良好。

    我不确定为什么我们的代码最初在 Tomcat 上运行,但在 Websphere 中却不行;我怀疑要么是我们使用的 JSF 2.2 版本有问题,要么是 Tomcat 稍微宽容一点,不需要我们这么明确。

    【讨论】:

    【解决方案2】:

    Primefaces 使用两个文件上传解码器来上传 p:fileupload 的内容

    1- NativeFileUploadDecoder

    2- CommonsFileUploadDecoder

    NativeFileUploadDecoder 是默认的上传解码器,它需要 servlet 容器 3.0,因此如果您的 servlet 容器小于 3,那么它将无法与您一起使用。还有一些应用服务器限制使用多部分内容

    因此,如果您因任何原因对本机上传解码器有问题,您必须使用另一个解码器,即“CommonsFileUploadDecoder”

    CommonsFileUploadDecoder 依赖于 Apache 公共库,因此您必须将 commons-fileupload 和 commons-io jar 放入您的类路径版本取决于您的 primefaces 版本,但 1.3 和 2.2 分别适用于我.

    要使用 CommonsFileUploadDecoder,您必须使用过滤器

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    

    仅等待过滤器将不起作用,因为在过滤器内部,它会检查上传器是否未提供,并且它至少检测到 JSF 2.2,因此它将绕过对默认解码器“Native”的请求然后它对你也不起作用

    要强制过滤器使用通用解码器,您必须在 web.xml 中放入以下上下文参数

    <context-param>
    <param-name>primefaces.UPLOADER</param-name>
       <param-value>commons</param-value>
    </context-param>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-23
      • 2015-03-17
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多