6

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>
4

6 に答える 6

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>

残念ながらそうではありません。FileItems のリストを自分で組み立てる必要があるため、独自の MultipartRequest が必要になります。しかし、停止します。FileItem と互換性のない javax.servlet.Part クラスを使用する必要があります。そこで、これら 2 つを橋渡しする新しいクラスを作成しました。このクラスはここにあります: http://pastebin.com/JcfAYjey

パズルの最後のピースは、PartItem と FileUploadFilter をリンクする前述の MultipartRequest です。このクラスを Primefaces-Repository から取得し、必要に応じて変更しました ( http://pastebin.com/Vc5h2rmJを参照)。違いは47行目と57行目です。

1. FileUploadFilter、MultipartRequest、PartItem の 3 つのクラスを作成します。 2. FileUploadFilter を web.xml に登録します。

注意してください: これは、すべての問題を解決するソリューションではなく、今後の実装での方向性を示すものです。たとえば、MultipartRequest は、 content-type を持つパーツに対してのみ機能しますimage/*。これを変更する必要がある場合があります。

お気軽にコードを変更してください ;) お役に立てば幸いです!

編集: 1 つの重要なステップについて言及するのを忘れていました。さらに、独自の 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>
于 2013-06-28T11:44:48.497 に答える
4

答えはUploadFile getInputstream()メソッドにあります。getContents()メソッドに依存しないでください。これは、glassfish 4 の以下の依存関係で機能する私の簡単なソリューションです

  • プライムフェイス 4.0.RC1
  • jsf2.2
  • 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()); 
    
于 2013-09-25T09:26:36.617 に答える
3

(CDI 構成ファイル)を削除してbeans.xml、JSF Bean を使用してみてください。

于 2013-06-21T11:54:02.153 に答える
2

PrimeFaces ブログで、バージョン 4.0 で JSF 2.2 が完全にサポートされることを見ました。

于 2013-09-13T08:33:51.790 に答える
1

commons-fileupload の問題だと思います。コードをデバッグすると、PrimeFaces の UploadFilter は commons-fileupload の FileUploadBase.parseRequest メソッドを正しくトリガーします (GlassFish 3.1.22 または GlassFish 4 を使用する場合と同様に流れます) が、FileItemIterator.hasNext のチェックは false を返します。

于 2013-06-23T15:54:03.057 に答える