blob
画像を列に保存するMySQLデータベースがあります。それらを PrimeFaces で表示したいと思います<p:dataTable>
。どうすればこれを達成できますか?
2 に答える
ソース (DB、ディスク ファイル システム、ネットワークなど)に関係なく、 に<p:graphicImage>
保存されているイメージを表示するために使用できます。最も簡単な例は次のとおりです。byte[]
byte[]
<p:graphicImage value="#{bean.streamedContent}" />
プロパティを参照しStreamedContent
ます。
ただし、これには落とし穴があります。特に、データ テーブルなどの反復コンポーネントで使用する場合は、getter メソッドが 2 回呼び出されます。1 回目は JSF 自体が URL を生成し<img src>
、2 回目は Web ブラウザが の URL に基づいて画像コンテンツをダウンロードする必要がある場合<img src>
です。効率的にするために、最初の getter 呼び出しで DB をヒットしないようにする必要があります。また、getter メソッド呼び出しをパラメータ化して、特定のイメージ ID を渡すジェネリック メソッドを使用できるようにするには、<f:param>
メソッド引数を渡す EL 2.2 機能がまったく機能しないことに注意してください。 !の URL になり<img src>
ます)。
要約すると、これは次のようにする必要があります。
<p:dataTable value="#{bean.items}" var="item">
<p:column>
<p:graphicImage value="#{imageStreamer.image}">
<f:param name="id" value="#{item.imageId}" />
</p:graphicImage>
</p:column>
</p:dataTable>
明らかに、コンテンツではなく、DB (主キー) 内の画像の#{item.imageId}
一意の識別子を返します。これは、次のようなアプリケーション スコープの Bean です。byte[]
#{imageStreamer}
@ManagedBean
@ApplicationScoped
public class ImageStreamer {
@EJB
private ImageService service;
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the HTML. 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 imageId = context.getExternalContext().getRequestParameterMap().get("imageId");
Image image = imageService.find(Long.valueOf(imageId));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}
このImage
特定の例では、クラスはonプロパティ@Entity
を持つだけです (JSF を使用しているため、もちろん JPA を使用して DB とやり取りしていると想定しています)。@Lob
bytes
@Entity
public class Image {
@Id
@GeneratedValue(strategy = IDENTITY) // Depending on your DB, of course.
private Long id;
@Lob
private byte[] bytes;
// ...
}
はImageService
単なる標準の@Stateless
EJB であり、ここで確認する特別なことは何もありません。
@Stateless
public class ImageService {
@PersistenceContext
private EntityManager em;
public Image find(Long id) {
return em.find(Image.class, id);
}
}
以下も参照してください。
Richfaces を使用している場合は、a4j:mediaOutputコンポーネントを使用して、Bean から BLOB をストリーミングできます。
そうでない場合は、残念ながら私は Primefaces に慣れていません。そのためのコンポーネントが提供されていない場合は、blob を返すサーブレットを指す URL を生成する方法が必要です。そうすればh:graphicImage
、その自動生成された URL で使用できます。