PrimeFaces GraphicImage と StreamedContent を使う時のメモ
ユーザーガイドに載ってる内容も込みで。
- StreamedContent に ViewScoped は使えない。
- RequestScoped にした場合、リクエストが2回来るから f:param で識別子を渡して getter で StreamedContent を生成し返すこと。
html 的には、<img src="..." > になるので commandButton等 の actionListener で StreamedContent を生成しても、<img src="..."> で画像を取りに行くリクエストではインスタンスが存在しない。
GraphicImage で使う場合は、field に StreamdContent を持つより、単に getter だけ用意した方が良さげな気がする。
画面的に ViewScoped を使いたい場合は、BackingBean を分ける事で実現可能。
コード例は Xtend で。
import java.io.File import java.io.Serializable import java.nio.file.Files import java.nio.file.StandardOpenOption import javax.enterprise.context.RequestScoped import javax.inject.Named import org.primefaces.model.DefaultStreamedContent import org.primefaces.model.StreamedContent import javax.faces.context.FacesContext import javax.faces.view.ViewScoped @ViewScoped @Named class BackingBean implements Serializable { @Property String fileNm def void submit() {} } @RequestScoped @Named class ImageBackingBean { def StreamedContent getImage() { val param = FacesContext.currentInstance .externalContext.requestParameterMap.get("name") val fileNm = if (param.nullOrEmpty) "default.png" else param new DefaultStreamedContent( Files.newInputStream( Paths.get("c:/work/image", fileNm), StandardOpenOption.READ)) } }
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>テスト</title> </h:head> <h:body> <h:form id="form"> <p:inputText value="#{backingBean.fileNm}"/> <p:graphicImage value="#{imageBackingBean.image}" > <f:param name="name" value="#{backingBean.fileNm}"/> </p:graphicImage> <p:commandButton actionListener="#{backingBean.submit}" value="サブミット" ajax="false"/> </h:form> </h:body> </html>