usar - primefaces graphic image url
Cargue imágenes desde fuera de la carpeta webapps/webcontext/deploy con la etiqueta<h: graphicImage> o<img> (4)
Necesito mostrar imágenes que residen fuera de la carpeta de implementación en la aplicación web usando la etiqueta JSF <h:graphicimage>
o la etiqueta HTML <img>
. ¿Cómo puedo lograr eso?
En JSP
<img src="data:image/jpeg;base64,
<%= new String(Base64.encode(Files.readAllBytes(Paths.get("C://temp//A.jpg"))))%>"/>
Los paquetes son com.sun.jersey.core.util.Base64
, java.nio.file.Paths
y java.nio.file.Files
.
En PrimeFaces puedes implementar tu bean de esta manera:
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()));
}
En tu HTML Facelet:
<body onload="#{yourBean.prepImage()}"></body>
<p:graphicImage value="#{youyBean.image}" style="width:100%;height:100%" cache="false" >
</p:graphicImage>
Sugiero establecer el atributo cache = "false" en el componente graphicImage.
Hasta el punto, debe ser accesible por una URL pública. Por lo tanto, <img src>
debe referir un http://
URI, no algo así como un file://
URI más o menos. En última instancia, la fuente HTML se ejecuta en la máquina del usuario final y las imágenes se descargan individualmente por el navegador web durante el análisis de la fuente HTML. Cuando el navegador web encuentra un URI de file://
como C:/path/to/image.png
, buscará en la propia imagen el sistema de archivos del disco local del usuario final en lugar de la imagen del servidor web. Obviamente, esto no funcionará si el navegador web se ejecuta en una máquina físicamente diferente a la del servidor web.
Hay varias formas de lograr esto:
Si tiene control total sobre la carpeta de imágenes, simplemente coloque la carpeta con todas las imágenes, por ej.
/images
Images directamente en la carpeta de despliegue de servletcontainer, como la carpeta/webapps
en el caso de Tomcat y/domains/domain1/applications
carpeta de/domains/domain1/applications
en caso de GlassFish . No es necesaria ninguna otra configuración.O bien, agregue un nuevo contexto de aplicación web al servidor que apunte a la ubicación del sistema de archivos del disco absoluto de la carpeta con esas imágenes. Cómo hacerlo depende del contenedor utilizado. Los ejemplos siguientes suponen que las imágenes se encuentran en
/path/to/images
y que desea acceder a ellas a través de http: //.../images .En el caso de Tomcat, agregue la siguiente entrada nueva a
/conf/server.xml
de Tomcat dentro de<Host>
:<Context docBase="/path/to/images" path="/images" />
En el caso de GlassFish, agregue la siguiente entrada a
/WEB-INF/glassfish-web.xml
:<property name="alternatedocroot_1" value="from=/images/* dir=/path/to" />
En el caso de WildFly, agregue la siguiente entrada dentro de
<host name="default-host">
of/standalone/configuration/standalone.xml
...<location name="/images" handler="images-content" />
... y más abajo en la entrada
<handlers>
del mismo<subsystem>
que arriba<location>
:<file name="images-content" path="/path/to/images" />
O crea un
Servlet
que transmita la imagen del disco a la respuesta:@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 usa OmniFaces, el
FileServlet
puede ser útil ya que también tiene en cuenta las solicitudes de encabezado, almacenamiento en caché y rango.O bien, use OmniFaces
<o:graphicImage>
que admita una propiedad de bean que devuelvebyte[]
oInputStream
:public InputStream getImage(String filename) { return new FileInputStream(new File("/path/to/images", filename)); }
O bien, use PrimeFaces
<p:graphicImage>
que admita un método de bean que devuelva contenido específico deStreamedContent
PrimeFaces.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))); } }
Para la primera manera y los enfoques Tomcat y WildFly de segunda manera, las imágenes estarán disponibles en http://example.com/images/filename.ext y, por lo tanto, se pueden referenciar en HTML simple de la siguiente manera
<img src="/images/filename.ext" />
Para el enfoque GlassFish de segunda y tercera manera, las imágenes estarán disponibles en http://example.com/context/images/filename.ext y, por lo tanto, se pueden referenciar en HTML simple de la siguiente manera
<img src="#{request.contextPath}/images/filename.ext" />
o en JSF de la siguiente manera (la ruta del contexto se antepone automáticamente)
<h:graphicImage value="/images/filename.ext" />
Para el enfoque de OmniFaces en cuarta forma, refiéralo de la siguiente manera
<o:graphicImage value="#{bean.getImage(''filename.ext'')}" />
Para el enfoque PrimeFaces en el quinto camino, hágalo de la siguiente manera:
<p:graphicImage value="#{bean.image}">
<f:param name="filename" value="filename.ext" />
</p:graphicImage>
Ver también:
- Forma recomendada para guardar archivos cargados en una aplicación servlet
- La forma más simple de servir datos estáticos desde fuera del servidor de aplicaciones en una aplicación web Java
- Plantilla abstracta para un servlet de recursos estáticos (compatible con el almacenamiento en caché de HTTP)
- Mostrar imagen como byte [] desde la base de datos como imagen gráfica en la página JSF
- Visualice la imagen dinámica desde la base de datos con p: graphicImage y StreamedContent
Para lograr lo que necesita con las etiquetas <h:graphicImage>
o <img>
, debe crear un alias Tomcat v7 para mapear la ruta externa al contexto de su aplicación web.
Para hacerlo, deberá especificar el contexto de su aplicación web . Lo más fácil sería definir un archivo META-INF / context.xml con el siguiente contenido:
<Context path="/myapp" aliases="/images=/path/to/external/images">
</Context>
Luego, luego de reiniciar su servidor Tomcat, puede acceder a sus archivos de imágenes usando las etiquetas <h:graphicImage
> o <img>
siguiente manera:
<h:graphicImage value="/images/my-image.png">
o
<img src="/myapp/images/my-image.png">
* Tenga en cuenta que la ruta de contexto es necesaria para la etiqueta, pero no para la
Otro enfoque posible si no requiere que las imágenes estén disponibles a través del método HTTP GET, podría ser el uso de la etiqueta Primefaces <p:fileDownload>
(usando commandLink o commandButton tags - HTTP POST method ).
En tu Facelet:
<h:form>
<h:commandLink id="downloadLink" value="Download">
<p:fileDownload value="#{fileDownloader.getStream(file.path)}" />
</h:commandLink>
</h:form
En tu 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;
}
}
}