我正在开发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"one_answers"JSF 2.2",所以我知道正在访问backingbean,并且正在使用JSF 2.2,但当我单击"上传"时,Java从未被调用,WebSphere日志中也没有任何条目;页面刚刚刷新。当我查看(从浏览器端)发送的HTTP数据包时,我看到POST请求中发送的文件,然后我得到了200 OK的响应。
有什么想法吗?
经过几天的调试和尝试替代方案,我们发现问题在于WebSphere 8.5.5要求任何试图读取多部分数据的servlet将多部分配置元素添加到web.xml文件中的定义中,或者使用@MultipartConfig注释。JSF 2.2 servlet似乎没有正确实现这一点,因为一旦我们将多部分配置元素添加到web.xml文件中,WebSphere上的一切都很好。
我不太清楚为什么我们的代码最初在Tomcat上工作,但在Websphere中却没有;我怀疑要么是我们使用的JSF 2.2构建有缺陷,要么是Tomcat稍微宽容一点,不需要我们那么明确。
Primefaces使用两个文件上传解码器上传p:fileupload 的内容
1-NativeFileUploadDecoder
2-CommonsFileUploadDecoder
NativeFileUploadDecoder是默认的上传解码器,它需要servlet容器3.0,所以如果servlet容器小于3,那么它将无法使用。此外,一些应用程序服务器对使用多部分内容进行了限制
因此,如果您因任何原因对本地上传解码器有问题,您必须使用另一个解码器,即"CommonsFileUploadDecoder"
CommonsFileUploadDecoder依赖于Apache公共库,因此您必须将commons fileupload和commons io jar放在类路径中版本取决于您的Primefifaces版本,但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>