Mun*_*ian 42 jsf image jsf-2 graphicimage
我需要使用JSF <h:graphicimage>标记或HTML <img>标记在Web应用程序中显示驻留在deploy文件夹之外的图像.我怎样才能做到这一点?
Bal*_*usC 74
到目前为止,它必须可以通过公共URL访问.因此,<img src>必须最终引用http://URI,而不是file://URI 等.最终,HTML源在最终用户的机器上执行,并且在解析HTML源期间,webbrowser单独下载图像.当webbrowser遇到file://诸如的URI C:\path\to\image.png之后,它将在终端用户自己的本地磁盘文件系统中查找图像而不是web服务器的图像.如果webbrowser在与Web服务器不同的机器上运行,这显然不会起作用.
有几种方法可以实现这一目标:
如果你完全控制images文件夹,那么只需删除包含所有图像的文件夹,例如/images直接放在servletcontainer的deploy文件夹中,例如/webappsTomcat的/domains/domain1/applications文件夹和GlassFish的文件夹.无需进一步配置.
或者,向服务器添加一个新的webapp上下文,该上下文指向包含这些图像的文件夹的绝对磁盘文件系统位置.怎么做取决于使用的容器.以下示例假定图像位于/path/to/images您希望通过http://.../images访问它们.
在Tomcat的情况下,将以下新条目添加到Tomcat的/conf/server.xml内部<Host>:
<Context docBase="/path/to/images" path="/images" />
Run Code Online (Sandbox Code Playgroud)
如果是GlassFish,请将以下条目添加到/WEB-INF/glassfish-web.xml:
<property name="alternatedocroot_1" value="from=/images/* dir=/path/to" />
Run Code Online (Sandbox Code Playgroud)
在WildFly的情况下,里面添加以下条目<host name="default-host">的/standalone/configuration/standalone.xml...
<location name="/images" handler="images-content" />
Run Code Online (Sandbox Code Playgroud)
...并进一步向下<handlers>的非常相同的条目<subsystem>如上<location>:
<file name="images-content" path="/path/to/images" />
Run Code Online (Sandbox Code Playgroud)
或者,创建一个Servlet将映像从磁盘流式传输到响应:
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
如果您碰巧使用OmniFaces,那么它FileServlet可能很有用,因为它还会考虑头部,缓存和范围请求.
或者,使用支持bean属性返回的OmniFaces<o:graphicImage>byte[]或InputStream:
@Named
@ApplicationScoped
public class Bean {
public InputStream getImage(String filename) {
return new FileInputStream(new File("/path/to/images", filename));
}
}
Run Code Online (Sandbox Code Playgroud)
或者,使用PrimeFaces<p:graphicImage>支持bean方法返回PrimeFaces特异性StreamedContent.
@Named
@ApplicationScoped
public class Bean {
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)));
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于第一种方式,Tomcat和WildFly以第二种方式接近,图像将可以通过http://example.com/images/filename.ext获得,因此可以在纯HTML中按照以下方式引用
<img src="/images/filename.ext" />
Run Code Online (Sandbox Code Playgroud)
对于第二种方式和第三种方式的GlassFish方法,图像将通过http://example.com/context/images/filename.ext提供,因此可以在纯HTML中按照以下方式进行引用:
<img src="#{request.contextPath}/images/filename.ext" />
Run Code Online (Sandbox Code Playgroud)
或者在JSF中如下(上下文路径自动添加)
<h:graphicImage value="/images/filename.ext" />
Run Code Online (Sandbox Code Playgroud)
对于第四种方式的OmniFaces方法,请参考如下
<o:graphicImage value="#{bean.getImage('filename.ext')}" />
Run Code Online (Sandbox Code Playgroud)
对于第五种方式的PrimeFaces方法,请参考如下:
<p:graphicImage value="#{bean.image}">
<f:param name="filename" value="filename.ext" />
</p:graphicImage>
Run Code Online (Sandbox Code Playgroud)
请注意,该示例#{bean}是@ApplicationScoped因为它基本上代表无状态服务.您也可以创建它@RequestScoped,但是随后会在每个请求上重新创建bean.你无法做到@ViewScoped,因为目前浏览器需要下载图像,服务器不会创建JSF页面.你可以做到@SessionScoped,但它会被保存在内存中,什么都不做.
| 归档时间: |
|
| 查看次数: |
65275 次 |
| 最近记录: |