升级到GlassFish 4和JSF 2.2 Primefaces后,FileUploadEvent停止工作。使用JSF 2.1,它没有问题。除文件上传外,一切正常。有什么东西我不见了吗?
GlassFish 4
JSF 2.2
PrimeFaces 3.4.2 and 3.5
Commons io version: 2.4
Commons fileupload version: 1.3
控制器端
public void handleFileUpload(FileUploadEvent event) {
System.out.println("HandleFileUpload");
byte[] file = event.getFile().getContents();
newFieldset.setData(file);
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
查看
<h:form enctype="multipart/form-data">
<p:fieldset legend="Create new feed" toggleable="true" collapsed="true" >
<p:fileUpload fileUploadListener="#{adminHomeController.handleFileUpload}" style="margin-top: 20px;"
mode="advanced"
update="messages"
sizeLimit="1000000"
multiple="false"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
<p:inputText label="Baslik" style="margin-top: 20px;" required="true" value="#{adminHomeController.newFieldset.legend}" />
<p:editor style="margin-top: 20px;"
value="#{adminHomeController.newFieldset.content}" />
<p:commandButton style="margin-top: 20px;" value="#{msg['common.save']}" update="messages" icon="ui-icon-disk" actionListener="#{adminHomeController.saveFieldset()}"/>
</p:fieldset>
<p:growl id="messages" showDetail="true"/>
</h:form>
答案 0 :(得分:6)
我终于弄清楚了。 Commons-fileuploads方法parseRequest(httpServletRequest)
尝试读取请求的inputStream。由于容器已经读取它,它是空的。那么解决这个问题可以做些什么呢?答案比我原先想象的要复杂一点。首先,您需要自己的FileUploadFilter,如下所示:
public class FileUploadFilter implements Filter
{
private final static Logger LOGGER = LoggerFactory.getLogger(FileUploadFilter.class);
/*
* (non-Javadoc)
*
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
/*
* (non-Javadoc)
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
{
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
boolean isMultipart = (httpServletRequest.getContentType() == null) ? false : httpServletRequest.getContentType().toLowerCase().startsWith("multipart/");
if (isMultipart)
{
MultipartRequest multipartRequest = new MultipartRequest(httpServletRequest);
LOGGER.info("File upload request parsed succesfully, continuing with filter chain with a wrapped multipart request");
filterChain.doFilter(multipartRequest, response);
}
else
{
filterChain.doFilter(request, response);
}
}
/*
* (non-Javadoc)
*
* @see javax.servlet.Filter#destroy()
*/
@Override
public void destroy()
{
LOGGER.info("Destroying UploadFilter");
}
下一步:在web.xml中注册此过滤器,然后删除/替换Primefaces过滤器。这应该是这样的:
<filter>
<filter-name>FileUpload Filter</filter-name>
<filter-class><YourPackage>.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
不幸的是,不是吗。您将需要自己的MultipartRequest,因为您必须自己组装FileItems列表。但是停止。我们必须使用与FileItem不兼容的javax.servlet.Part类。所以我写了一个新的课程来连接这两个。您可以在此处找到此课程:http://pastebin.com/JcfAYjey
最后一个难题是提到的MultipartRequest,它链接了PartItem和FileUploadFilter。我从Primefaces-Repository中取出了这个类,并根据需要对其进行了更改(参见http://pastebin.com/Vc5h2rmJ)。第47和57行之间存在差异。
那么你需要做什么: 1.创建三个类FileUploadFilter,MultipartRequest和PartItem 2.在web.xml中注册FileUploadFilter 3.享受!
请注意:这不是一个解决所有问题的解决方案,而只是您可能在进一步实施中采取的方向。例如,MultipartRequest仅适用于内容类型为image/*
的部分。您可能需要更改此内容。
随意更改代码;)希望它有所帮助!
编辑:我忘了提到一个重要的步骤。您还需要自己的FileIUploadRenderer。实现的一个Primefaces使用instanceof
检查来查找MultipartRequest。由于您现在使用的是另一个,因此必须更改导入。课程的其余部分可以保持不变(http://pastebin.com/rDUkPqf6)。不要忘记在faces-config.xml中注册它:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.FileUploadRenderer</renderer-type>
<renderer-class><YourPackage>.FileUploadRenderer</renderer-class>
</renderer>
</render-kit>
答案 1 :(得分:4)
答案在于 UploadFile getInputstream()方法。不要依赖 getContents()方法。 这是我的简单解决方案,它与glassfish 4中的以下依赖关系一起使用
commons-fileupload 1.3
private byte[] getFileContents(InputStream in) {
byte[] bytes = null;
try {
// write the inputStream to a FileOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
bos.write(bytes, 0, read);
}
bytes = bos.toByteArray();
in.close();
in = null;
bos.flush();
bos.close();
bos = null;
logger.debug("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
return bytes;
}
getFileContents(getFile().getInputstream());
答案 2 :(得分:3)
尝试删除beans.xml
(CDI配置文件)并使用JSF bean。
答案 3 :(得分:2)
我在PrimeFaces博客上看到,完整的JSF 2.2支持将从版本4.0开始。
答案 4 :(得分:1)
答案 5 :(得分:1)
我认为这是一个公共文件上传问题。当我通过代码调试时,PrimeFaces的UploadFilter正确触发了commons-fileupload的FileUploadBase.parseRequest方法(当我使用GlassFish 3.1.22或GlassFish 4时相同的流程),但对FileItemIterator.hasNext的检查返回false。