2013-06-20 59 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

相關問題