2013-06-20 58 views
6

升级到GlassFish 4和JSF 2.2 Primefaces之后FileUploadEvent停止工作。有了JSF 2.1,它没有任何问题。除了文件上传之外,一切工作都正常。有什么我失踪了吗?Glassfish 4,JSF 2.2和PrimeFaces FileUploadEvent不能一起工作

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> 

回答

1
+1

我已经工作包括Commons io版本:2.4和Commons fileupload版本:1.3依赖关系,所以情况并非如此。在切换到JSF 2.2之前,文件上传机制正在工作,现在它根本没有触发监听器功能,也没有抛出异常。我认为这是行不通的。 – Pinchy

3

试图删除beans.xml(CDI配置文件),并使用JSF豆。

+0

谢谢,但不,我不想用我想与CDI合作的豆子。欢呼 – Pinchy

+0

升级到Primefaces 4.0可能会解决问题。 –

1

我认为这是一个commons-fileupload问题。当我通过代码进行调试时,PrimeFaces的UploadFilter会正确触发commons-fileupload的FileUploadBase.parseRequest方法(在使用GlassFish 3.1.22或GlassFish 4时同样流动),但是对FileItemIterator.hasNext的检查返回false。

+0

我通过代码调试,现在我能够确认你的想法。来自commons-fileupload的MultipartStream(第1003行)引发了一个异常,导致FileItemIterator.hasNext返回false。不幸的是,到目前为止我还无法解决这个问题......有没有其他人在这个问题上取得了一些进展? – Kai

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,因为您必须自己组装FileItem的列表。但停止。我们必须使用与FileItem不兼容的javax.servlet.Part类。所以我写了一个桥接这两个的新课程。你可以在这里找到这个类:http://pastebin.com/JcfAYjey

拼图的最后一部分是提到的连接PartItem和FileUploadFilter的MultipartRequest。我从Primefaces-Repository中选择了该课程并根据需要对其进行了更改(请参阅http://pastebin.com/Vc5h2rmJ)。所不同的是线47和57

那么你必须做之间: 1.创建三类FileUploadFilter,MultipartRequest和PartItem 2.注册FileUploadFilter在web.xml 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> 
2

我在PrimeFaces博客上看到,完整的JSF 2.2支持将从版本4.0开始。

4

答案在于上传文件getInputstream()方法。不要依赖getContents()方法。 这是我简单的解决方案,它与下面的依赖在GlassFish中4

  • Primefaces 4.0.RC1
  • JSF 2.2
  • 公地文件上传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()); 
    
+0

这对我来说是工作,从PF3.5到PF4.0,但为什么event.getFile()。getContent()返回null? – meyquel

相关问题