Afficher les images de blob de la base de données à l'intérieur
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 un StreamedContent
comme suit:
InputStream stream = new ByteArrayInputStream(ingredient.getImage());
ingredient.setJsfImage(new DefaultStreamedContent(stream, "image/jpg"));
alors j'essaie 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, j'obtiens l'erreur suivante dans JBoss:
SEVERE [org.primefaces.application.PrimeResourceHandler] (http--127.0.0.1-8080-12 Erreur dans le flux de ressources dynamiques.
comment cela est-il causé et comment puis-je le résoudre?
6 réponses
vous devez vous rendre compte que le <p:graphicImage>
rend en fait un <img src>
élément avec juste une URL qui est ensuite invoquée individuellement plus tard par le webbrowser quand il est sur le point de parser le markup HTML obtenu et de présenter les résultats.
donc, quoi que vous fassiez dans la méthode getter de <p:graphicImage>
, elle doit être conçue de façon à pouvoir être invoquée sur une base de demande. Ainsi, l'approche la plus saine serait de créer un <p:graphicImage>
avec un <f:param>
où le <p:graphicImage value>
pointe une requête ou une application entièrement autonome et le <f:param value>
pointe l'identificateur d'image unique.
E. G.
<p:graphicImage value="#{images.image}">
<f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>
où le 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 , alors envisager d'utiliser son <o:graphicImage>
à la place qui peut être utilisé plus intuitivement, presque de la façon dont vous vous attendiez. Voir aussi le blog sur le sujet.
voir aussi:
Je ne comprends pas pourquoi vous avez besoin de ça. Vous pouvez simplement créer un servlet qui obtiendra l'image de la base de données avec un mapping "/images/yourimage.jpg".
Voici un tutoriel rapide avec un code correspondant dans sur comment faire cela.
JSF - l'Affichage des images à partir de la base de données de l'ACI
Merci BalusC. J'ai fait cette chose en définissant un entier dans la fève de soutien et en lui assignant une valeur diffente tout en mettant à jour le ByteArray pour l'image. Cet entier sert d'identificateur unique pour l'image. Puis j'ai placé cet entier comme valeur de <f:param>
dans <p:graphicImage>
sur la page.
balise image ressembler à
<p:graphicImage value="#{empBean.image}">
<f:param name="id" value="#{empBean.imageId}" />
</p:graphicImage>`
et le réglage de l'image dans la fève de soutien 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");
}
ça marche maintenant.
vous devez garder à l'esprit ce que le composant graphicImage
rend sur la page. Il renvoie à L'élément HTML <img>
. Dans le navigateur, la demande sera faite pour la page JSF, puis des demandes subséquentes se produiront pour chacune des images de la page.
ces images proviennent de PrimeFaces resource servlet et non de FacesServlet, ce qui signifie que la portée de la fève gérée et ses propriétés ne sont probablement pas applicables.
essayez de charger le blob dans un tableau d'octets d'abord puis le Ceci commencera probablement à fonctionner.
EDIT: Voir ma réponse suivante à cette question semblable. graphicimage not rendering streamedcontenu in Primefaces
InputStream is = new ByteArrayInputStream((byte[]) yourBlobData);
myImage = new DefaultStreamedContent(is, "image/png");
dans la page jsf;
<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />
mmm j'sûr à 99% que <p:graphicImage
ne fonctionne pas avec l'interface utilisateur:répétez-vous ll ont beaucoup de problèmes avec cette (Parce que j'ai fait XD), je vous recommande de créer une servlet et de servir les images comme un inputstream (il y a beaucoup d'exemples).