Affichage dynamique de l'image à partir de la base de données ou de la source à distance avec p:graphicImage et StreamedContent
Je suis en train d'affichage de l'image en octets, qui est enregistré dans la base de données comme un StreamedContent
dans le <p:graphicImage>
comme suit:
<p:graphicImage value="#{item.imageF}" width="50" id="grpImage" height="80"/>
private StreamedContent content; //getter and setter
public StreamedContent getImageF() {
if (student.getImage() != null) {
InputStream is = new ByteArrayInputStream(student.getImage());
System.out.println("Byte :"+student.getImage());
content = new DefaultStreamedContent(is, "", student.getStuID());
System.out.println("ddd ------------------------------- " + content);
return content;
}
return content;
}
Cela renvoie une image vide. Comment est-il la cause et comment puis-je le résoudre?
La sortie standard (stdout) imprime les suivantes:
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@b0887b
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1d06a92
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@39a60
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@8c3daa
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1dbe05b
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@66a266
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1293976
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@17b7399
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1e245a5
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@4a7153
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1561bfd
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@47a8c2
Vous devez vous connecter pour publier un commentaire.
La
<p:graphicImage>
exige une certaine méthode de lecture. Il va savoir être invoquée deux fois par image de synthèse, chacun dans un de complètement différent de la requête HTTP.La première requête HTTP, qui a demandé le code HTML résultat d'une page JSF, appeler le getter pour la première fois afin de générer le code HTML
<img>
élément avec la droite unique et auto-généré URL dans lasrc
attribut qui contient des informations sur les haricots et les getter exactement devrait être appelée chaque fois que le navigateur internet est sur le point de demander à l'image. Notez que la lecture n'est qu'à ce moment pas besoin de retourner l'image du contenu. Il ne serait pas être utilisé de quelque façon que ce n'est pas la façon dont fonctionne le HTML (images ne sont pas "inline" dans le code HTML de sortie, mais elles sont au lieu de les commander séparément).Une fois que le navigateur récupère le code HTML de suite que la réponse HTTP, il va analyser le code source HTML dans le but de présenter le résultat visuellement à l'utilisateur final. Une fois le navigateur rencontre une
<img>
élément lors de l'analyse de la source HTML, alors il enverra une nouvelle marque de la requête HTTP dans l'URL comme indiqué dans sonsrc
attribut afin de télécharger le contenu de l'image et de l'intégrer dans la présentation visuelle. Cela va appeler la méthode de lecture pour la deuxième fois, qui à son tour doit retourner le réelle contenu de l'image.Dans votre cas particulier PrimeFaces était apparemment incapable d'identifier et d'invoquer la lecture afin de récupérer l'image réelle du contenu, ou de la lecture n'a pas de retour prévu le contenu de l'image. L'utilisation de
#{item}
nom de la variable et la beaucoup d'appels dans le journal suggère que vous l'utilisiez dans un<ui:repeat>
ou un<h:dataTable>
. Probablement le backing bean est la portée de la requête et le modèle de données n'est pas correctement conservés lors de la demande pour l'image et le JSF ne serez pas en mesure d'invoquer la lecture au cours de l'itération droit à la ronde. Une vue étendue bean serait également ne pas fonctionner comme le JSF de l'état d'affichage est pas disponible lorsque le navigateur demande réellement l'image.Pour résoudre ce problème, votre meilleur pari est de réécrire la méthode de lecture en tant que telle, de sorte qu'il peut être invoqué par la demande de base dans lequel vous passez l'image unique identificateur de
<f:param>
au lieu de compter sur l'aide des propriétés du bean qui peut aller de "out of sync" au cours de la suite des requêtes HTTP. Il serait complètement de sens d'utiliser une application étendue de managed bean pour ce qui n'ont pas d'état. En outre, unInputStream
peut être lu qu'une seule fois, et non pas plusieurs fois.En d'autres termes: jamais déclarer
StreamedContent
ni aucuneInputStream
ou mêmeUploadedFile
comme un haricot bien; seulement le créer tout nouveau dans la lecture d'un apatride@ApplicationScoped
bean lorsque le navigateur demande en fait le contenu de l'image.E. g.
Où la
StudentImages
backing bean peut ressembler à ceci:Veuillez noter que ceci est un cas très particulier dans lequel l'exécution de la logique métier dans une méthode de lecture est complètement légitime, compte tenu de la façon dont le
<p:graphicImage>
fonctionne sous les couvertures. Invoquant la logique métier dans les méthodes de lecture est généralement mal vu, voir aussi Pourquoi JSF appels getters plusieurs fois. N'utilisez pas de ce cas spécial, comme excuse, pour d'autres standard (non spéciaux) des cas. Veuillez également noter que vous ne pouvez pas faire usage de EL 2.2 fonction de la méthode de passage des arguments comme#{studentImages.image(student.id)}
parce que cet argument ne finira pas dans l'URL de l'image. Donc vous avez vraiment besoin de passer comme<f:param>
.Si vous arrive d'utiliser OmniFaces 2.0 ou plus récente, alors envisager l'utilisation de ses
<o:graphicImage>
à la place qui peut être utilisé de manière plus intuitive, avec une application étendue méthode de lecture directement en déléguant à la méthode de service et de soutien de EL 2.2 arguments de méthode.Donc:
Avec
Voir aussi le blog sur le sujet.
ManageBean
avecRequestScope
. Comment rendre la dynamique de l'image avecRequestScope
bean?studenList
commeMap
dansRequestScope
bean lors de la fève de l'état d'initialisation. Je vais récupérerStudent
de laMap
àgetImage()
méthode. Est-il ok?f:param
nom est"id"
mais.get("studentId")
ne correspond pas à ce nom.Essayez d'inclure un type mime. Dans votre posté exemple, vous avez aussi "". Le vide de l'image peut être parce qu'il ne reconnaît pas le flux en tant que fichier image depuis que le champ est une chaîne vide. Il faut donc ajouter un type mime image/png ou image/jpg et voir si cela fonctionne:
Il ya un couple de possibilités ici (et merci de poster l'ensemble de la classe, si ce n'est pas ça).
1) Vous n'êtes pas initialiser correctement l'image
2) Votre flux de données est vide de sorte que vous obtenez rien
Je suis en supposant étudiant.getImage() a une signature de byte[] donc, assurez-vous d'abord que les données sont intactes et représente une image. Deuxièmement--vous n'êtes pas la spécification d'un type de contenu qui doit être "image/jpg" ou ce que vous êtes en utilisant.
Voici une partie du code réutilisable pour le vérifier, je suis en utilisant Primefaces 2 pour cela.
et du balisage...
Si ce code fonctionne, alors vous êtes mis en place correctement. Malgré le fait que c'est des ordures code pour le flux (ne pas utiliser en production) il devrait vous donner un point de résoudre les problèmes à partir. Ma conjecture est que vous pourriez avoir quelque chose qui se passe dans votre APP ou autre Base de données cadre où vous êtes byte[] est vide ou qu'il est mal formaté. Sinon, vous pouvez juste avoir un contenu de type problème.
Enfin, je voudrais cloner les données à partir de la fève de sorte que les étudiants.getImage() ne seraient copiés dans un nouveau tableau et ensuite utilisé. De cette façon, si vous avez quelque chose d'inconnu va (autre chose déplacement de l'objet ou modification de l'byte[] vous n'êtes pas déconner avec votre flux.
Faire quelque chose comme:
de sorte que votre bean dispose d'une copie (ou de Tableaux.copier()--tout ce qui flotte votre bateau). Je ne peux pas insister assez sur la façon dont quelque chose de simple comme ce type de contenu est généralement de ce qui est mauvais. Bonne chance avec elle.
La réponse de BalusC est (comme d'habitude) la bonne.
Mais garder une chose (comme déjà indiqué par lui) dans l'esprit. La demande finale est effectuée à partir du navigateur pour obtenir l'URL de la construction
<img>
tag. Ce n'est pas fait dans un contexte jsf'.Donc, si vous essayez par exemple de l'accès à la phaseId (enregistrement ou toute autre raison),
Il en résultera une
NullPointerException
et d'une certaine manière trompeuse message d'erreur que vous obtiendrez, c'est:Il m'a fallu un certain temps pour comprendre quel était le problème.