4

blob画像を列に保存するMySQLデータベースがあります。それらを PrimeFaces で表示したいと思います<p:dataTable>。どうすればこれを達成できますか?

4

2 に答える 2

12

ソース (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 とやり取りしていると想定しています)。@Lobbytes

@Entity
public class Image {

    @Id
    @GeneratedValue(strategy = IDENTITY) // Depending on your DB, of course.
    private Long id;

    @Lob
    private byte[] bytes;

    // ...
}

ImageService単なる標準の@StatelessEJB であり、ここで確認する特別なことは何もありません。

@Stateless
public class ImageService {

    @PersistenceContext
    private EntityManager em;

    public Image find(Long id) {
        return em.find(Image.class, id);
    }

}

以下も参照してください。

于 2013-06-05T13:13:27.300 に答える
-1

Richfaces を使用している場合は、a4j:mediaOutputコンポーネントを使用して、Bean から BLOB をストリーミングできます。

そうでない場合は、残念ながら私は Primefaces に慣れていません。そのためのコンポーネントが提供されていない場合は、blob を返すサーブレットを指す URL を生成する方法が必要です。そうすればh:graphicImage、その自動生成された URL で使用できます。

于 2013-06-05T08:28:57.277 に答える