Get concrete URL of <p:graphicImage> returning StreamedContent

拈花ヽ惹草 提交于 2019-12-04 07:10:21

This have one solution - using servlet here is a servlet which will work in any jsf application

package com.dossier.web.handlers;

//~--- non-JDK imports --------------------------------------------------------



import com.dossier.backend.services.mongo.FileService;
import com.mongodb.gridfs.GridFSDBFile;

//~--- JDK imports ------------------------------------------------------------

import java.io.*;

import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;

/**
 *
 * @author Armen Arzumanyan
 */
@WebServlet(urlPatterns = { "/PreviewImage" })
public class PreviewImage extends HttpServlet implements SingleThreadModel {
    private static final long serialVersionUID = -6624464650990859671L;
    private FileService       fileAction       = new FileService();

    @Override
    public void init() throws ServletException {
        super.init();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPreviewImage(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {}

    private void doPreviewImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        FacesContext context   = FacesContext.getCurrentInstance();
        String       fileIdStr = request.getParameter("fileId");
        String       widthStr  = request.getParameter("w");
        GridFSDBFile file      = null;
        int          width     = 0;

        if ((widthStr != null) && (widthStr.length() > 0)) {
            try {
                width = Integer.parseInt(widthStr);
            } catch (NumberFormatException e) {}
        }

        if (fileIdStr != null) {
            if (fileAction != null) {
                file = fileAction.getFile(fileIdStr.trim());
            }

            if (file != null) {
                byte[] content = IOUtils.toByteArray(file.getInputStream());

                if (content != null) {
                    String mimeType = file.getContentType();

                    response.addHeader("Pragma", "cache");
                    response.addHeader("Cache-Control", "max-age=3600, must-revalidate");
                    response.addDateHeader("Expires", System.currentTimeMillis() + 1000 * 3600 * 10);
                    response.setContentType(mimeType);

                    try {
                        if (((mimeType != null)
                                && (mimeType.equalsIgnoreCase("image/gif") || mimeType.equalsIgnoreCase("image/x-png")
                                    || mimeType.equalsIgnoreCase("image/png") || mimeType.equalsIgnoreCase("image/jpg")
                                    || mimeType.equalsIgnoreCase("image/jpeg"))) || (width == 0)) {
                            response.getOutputStream().write(content);
                        } else {

//                          ByteArrayInputStream bi = new ByteArrayInputStream(content);
//                          InputStream thumbStream = scaleImageJPG(bi, width);
//                          byte[] thumbContent = new byte[thumbStream.available()];
//                          thumbStream.read(thumbContent);
                            response.getOutputStream().write(content);
                        }
                    } catch (IOException e) {

                        // log.error("file content send error");
                        e.printStackTrace();
                    } catch (Exception e) {

                        // log.error("file exception: " + e);
                        e.printStackTrace();
                    } finally {
                        content = null;
                        file    = null;
                    }

                    return;
                }
            } else {

                // TODO add page not found
                response.addHeader("Pragma", "no-cache");
                response.addDateHeader("Expires", System.currentTimeMillis() - 1000 * 3600);

                try {
                    response.getWriter().println("file object is null");
                } catch (Exception e) {}

                return;
            }
        }

        // TODO add page not found
        response.addHeader("Pragma", "no-cache");
        response.addDateHeader("Expires", System.currentTimeMillis() - 1000 * 3600);

        try {
            response.getWriter().println("file id is not set");
        } catch (Exception e) {}

        // log.debug("file ID parameter is not set or file is not found");
        return;
    }

    // </editor-fold>
}


//~ Formatted by Jindent --- http://www.jindent.com

And here is a web page code

<h:graphicImage id="primage" styleClass="img-rounded img-responsive"
                                                                url="/PreviewImage?w=250&amp;fileId=#{updatePersonBean.person.imageId}"
                                                                width="250" rendered="#{updatePersonBean.person.imageId != null}"/>                                              
                                                <h:graphicImage id="primagenew" styleClass="img-rounded img-responsive"
                                                                url="/resources/img/userpic_simple.gif"
                                                                width="250" rendered="#{updatePersonBean.person.imageId == null}"/>

Enjoy

An easy way without need to implement a new bean is to output an invisible graphicImage and copy around the URL using Javascript:

<h:form id="myForm">
    <p:graphicImage id="urlOutputter" value="#{MyForm.image}" style="display: none;"/>
    <span id="imageData" data-image="***URL HERE***"/>
    <script>
        var url = document.getElementById("myForm:urlOutputter").src;
        document.getElementById("imageData").setAttribute("data-image", url);
    </script>

Have suggested a solution to this question here.

Long story short, you can use the getImageSrc method of the GraphicImageRenderer in order to get the image URI.

First step is extending the GraphicImageRenderer to publish the protected getImageSrc method:

public class GraphicImageRendererXtension extends GraphicImageRenderer {
    // publish the protected GraphicImageRenderer#getImageSrc method:
    public String getPublicImageSrc(FacesContext context, GraphicImage image) throws Exception {
        return getImageSrc(context, image);
    }
}

The we need a method in managed bean that enables us use the getPublicImageSrc method:

public class MyBean {
  // ...
  public String getImgUri(GraphicImage imgComponent) throws Exception {
    assert null != imgComponent;
    String imgUri = new GraphicImageRendererXtension().getPublicImageSrc(FacesContext.getCurrentInstance(),
                imgComponent);
    return imgUri;
  }
}

Finally we bind the p:graphicImage component to an arbitrary variable and invoke myBean.getImgUri to get the Uri for any purpose:

<h:outputLink value="#{myBean.getImgUril(myImage)}">
        <p:graphicImage binding="#{myImage}" value="#{myBean.img}" />
</h:outputLink> 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!