WebSphere 8.5中的JSF文件上载

时间:2014-04-21 19:37:32

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

我正在开发一个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响应。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

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

我不确定为什么我们的代码最初在Tomcat上工作,但在Websphere中没有;我怀疑我们使用的JSF 2.2版本是否有问题,或者Tomcat只是稍微宽容一点,并不要求我们明确。

答案 1 :(得分:0)

Primefaces使用两个文件上传解码器上传p:fileupload

的内容

1- NativeFileUploadDecoder

2- CommonsFileUploadDecoder

NativeFileUploadDecoder是默认的上传解码器,它需要servlet容器3.0,所以如果你的servlet容器小于3,那么它将无法使用。一些应用程序服务器也限制使用多部分内容

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

CommonsFileUploadDecoder依赖于Apache公共lib,所以你必须把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>