The param id is read by the streamer and use to fetch the entity that stores the byte[] data.
1.) In the JSF page, let us define a graphicImage component like this:
<p:graphicImage id="serviceImage" cache="false"
value="#{customImageStreamer.image}" height="150"
width="150">
<f:param name="id" value="#{myService.entity.id}"></f:param>
</p:graphicImage>
2.) Let us define a generic image streamer that we can extend.
public abstract class ImageStreamer<T extends BaseEntity> {
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.
Long id = Long.parseLong(context.getExternalContext().getRequestParameterMap().get("id"));
T obj = getPersistenceService().findById(id);
if (getImageArr(obj) != null) {
return new DefaultStreamedContent(new ByteArrayInputStream(getImageArr(obj)));
} else {
return new DefaultStreamedContent();
}
}
}
public StreamedContent getImage(T obj) throws IOException {
// So, browser is requesting the image. Return a real
// StreamedContent with the image bytes.
if (getImageArr(obj) != null) {
return new DefaultStreamedContent(new ByteArrayInputStream(getImageArr(obj)));
} else {
return new DefaultStreamedContent();
}
}
protected byte[] downloadUrl(URL toDownload) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
InputStream stream = null;
try {
byte[] chunk = new byte[4096];
int bytesRead;
stream = toDownload.openStream();
while ((bytesRead = stream.read(chunk)) > 0) {
outputStream.write(chunk, 0, bytesRead);
}
} catch (IOException e) {
return null;
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
return null;
}
}
}
return outputStream.toByteArray();
}
public abstract PersistenceServicegetPersistenceService();
public abstract byte[] getImageArr(T obj);
}
3.) The actual class implementation that streams the image. Note that it must be applicationScoped.
@Named
@ApplicationScoped
public class StudentImageStreamer extends ImageStreamer{
@Inject
private StudentService studentService;
@Override
public PersistenceServicegetPersistenceService() {
return studentService;
}
@Override
public byte[] getImageArr(Student obj) {
return obj.getImageAsByteArr();
}
}
If you have another class that needs streaming for primefaces graphic image, then just create another class that extends ImageStreamer.
References:
http://stackoverflow.com/questions/8207325/display-dynamic-image-from-database-with-pgraphicimage-and-streamedcontent
0 nhận xét:
Đăng nhận xét