29

重要 :このスレッドで議論されている問題は、2014 年 10 月 6 日月曜日 (今からほんの数分前) にリリースされたPrimeFaces 5.1 final (コミュニティ リリース)の時点で修正されています。JSF 2.2.8-02 (またはapiimpl ) を試しました。

そのため、たまたまそのバージョン(またはそれ以上、言及する必要はありません)を使用した場合、この質問を読む必要さえありません。


Web アプリケーションを実行しています

  • グラスフィッシュ 4.0
  • モハラ 2.2.4
  • PrimeFaces 4.0 最終版

AJAX を使用したファイルのアップロードを除くすべてが正常に機能します。次の xhtml ファイルは、PrimeFaces コマンド ボタンによってトリガーされる AJAX 要求を介してマルチパート コンテンツを送信します。

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Test</title>
    </h:head>
    <h:body>
        <h:form prependId="true" enctype="multipart/form-data">
            <p:fileUpload id="txtCatImage"
                          value="#{testManagedBean.uploadedFile}"
                          mode="advanced"
                          dragDropSupport="true"
                          fileLimit="1"
                          sizeLimit="100000"
                          multiple="false"
                          allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
                          fileUploadListener="#{testManagedBean.fileUploadListener}"/>

            <p:message for="txtCatImage" showSummary="false"/>
            <p:commandButton id="btnSubmit" 
                             actionListener="#{testManagedBean.insert}" 
                             ajax="true" icon="ui-icon-check" value="Save"/>                
        </h:form>
    </h:body>
</html>

テストマネージドBean:

@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private UploadedFile uploadedFile;

    public TestManagedBean(){}

    public UploadedFile getUploadedFile() {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFile uploadedFile) {
        this.uploadedFile = uploadedFile;
    }

    public void fileUploadListener(FileUploadEvent event){
        uploadedFile=event.getFile();
    }

    public void insert(){
        if(uploadedFile!=null){
            System.out.println(uploadedFile.getFileName());
        }
        else{
            System.out.println("The file object is null.");
        }
    }
}

ファイルがファイル ブラウザーからアップロードされると、そのリスナーにファイル名が表示されます - fileUploadListener().

ファイルをアップロードした後、指定されたコマンド ボタンを押すと ( ajax="true")、次の例外がスローされます。

WARNING:   javax.servlet.ServletException: The request content-type is not a multipart/form-data
javax.faces.FacesException: javax.servlet.ServletException: The request content-type is not a multipart/form-data
    at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:44)
    at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:44)
    at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
    at javax.faces.component.UIInput.decode(UIInput.java:771)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
    at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
    at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
    at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929)
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:70)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at filter.NoCacheFilter.doFilter(NoCacheFilter.java:28)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.servlet.ServletException: The request content-type is not a multipart/form-data
    at org.apache.catalina.fileupload.Multipart.getPart(Multipart.java:187)
    at org.apache.catalina.connector.Request.getPart(Request.java:4535)
    at org.apache.catalina.connector.RequestFacade.getPart(RequestFacade.java:1095)
    at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:60)
    at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:37)
    ... 48 more

SEVERE:   javax.servlet.ServletException: The request content-type is not a multipart/form-data
    at org.apache.catalina.fileupload.Multipart.getPart(Multipart.java:187)
    at org.apache.catalina.connector.Request.getPart(Request.java:4535)
    at org.apache.catalina.connector.RequestFacade.getPart(RequestFacade.java:1095)
    at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:60)
    at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:37)
    at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:44)
    at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
    at javax.faces.component.UIInput.decode(UIInput.java:771)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
    at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
    at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
    at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929)
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:70)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at filter.NoCacheFilter.doFilter(NoCacheFilter.java:28)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:722)

コマンドボタンの ajax 属性が false - に設定されている場合にのみ機能しますajax="false"


Tomcat 7.0.35 で Mojarra バージョンを 2.1.9 にダウングレードしました。この Mojarra バージョンと PrimeFaces 4.0 final (および PrimeFaces 4.0 RC1 も) (AJAX 要求でアップロードされたファイル) で動作しました。

代わりに、次の Mojarra バージョンを試しました

  • 2.2.0
  • 2.2.1
  • 2.2.2
  • 2.2.3
  • 2.2.4

<p:rowEditor/>GlassFish 4.0 の場合、PrimeFaces DataTable を使用した行の編集 (たとえば、各行の画像と一緒に) は常に AJAX ベースであるため、非常に必要な AJAX 要求でファイルをアップロードすることに成功したものはありませんでした。

とにかくGlassFish 4.0を残したい。また、GlassFish 4.0 で Mojarra 2.1.9 をダウングレードしようとしましたが、例外で終わるバンドルを作成できませんでした。GlassFish 4.0 は、2.2.x より前の Mojarra では動作しないようです。

では、この例外の原因は何でしょうか? PrimeFaces と JSF のどちらでしょうか? ただ混乱した。この特定の環境で AJAX 要求を使用してファイルをアップロードするための回避策はありますか?


編集:

のフィルタ マッピングweb.xml:

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

この問題は、2014 年 1 月 8 日にリリースされた Mojarra バージョン2.2.5 (またはapiimpl )で解決されていません。


2014 年 3 月 4 日にリリースされた Mojarra バージョン2.2.6 (またはapiimpl )でもう一度試してみました。問題はそのままです。


2014 年 5 月 5 日にリリースされたPrimeFaces 5.0 finalではまだ動作しません。

4

5 に答える 5

52

カイが現在の質問に対する回答で正しく指摘したように、問題は、リクエストがリクエストであるかどうかをチェックしないことNativeFileUploadDecoderによって使用される asによって引き起こされます。これは、「通常の」ajax リクエストが送信されるフォームにコンポーネントが存在する場合に問題を引き起こします。は正しくチェックし、ネイティブ ファイル アップロード パーサーがまだない JSF 2.1 で正しく動作するのはそのためです。FileUploadRenderermultipart/form-dataCommonsFileUploadDecoder

カスタムレンダラーでこれを回避するという彼の解決策は正しい方向ですが、アプローチは非常に不器用です。この特定のケースでは、さらに数行を追加するためだけに、200 行を超えるクラス全体をコピーペーストする必要はまったくありません。代わりに、そのクラスを正確に拡張し、次のようにスーパーに委譲する前に if チェックでメソッドを正確にオーバーライドします。

package com.example;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.primefaces.component.fileupload.FileUploadRenderer;

public class MyFileUploadRenderer extends FileUploadRenderer {

    @Override
    public void decode(FacesContext context, UIComponent component) {
        if (context.getExternalContext().getRequestContentType().toLowerCase().startsWith("multipart/")) {
            super.decode(context, component);
        }
    }

}

それだけです(ただし、その<renderer-kit>エントリを保持しfaces-config.xmlてください)。リクエストがリクエストでない場合、デコードを続行しても意味がありませんmultipart。とにかく、ファイル部分は利用できません (またjavax.servlet.*、同じ機能が を介してすぐに利用できる場合、API にキャストバックする意味もありませんExternalContext)。

于 2013-11-03T10:54:20.840 に答える
9

これは古く、すでに回答されていますが、見逃した場合に備えて、何かを共有したかったのです: -servlet3 または commons)。これを使用して、次のように commons-uploader を強制できます。

<context-param>
   <param-name>primefaces.UPLOADER</param-name>
   <param-value>commons</param-value>
</context-param>

(もちろん、上記およびガイドで説明されているように、FileUploadFilter は引き続き必要です)。詳細については、PrimeFaces ユーザー ガイドを参照してください。

于 2014-02-14T15:45:16.607 に答える
2

@BalusC - 既存のものを拡張するためのあなたの提案FileUploadRendererは非常にきれいです。ありがとう!

使用している JSF のバージョンによっては、ランダムな iFrame ポップアップが表示される場合があります。これは、 JAVASERVERFACES-2843 に記載されているバグです。

これを修正する最初の試み (2.2.1 にアップグレードする必要なし) では、iFrame を CSS で非表示にしました。

#JSFFrameId {
  visibility:hidden;
}

これは機能しましたが、何らかの理由で追加の AJAX 送信が起動しませんでした。次に、小さなスクリプトを呼び出して iFrame を削除すると、問題が解決しました。

<h:commandButton id="btnSubmit" action="#{fileUploadController.upload}" value="Save" >
  <f:ajax execute="@all" render="frmMain" onevent="removeIFrame()" />
</h:commandButton> 

JavaScript:

function removeIFrame()
{
  document.getElementById("JSFFrameId").removeNode();
}
于 2014-03-28T02:01:47.733 に答える
0

私は同じ問題を抱えていました.私の場合、データテーブルでprimefacesファイルアップローダーを使用し、onRowEditを使用して既存の画像を変更しようとしましたが、上記と同じエラーが発生しました. 次に、primefaces jar を 5.1 バージョンに変更しました。今は正常に動作しています。

于 2015-05-17T07:45:16.500 に答える