JBoss 7.1.1でPrimeFaces 3.2を使用しています。
<ui:repeat>
のMySQLデータベースのBLOBに保存されている画像を表示しようとしています。画像はbyte[]
に保存され、次のようにStreamedContent
に変換されます。
InputStream stream = new ByteArrayInputStream(ingredient.getImage());
ingredient.setJsfImage(new DefaultStreamedContent(stream, "image/jpg"));
次に、次のようにFaceletに表示しようとしています:
<ui:repeat var="ingredient" value="#{formBean.ingredientResultSet}">
<p:panel id="resultsPanel" header="#{ingredient.location.shopName}">
<p:graphicImage value="#{ingredient.jsfImage}" alt="No picture set" />
...
ただし、ページをロードすると、JBossで次のエラーが表示されます。
SEVERE [org.primefaces.application.PrimeResourceHandler](http--127.0.0.1-8080-12)動的リソースのストリーミング中にエラーが発生しました。
これはどのように引き起こされ、どうすれば解決できますか?
<p:graphicImage>
は実際に<img src>
要素をURLのみでレンダリングし、取得したHTMLマークアップを解析して結果を表示しようとするときにWebブラウザーによって後で個別に呼び出されることを認識する必要があります。
したがって、<p:graphicImage>
のgetterメソッドで何をするにしても、リクエストごとに呼び出せるように設計する必要があります。そのため、最も健全なアプローチは、<p:graphicImage>
が<f:param>
で<p:graphicImage value>
を作成することです。ここで、<f:param value>
は完全にスタンドアロンの要求またはアプリケーションスコープBeanを指し、識別子。
例えば。
<p:graphicImage value="#{images.image}">
<f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>
Images
バッキングBeanは次のようになります。
@ManagedBean
@ApplicationScoped
public class Images {
@EJB
private ImageService service;
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Return a real StreamedContent with the image bytes.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}
または、既に OmniFaces 2.0以降 を使用している場合は、代わりに <o:graphicImage>
を使用することを検討してください。期待される。この件に関する ブログ も参照してください。
おかげでBalusC。これを行うには、バッキングBeanで整数を定義し、イメージのByteArrayを更新しながら、それに異なる値を割り当てます。この整数は、画像の一意の識別子として機能します。次に、この整数をページ上の<f:param>
内の<p:graphicImage>
の値として設定します。
画像タグは次のようになります
<p:graphicImage value="#{empBean.image}">
<f:param name="id" value="#{empBean.imageId}" />
</p:graphicImage>`
そして、バッキングBeanのイメージを次のように設定します。
if(user.getPicture()!=null){
imageId = (int) new Date().getTime();
BinaryStreamImpl bs = new BinaryStreamImpl(user.getPicture());
//picture is byte[] property in user class
this.image = new DefaultStreamedContent(bs.getInputStream(), "image/png");
}
現在は正常に動作しています。
なぜこれが必要なのかわかりません。マッピング「/images/yourimage.jpg」でデータベースから画像を取得するサーブレットを作成するだけです。
これを行う方法に関する対応するコードを含むクイックチュートリアルを次に示します。
graphicImage
コンポーネントがページ上でレンダリングするものに留意する必要があります。 HTMLにレンダリングします<img>
要素。ブラウザでは、JSFページに対してリクエストが行われ、その後、ページ上の各画像に対しても後続のリクエストが発生します。
これらのイメージは、FacesServletではなくPrimeFacesリソースサーブレットから取得されます。つまり、マネージドBeanとそのプロパティのスコープはおそらく適用されません。
最初にBLOBをバイト配列にロードしてみてください。これでおそらく動作し始めます。
EDIT:この同様の質問に対する私の答えをご覧ください。 Primefacesのストリーミングコンテンツをレンダリングしないグラフィックイメージ
InputStream is = new ByteArrayInputStream((byte[]) yourBlobData);
myImage = new DefaultStreamedContent(is, "image/png");
jsfページ。
<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />