Charger des images à partir de l'extérieur de webapps / webcontext / déployer le dossier en utilisant ou tag
j'ai besoin d'Afficher des images qui résident en dehors du dossier deploy dans l'application web en utilisant la balise JSF <h:graphicimage>
ou la balise HTML <img>
. Comment puis-je y parvenir?
4 réponses
au point, il doit être accessible par une URL publique. Ainsi, le <img src>
doit finalement faire référence à un http://
URI, pas quelque chose comme un file://
URI ou ainsi. En fin de compte, la source HTML est exécutée sur la machine d'enduser et les images sont téléchargées individuellement par le webbrowser lors de l'analyse de la source HTML. Lorsque le webbrowser rencontre un file://
URI tel que C:\path\to\image.png
, alors il regardera dans le système de fichiers de disque local d'enduser pour l'image au lieu de la serveur web. Cela ne va évidemment pas fonctionner si le webbrowser fonctionne sur une machine physiquement différente de celle du webserver.
Il y a plusieurs façons d'y parvenir:
-
si vous avez le contrôle total sur le dossier images, alors il suffit de déposer le dossier avec toutes les images, par exemple
/images
directement dans le dossier de déploiement de servletcontainer, comme le dossier/webapps
dans le cas de Tomcat et le dossier/domains/domain1/applications
dans cas de GlassFish. Aucune configuration supplémentaire n'est nécessaire.
-
Ou ajouter une nouvelle webapp contexte pour le serveur, ce qui souligne l'absolue de disque système de fichiers de l'emplacement du dossier, avec ces images. La façon de procéder dépend du contenant utilisé. Les exemples ci-dessous supposent que les images sont localisées dans
/path/to/images
et que vous souhaitez y accéder via http://.../ images .dans le cas de Tomcat, ajouter la nouvelle rubrique suivante à
/conf/server.xml
dans le cas de Tomcat<Host>
:<Context docBase="/path/to/images" path="/images" />
dans le cas du poisson de verre, ajouter la rubrique suivante à
/WEB-INF/glassfish-web.xml
:<property name="alternatedocroot_1" value="from=/images/* dir=/path/to" />
dans le cas d'une mouche sauvage, ajouter l'entrée suivante à l'intérieur de
<host name="default-host">
de/standalone/configuration/standalone.xml
...<location name="/images" handler="images-content" />
... et plus bas dans
<handlers>
entrée de la même<subsystem>
comme ci-dessus<location>
:<file name="images-content" path="/path/to/images" />
-
Ou, créer un
Servlet
qui diffuse l'image à partir du disque de réponse:@WebServlet("/images/*") public class ImageServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String filename = request.getPathInfo().substring(1); File file = new File("/path/to/images", filename); response.setHeader("Content-Type", getServletContext().getMimeType(filename)); response.setHeader("Content-Length", String.valueOf(file.length())); response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\""); Files.copy(file.toPath(), response.getOutputStream()); } }
si vous utilisez des OmniFaces, alors le
FileServlet
peut être utile car il prend également en compte les requêtes head, caching et range.
-
Ou, utiliser OmniFaces
<o:graphicImage>
qui supporte une propriété de haricot retournantbyte[]
ouInputStream
:public InputStream getImage(String filename) { return new FileInputStream(new File("/path/to/images", filename)); }
-
Ou, utiliser PrimeFaces
<p:graphicImage>
qui prend en charge une méthode d'haricot retour PrimeFaces spécifiquesStreamedContent
.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 filename = context.getExternalContext().getRequestParameterMap().get("filename"); return new DefaultStreamedContent(new FileInputStream(new File("/path/to/images", filename))); } }
Pour le premier et le Tomcat et WildFly approches dans la deuxième voie, les images seront disponibles par http://example.com/images/filename.ext et donc référençable en HTML comme suit
<img src="/images/filename.ext" />
pour l'approche GlassFish dans la deuxième et la troisième voie, les images seront disponibles par http://example.com/context/images/filename.ext et donc référençable en HTML comme suit
<img src="#{request.contextPath}/images/filename.ext" />
ou dans JSF comme suit: (le chemin de contexte est automatiquement préprogrammé)
<h:graphicImage value="/images/filename.ext" />
pour L'approche OmniFaces dans la quatrième voie, référence comme suit
<o:graphicImage value="#{bean.getImage('filename.ext')}" />
pour l'approche PrimeFaces dans le Cinquième Sens, référence comme suit:
<p:graphicImage value="#{bean.image}">
<f:param name="filename" value="filename.ext" />
</p:graphicImage>
voir aussi:
- méthode recommandée pour sauvegarder les fichiers téléchargés dans une application servlet
- la façon la plus simple de servir des données statiques à partir de l'extérieur du serveur d'application dans une application Web Java
- Abstrait modèle pour une ressource statique servlet (soutien à la mise en cache HTTP)
- Afficher l'image que byte[] à partir de la base de données que le graphique de l'image dans la page JSF
- afficher l'image dynamique à partir de la base de données avec P: graphicImage et StreamedContent
afin d'obtenir ce dont vous avez besoin en utilisant les balises <h:graphicImage>
ou <img>
, vous devez créer un alias V7 Tomcat afin de mapper le chemin externe vers le contexte de votre application web.
pour ce faire, vous devrez spécifier le contexte de votre application web . Le plus facile serait de définir un méta-INF/contexte.fichier xml avec le contenu suivant:
<Context path="/myapp" aliases="/images=/path/to/external/images">
</Context>
puis après avoir redémarré votre serveur Tomcat, vous pouvez accéder vos fichiers d'images en utilisant <h:graphicImage
> ou <img>
tags comme suit:
<h:graphicImage value="/images/my-image.png">
ou
<img src="/myapp/images/my-image.png">
* notez que le chemin de contexte est nécessaire pour la balise mais pas pour la
une autre approche possible si vous n'avez pas besoin que les images soient disponibles par la méthode HTTP GET, pourrait être d'utiliser Primefaces <p:fileDownload>
tag (using commandLink ou bouton de commande balises méthode HTTP POST ).
Dans votre Facelet:
<h:form>
<h:commandLink id="downloadLink" value="Download">
<p:fileDownload value="#{fileDownloader.getStream(file.path)}" />
</h:commandLink>
</h:form
Dans votre bean:
@ManagedBean
@ApplicationScope
public class FileDownloader {
public StreamedContent getStream(String absPath) throws Exception {
FileInputStream fis = new FileInputStream(absPath);
BufferedInputStream bis = new BufferedInputStream(fis);
StreamedContent content = new DefaultStreamedContent(bis);
return content;
}
}
}
dans PrimeFaces vous pouvez mettre en œuvre votre haricot de cette façon:
private StreamedContent image;
public void setImage(StreamedContent image) {
this.image = image;
}
public StreamedContent getImage() throws Exception {
return image;
}
public void prepImage() throws Exception {
File file = new File("/path/to/your/image.png");
InputStream input = new FileInputStream(file);
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
setImage(new DefaultStreamedContent(input,externalContext.getMimeType(file.getName()), file.getName()));
}
dans votre Facelet HTML:
<body onload="#{yourBean.prepImage()}"></body>
<p:graphicImage value="#{youyBean.image}" style="width:100%;height:100%" cache="false" >
</p:graphicImage>
je suggère de définir l'attribut cache=" false " dans le composant graphicImage.
In JSP
<img src="data:image/jpeg;base64,
<%= new String(Base64.encode(Files.readAllBytes(Paths.get("C:\temp\A.jpg"))))%>"/>
Les colis sont com.sun.jersey.core.util.Base64
, java.nio.file.Paths
et java.nio.file.Files
.