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?

30
demandé sur BalusC 2012-04-09 17:26:36

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:

52
répondu BalusC 2017-05-23 12:02:27

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

3
répondu Ilya Sidorovich 2012-04-17 14:10:03

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.

3
répondu imdzeeshan 2015-09-02 13:00:49

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

1
répondu maple_shaft 2017-05-23 11:54:33
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" />
0
répondu Serdari 2014-02-19 09:15:22

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).

-2
répondu IturPablo 2012-04-14 18:53:54