構成およびトラブルシューティングの方法<p:fileUpload>
は、PrimeFacesのバージョンによって異なります。
PrimeFacesのすべてのバージョン
以下の要件は、すべてのPrimeFacesバージョンに適用されます。
のenctype
属性<h:form>
をに設定する必要がありますmultipart/form-data
。これがない場合、ajaxアップロードは機能する可能性がありますが、一般的なブラウザの動作は指定されておらず、フォームの構成とWebブラウザのmake / versionに依存しています。常に安全側に指定してください。
mode="advanced"
(つまりajaxアップロード、これがデフォルトです)を使用する場合<h:head>
は、(マスター)テンプレートにあることを確認してください。これにより、必要なJavaScriptファイルが適切に含まれるようになります。これはmode="simple"
(非Ajaxアップロード)には必要ありませんが、他のすべてのPrimeFacesコンポーネントのルックアンドフィールや機能を損なうため、とにかく見逃さないでください。
使用している場合mode="simple"
(すなわち、非AJAXアップロード)、その後、アヤックスはどのPrimeFacesで無効にされなければならないことでボタン/リンクを命じるajax="false"
、あなたが使用しなければならない<p:fileUpload value>
と<p:commandButton action>
の代わりに、<p:fileUpload fileUploadListener>
(のためのPrimeFaces <=の7.x)または<p:fileUpload listener>
(用PrimeFaces> = 8.x)の
したがって、ajaxサポート付きの(自動)ファイルアップロードが必要な場合(<h:head>
!に注意してください):
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{bean.upload}" auto="true" /> // for PrimeFaces >= 8.x this should be listener instead of fileUploadListener
</h:form>
public void upload(FileUploadEvent event) {
UploadedFile uploadedFile = event.getFile();
String fileName = uploadedFile.getFileName();
String contentType = uploadedFile.getContentType();
byte[] contents = uploadedFile.getContents(); // Or getInputStream()
// ... Save it, now!
}
または、非Ajaxファイルのアップロードが必要な場合:
<h:form enctype="multipart/form-data">
<p:fileUpload mode="simple" value="#{bean.uploadedFile}" />
<p:commandButton value="Upload" action="#{bean.upload}" ajax="false" />
</h:form>
private UploadedFile uploadedFile; // +getter+setter
public void upload() {
String fileName = uploadedFile.getFileName();
String contentType = uploadedFile.getContentType();
byte[] contents = uploadedFile.getContents(); // Or getInputStream()
// ... Save it, now!
}
以下のようなAJAX関連の属性というノートを行いauto
、allowTypes
、update
、onstart
、oncomplete
、などがされて無視さでmode="simple"
。したがって、そのような場合にそれらを指定する必要はありません。
また、後のHTTPリクエストによって呼び出された別のBeanメソッドではなく、上記のメソッド内でファイルの内容をすぐに読み取る必要があることに注意してください。これは、アップロードされたファイルのコンテンツがリクエストスコープであるため、後の/別のHTTPリクエストでは使用できないためです。後の要求でそれを読み取ろうとすると、おそらくjava.io.FileNotFoundException
一時ファイルで終了します。
PrimeFaces 8.x
設定は以下の5.xバージョン情報と同じですが、リスナーが呼び出されない場合は、listener
(8.xより前のバージョンのように)属性が呼び出されているかどうかを確認してくださいfileUploadListener
PrimeFaces 5.x
JSF 2.2を使用していて、faces-config.xml
JSF 2.2バージョンへの準拠も宣言されている場合は、追加の構成は必要ありません。PrimeFacesファイルアップロードフィルターはまったく必要ありません。使用するターゲットサーバーに応じてJSFを適切にインストールおよび構成する方法が不明な場合は、Mavenを介してJSFライブラリを適切にインストールおよび構成する方法に進んでください。そして私たちのJSFのwikiページのセクション「JSFのインストール」。
ただし、JSF 2.2をまだ使用しておらず、それをアップグレードできない場合(Servlet 3.0互換コンテナにすでにある場合は、簡単に行うことができます)、以下のPrimeFacesファイルアップロードフィルターを手動で登録する必要がありますweb.xml
(マルチを解析しますパーツリクエストを送信し、通常のリクエストパラメータマップに入力しFacesServlet
て、通常どおり作業を続行できるようにします。
<filter>
<filter-name>primeFacesFileUploadFilter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
</filter-mapping>
の<servlet-name>
値は、同じのエントリのfacesServlet
値と正確に一致する必要があります。したがって、たとえばの場合、それに合わせて編集する必要があります。<servlet>
javax.faces.webapp.FacesServlet
web.xml
Faces Servlet
PrimeFaces 4.x
PrimeFaces 5.xと同じストーリーが4.xにも適用されます。
によってアップロードされたファイルのコンテンツを取得する際に潜在的な問題のみがありますUploadedFile#getContents()
。これはnull
、Apache Commons FileUploadの代わりにネイティブAPIが使用されている場合に返されます。UploadedFile#getInputStream()
代わりに使用する必要があります。MySQLでp:fileUploadからアップロードした画像をBLOBとして挿入する方法もご覧ください。
ネイティブAPIのもう1つの潜在的な問題は、アップロードコンポーネントが、アップロードコンポーネントを処理しない別の「通常の」Ajaxリクエストが発生するフォームに存在する場合に現れます。「ファイルのアップロードがPrimeFaces 4.0 / JSF 2.2.xのAJAXで機能しない-javax.servlet.ServletException:リクエストコンテンツタイプがmultipart / form-dataではありません」も参照してください。
どちらの問題も、Apache Commons FileUploadに切り替えることで解決できます。詳細については、PrimeFaces 3.xのセクションを参照してください。
PrimeFaces 3.x
このバージョンは、JSF 2.2 /サーブレット3.0のネイティブファイルアップロードをサポートしていません。Apache Commons FileUploadを手動でインストールし、ファイルアップロードフィルターをに明示的に登録する必要がありますweb.xml
。
次のライブラリが必要です。
これらは、Webアプリケーションのランタイムクラスパスに存在する必要があります。Mavenを使用するときは、少なくともランタイムスコープであることを確認してください(デフォルトのコンパイルスコープも有効です)。JARを手動で持ち運ぶ場合は、JARが/WEB-INF/lib
フォルダーに入れられることを確認してください。
ファイルアップロードフィルターの登録の詳細は、上記のPrimeFaces 5.xセクションにあります。PrimeFaces 4+を使用していて、JSF 2.2 / Servlet 3.0ネイティブファイルアップロードの代わりにApache Commons FileUploadを明示的に使用したい場合は、上記のライブラリの横にある必要があり、以下のコンテキストパラメータもフィルタリングしますweb.xml
。
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
</context-param>
トラブルシューティング
それでも機能しない場合は、PrimeFacesの設定とは関係のない別の原因が考えられます。
あなただけがPrimeFacesのファイルアップロードフィルタを使用している場合:別のはありますFilter
あなたのWebアプリケーションで実行される前に、 PrimeFacesのファイルアップロードフィルタと、既に例えば、呼び出しによってリクエストボディを消費したgetParameter()
、getParameterMap()
、getReader()
エトセトラ、。リクエストボディは一度しか解析できません。ファイルアップロードフィルターが機能する前にこれらのメソッドの1つを呼び出すと、ファイルアップロードフィルターは空のリクエスト本文を取得します。
これを修正するに<filter-mapping>
は、ファイルアップロードフィルタのをの他のフィルタの前に置く必要がありますweb.xml
。リクエストがリクエストでない場合、multipart/form-data
ファイルアップロードフィルターは何も起こらなかったかのように続行します。注釈を使用するために自動的に追加されるフィルター(PrettyFacesなど)を使用する場合、web.xmlを介して明示的な順序を追加する必要がある場合があります。WARでアノテーションを使用して実行のサーブレットフィルターの順序を定義する方法を参照してください
PrimeFacesファイルアップロードフィルターを使用している場合のみ:Filter
Webアプリには、PrimeFacesファイルアップロードフィルターの前に実行され、RequestDispatcher#forward()
呼び出しを実行した別のものがあります。通常、PrettyFacesなどのURL書き換えフィルターがこれを行います。これによりFORWARD
ディスパッチャーがトリガーされますが、フィルターはデフォルトでREQUEST
ディスパッチャーのみをリッスンします。
これを修正するには、転送フィルターの前に PrimeFacesファイルアップロードフィルターを配置するか、FORWARD
ディスパッチャもリッスンするようにPrimeFacesファイルアップロードフィルターを再構成する必要があります。
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
ネストされたがあり<h:form>
ます。これはHTMLでは違法であり、ブラウザの動作は規定されていません。多くの場合、ブラウザは送信時に期待されるデータを送信しません。ネストしていないことを確認してください<h:form>
。これは完全にフォームのに関係ありませんenctype
。フォームをネストしないでください。
それでも問題が解決しない場合は、HTTPトラフィックをデバッグしてください。Webブラウザーの開発者ツールセットを開き(Chrome / Firebug23 + / IE9 +でF12を押します)、[ネット/ネットワーク]セクションを確認します。HTTP部分が正常に見える場合は、JSFコードをデバッグします。ブレークポイントを設定しFileUploadRenderer#decode()
、そこから進みます。
アップロードしたファイルを保存しています
ようやくそれが機能するようになったら、次の質問はおそらく「アップロードされたファイルをどのように/どこに保存すればよいですか?」のようになります。さて、ここに続きます:アップロードされたファイルをJSFに保存する方法。
web.xml
としては、PrimeFacesユーザーガイドに従ってPrimeFacesアップロードフィルターを登録しなかったことが考えられます。とにかくそれを読みましたか?しかし、それはなぜmode="simple"
あなたに役立つのかを説明しません。