Glassfish 4,JSF 2.2和PrimeFaces FileUploadEvent无法协同工作

Pin*_*chy 6 file-upload primefaces jsf-2.2 glassfish-4

升级到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
Run Code Online (Sandbox Code Playgroud)

控制器端

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);
}
Run Code Online (Sandbox Code Playgroud)

视图

<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>
Run Code Online (Sandbox Code Playgroud)

Kai*_*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");
}
Run Code Online (Sandbox Code Playgroud)

下一步:在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>
Run Code Online (Sandbox Code Playgroud)

不幸的是,不是吗.您将需要自己的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仅适用于具有content-type的部分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>
Run Code Online (Sandbox Code Playgroud)