问题描述
我使用流式内容从后端数据库生成动态图像.当与p:graphicImage一起使用时,它们可以正常工作.
I generate dynamic images from a backend database using streamed content. They work fine when used with p:graphicImage.
当这样的动态图像需要作为div的背景时,就会出现问题.
The issue comes when such a dynamic image needs to be the background of div.
如何使用以流内容创建的动态图像作为div元素的背景?
How can I use dynamic images created with stream content as a background of a div element?
JSF控制器
public StreamedContent imageByCodeInlineWithoutGet(String code) {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getRenderResponse()) {
return new DefaultStreamedContent();
} else {
String id = code;
if (id == null) {
return new DefaultStreamedContent();
}
String j = "select s from Upload s where lower(s.code)=:id";
Map m = new HashMap();
m.put("id", id.trim().toLowerCase());
Upload temImg = getUploadFacade().findFirstByJpql(j, m);
if (temImg != null) {
byte[] imgArr = null;
try {
imgArr = temImg.getBaImage();
} catch (Exception e) {
return new DefaultStreamedContent();
}
if (imgArr == null) {
return new DefaultStreamedContent();
}
StreamedContent str = new DefaultStreamedContent(new ByteArrayInputStream(imgArr), temImg.getFileName());
return str;
} else {
return new DefaultStreamedContent();
}
}
}
动态生成图像
<p:graphicImage cache="false" value="#{streamedContentController.imageByCodeInlineWithoutGet('header__logo')}" >
</p:graphicImage>
我想将图像用作css背景,如下所示
I want to use the image as a css background like below
<style type="text/css">
background-image:#{streamedContentController.imageByCodeInlineWithoutGet('header__logo')};
</style>
或作为参数传递.
<div class="hero__item set-bg" data-setbg="#{streamedContentController.imageByCodeInlineWithoutGet('header__logo')}">
</div>
</div>
JSF或PrimeFaces或任何其他库是否有可能?
Is it possible with JSF or PrimeFaces or any other library ?
推荐答案
在GET请求中针对特定路径发送自定义内容的最简单方法是 HttpServlet
.
The easiest way of sending custom content on a GET request for a specific path is a HttpServlet
.
仅从开球示例开始:
@WebServlet("/images/*")
public class ImageServlet extends HttpServlet {
@EJB
private YourEJB imageEJB; // your EJB for images
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// get the image code from the requested path
String imageCode = request.getPathInfo().substring(1);
// get the image type and byte array as the content
response.setContentType(getServletContext().getMimeType(/* image type */);
// OR
response.setContentType(/* image mime type */);
response.setContentLength(/* byte array length */); // just 'array.length'
response.getOutputStream().write(/* byte array */); // just `array`
}
}
说明
这将注册自定义 HttpServlet
给定路径的a>(/images/*
可以更改为您想要的路径).当客户端通过GET请求加载图像时,将调用servlet.
Explanation
This registers a custom HttpServlet
for the given path (/images/*
this path can be changed to what you want).The servlet gets called when the client loads the image via a GET request.
然后,您可以从请求的路径获取图像代码(request.getPathInfo().substring(1)
获取文件路径并删除第一个斜杠).
Then you can get the image code from the requested path (request.getPathInfo().substring(1)
gets the file path and removes the first slash).
然后,您必须获取图像的mime类型.这可以通过两种方式实现:
Then you have to get the mime type of the image. This is possible by two ways:
- 获取基本文件扩展名(
jpg
,png
等),并从web.xml
(mime-type
元素)获取文件类型的mime类型 - 直接获取mime类型
- get the basic file extension (
jpg
,png
, etc.) and get the mime type for the file type fromweb.xml
(mime-type
elements) - directly get the mime type
然后,您必须具有代表图像内容的字节数组.用contentLength
设置响应大小.
Then you must have the byte array that represents the content of the image. Set the response size with contentLength
.
然后最后将字节数组写入响应.
Then finally write the byte array to the response.
好处是您可以在任何地方使用它(css,js,纯html等).
The good thing is you can use it everwhere (css, js, plain html, etc.).
只需指定/images/*code*
,就会加载图像.
Just specify the /images/*code*
and the image gets loaded.
Omnifaces GraphicImageBean (类似于此解决方案)
Omnifaces GraphicImageBean (similar to this solution)
这篇关于JSF动态图像作为div背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!