How to use <p:graphicImage> with DefaultStreamedContent in an ui:repeat?
Solution 1:
It is not possible to use <p:graphicImage>
this way. You should rather iterate over a collection of unique image identifiers, not over a collection of StreamedContent
. Those unique image identifiers have then to be passed as a <f:param>
to <p:graphicImage>
which in turn will generate the right URLs for the browser.
<ui:repeat value="#{data.imageIds}" var="imageId">
<p:graphicImage value="#{imageStreamer.image}">
<f:param name="id" value="#{imageId}" />
</p:graphicImage>
</ui:repeat>
Your #{data}
managed bean must just have a:
private List<Long> imageIds; // +getter
The #{imageStreamer}
should be a separate application scoped managed bean which look basically like this:
@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 view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Get ID value from actual request param.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}