J'utilise PrimeFaces 3.2 sur JBoss 7.1.1.
J'essaie d'afficher une image qui est stockée dans un BLOB dans une base de données MySQL dans <ui:repeat>
. L'image est stockée dans un byte[]
puis convertie en une StreamedContent
comme suit:
InputStream stream = new ByteArrayInputStream(ingredient.getImage());
ingredient.setJsfImage(new DefaultStreamedContent(stream, "image/jpg"));
Ensuite, j'essaye de l'afficher dans un Facelet comme suit:
<ui:repeat var="ingredient" value="#{formBean.ingredientResultSet}">
<p:panel id="resultsPanel" header="#{ingredient.location.shopName}">
<p:graphicImage value="#{ingredient.jsfImage}" alt="No picture set" />
...
Cependant, lors du chargement de la page, l'erreur suivante apparaît dans JBoss:
SEVERE [org.primefaces.application.PrimeResourceHandler] (http - 127.0.0.1-8080-12) Erreur lors de la diffusion d'une ressource dynamique.
Comment cela est-il causé et comment puis-je le résoudre?
Vous devez comprendre que le <p:graphicImage>
restitue un élément <img src>
avec juste une URL, qui est ensuite invoquée individuellement par le navigateur Web lorsqu'il est sur le point d'analyser le balisage HTML obtenu et de présenter les résultats.
Ainsi, quoi que vous fassiez dans la méthode getter de <p:graphicImage>
, elle doit être conçue de manière à pouvoir être invoquée à la demande. Ainsi, la solution la plus rationnelle serait de créer un <p:graphicImage>
avec un <f:param>
dans lequel le <p:graphicImage value>
pointe un bean complet d'application ou une application entièrement autonome et le <f:param value>
pointe l'identificateur d'image unique.
Par exemple.
<p:graphicImage value="#{images.image}">
<f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>
Où le haricot de sauvegarde Images
peut ressembler à ceci:
@ManagedBean
@ApplicationScoped
public class Images {
@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. Return a real StreamedContent with the image bytes.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}
Ou, si vous utilisez déjà OmniFaces 2.0 ou plus récent , envisagez d’utiliser son <o:graphicImage>
qui peut être utilisé de manière plus intuitive, presque exactement comme vous le souhaitiez. Voir aussi le blog sur le sujet.
Merci BalusC. J'ai fait cela en définissant un entier dans le bean de sauvegarde et en lui attribuant une valeur différente lors de la mise à jour de ByteArray pour image. Cet entier sert d'identifiant unique pour l'image. Ensuite, je règle cet entier comme valeur de <f:param>
dans <p:graphicImage>
à la page.
étiquette d'image ressemble à
<p:graphicImage value="#{empBean.image}">
<f:param name="id" value="#{empBean.imageId}" />
</p:graphicImage>`
et en définissant l'image dans le haricot de support comme
if(user.getPicture()!=null){
imageId = (int) new Date().getTime();
BinaryStreamImpl bs = new BinaryStreamImpl(user.getPicture());
//picture is byte[] property in user class
this.image = new DefaultStreamedContent(bs.getInputStream(), "image/png");
}
Cela fonctionne bien maintenant.
Je ne comprends pas pourquoi avez-vous besoin de cela. Vous pouvez simplement créer un servlet qui obtiendra l'image de la base de données avec un mappage "/images/yourimage.jpg".
Voici un tutoriel rapide avec un code correspondant sur la façon de le faire.
JSF - Affichage d'images de la base de données au format JSF
Vous devez garder à l'esprit ce que le composant graphicImage
rend sur la page. Il rend à l'élément HTML <img>
. Dans le navigateur, la demande sera faite pour la page JSF, puis les demandes suivantes apparaîtront également pour chacune des images de la page.
Ces images proviennent du servlet de ressources PrimeFaces et non de FacesServlet, ce qui signifie que la portée du bean géré et ses propriétés ne sont probablement pas applicables.
Essayez de charger le blob dans un tableau d'octets en premier, puis ceci commencera probablement à fonctionner.
EDIT: Voir la réponse suivante à cette question similaire. graphicimage ne rendant pas le contenu streamé dans Primefaces
InputStream is = new ByteArrayInputStream((byte[]) yourBlobData);
myImage = new DefaultStreamedContent(is, "image/png");
en page jsf;
<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />