File upload Glassfish 4、JSF 2.2和PrimeFaces FileUploadEvent不能一起工作

File upload Glassfish 4、JSF 2.2和PrimeFaces FileUploadEvent不能一起工作,file-upload,primefaces,jsf-2.2,glassfish-4,File Upload,Primefaces,Jsf 2.2,Glassfish 4,升级到GlassFish 4和JSF 2.2后,Primefaces FileUploadEvent停止工作。在JSF2.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

升级到GlassFish 4和JSF 2.2后,Primefaces FileUploadEvent停止工作。在JSF2.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);
}
看法



请参见尝试删除
beans.xml
(CDI配置文件)并使用JSFbean。

我认为这是一个公共文件上载问题。当我调试代码时,PrimeFaces的UploadFilter会正确触发commons fileupload的FileUploadBase.parseRequest方法(当我使用GlassFish 3.1.22或GlassFish 4时,流程相同),但对FileItemIterator.hasNext的检查返回false

我终于找到了答案。Commons fileuploads方法
parseRequest(httpServletRequest)
尝试读取请求的输入流。因为容器已经读取了它,所以它是空的。那么我们可以做些什么来解决这个问题呢?答案比我最初想象的要复杂一些。首先,您需要自己的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");
}
  <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>
下一步:在web.xml中注册此过滤器,并移除/替换Primefaces过滤器。这应该是这样的:

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");
}
  <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>

我在PrimeFaces博客上看到,从4.0版开始,JSF2.2将得到全面支持。

答案在于上传文件getInputstream()方法。不要依赖于getContents()方法。 这是我在glassfish 4中处理以下依赖项的简单解决方案

  • Primefaces 4.0.RC1
  • JSF2.2
  • commons文件上传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()); 
    

我已经包含了Commons io版本:2.4和Commons fileupload版本:1.3的依赖项,所以情况并非如此。在我切换到JSF2.2之前,文件上传机制是有效的,现在它根本没有启动侦听器函数,也没有引发异常。我假设它不会工作。谢谢,但不,我不想使用bean,我想使用CDI。我已经调试了代码,现在我可以确认你的想法了。commons fileupload中的MultipartStream(第1003行)引发异常,导致FileItemIterator.hasNext返回false。不幸的是,到目前为止我还不能解决这个问题。。。还有其他人在这个问题上取得了一些进展吗?这对我来说是可行的,从PF3.5到PF4.0,但为什么event.getFile().getContent()返回null??