JSF 动态图像作为 div 背景

JSF Dynamic Image as div Background

我使用流式内容从后端数据库生成动态图像。它们在与 p:graphicImage.

一起使用时工作正常

当div的背景需要这样的动态图片时,问题就来了。

如何使用流内容创建的动态图像作为 div 元素的背景?

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 背景,如下所示

                        <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 或任何其他库?

在针对特定路径的 GET 请求上发送自定义内容的最简单方法是 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/images/* 此路径可以更改为您想要的)。 当客户端通过 GET 请求加载图像时,将调用 servlet。

然后就可以从请求的路径获取图片代码(request.getPathInfo().substring(1)获取文件路径,去掉第一个斜杠)

然后你必须得到图像的mime类型。这可以通过两种方式实现:

  • 获取基本文件扩展名(jpgpng 等)并从 web.xmlmime-type 元素)获取文件类型的 mime 类型
  • 直接获取mime类型

那么你必须有表示图像内容的字节数组。使用 contentLength.

设置响应大小

然后最后将字节数组写入响应。


用法

好处是你可以在任何地方使用它(css、js、普通 html 等)。

只需指定 /images/*code* 即可加载图像。


另请参阅

Omnifaces GraphicImageBean(类似于这个解决方案)