file-upload - primefaces 显示数据库中的图像

标签 file-upload jsf-2 primefaces graphicimage

<分区>

我正在尝试显示客户图像(存储在 BLOB 对象中的 CustomerMaster.customerPhoto 中)。我正在使用 imageBuilder Bean (RequestScoped) 根据存储在 CustomerMaster 中的内容构建图像在 Customer Bean(ViewScoped) 中可用。我在 ImageBuilder 中添加了属性以访问客户 Bean 中的 CustomerMaster 对象。还添加了用于跟踪目的的 sysout 语句。

这里是输出

09:34:22,817 INFO  [stdout] (http--127.0.0.1-8080-2) getImage - 1
09:34:22,817 INFO  [stdout] (http--127.0.0.1-8080-2) getImage - 3
09:34:22,817 INFO  [stdout] (http--127.0.0.1-8080-2) getImage - 4
09:34:22,817 INFO  [stdout] (http--127.0.0.1-8080-2) getImage - 5PhotoMaster [photoId=1,  contentType=image/gif]    2064
09:34:22,817 INFO  [stdout] (http--127.0.0.1-8080-2) getImage - 6
09:34:22,827 WARNING [javax.enterprise.resource.webcontainer.jsf.context] (http--127.0.0.1-8080-2) JSF1091: No mime type could be found for file dynamiccontent.  To resolve this, add a mime-type mapping to the applications web.xml.
09:34:23,057 SEVERE [org.primefaces.application.PrimeResourceHandler] (http--127.0.0.1-8080-4) Error in streaming dynamic resource. Unable to set property customerBean for managed bean imageBuilderBean

根据 sysout 语句,我可以看到 ImageBuilderBean 能够访问 CustomerMaster 对象并能够创建 DefaultStreamedContent。

但后来我收到以下严重消息,网页上未显示图像:

09:34:23,057 SEVERE [org.primefaces.application.PrimeResourceHandler] (http--127.0.0.1-8080-4) Error in streaming dynamic resource. Unable to set property customerBean for managed bean imageBuilderBean

如果我在 CustomerBean(而不是 ViewScoped)中使用 Session 范围,则一切都是工作文件。甚至图像显示在网页上。根据我的理解,从 requestScoped Bean 调用 Viewscoped bean 应该没有任何问题。

我不确定哪里出了问题。请帮忙。请参阅代码以供引用。

ImageBuilder.Java

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

    @ManagedBean (name="imageBuilderBean")
    @RequestScoped
    public class ImageBuilderBean implements Serializable {

        private static final long serialVersionUID = -480089903900643650L;

        @ManagedProperty(value="#{customerBean}")    
        private CustomerBean customerBean;

        private StreamedContent image;

        public ImageBuilderBean() {
            super();
        }

        @PostConstruct
        void ResetBean(){
            System.out.println("getImage - 1");

            FacesContext context = FacesContext.getCurrentInstance();

            if (context.getRenderResponse()) {
                System.out.println("getImage - 2");
                // So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
                image = new DefaultStreamedContent();
            }
            else {
                System.out.println("getImage - 3");

                CustomerMaster custMaster = customerBean.getCustMaster();
                if (custMaster != null){
                    System.out.println("getImage - 4");

                    PhotoMaster photo = custMaster.getCustomerPhoto();
                    if (photo != null) {

                        try {
                            System.out.println("getImage - 5" + photo + "    " + photo.getContent().length());
                            InputStream inputStream = photo.getContent().getBinaryStream();
                            image = new DefaultStreamedContent(inputStream, photo.getContentType());
                            System.out.println("getImage - 6");
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            System.out.println("exception Shirish");
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

客户.XHTML

<p:column>
    <p:graphicImage id="custImageId" value="#{imageBuilderBean.image}" cache="false" />
</p:column> 

CustomerBean.Java

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

@ManagedBean (name="customerBean")
@ViewScoped
public class CustomerBean implements Serializable {

private static final long serialVersionUID = -3727342589028832013L;
// Setters and Getters

更新:

由于 graphicImage 标签被转换为 <img>标签。浏览器生成两个显示图像的请求。生成以下两个 url:

  1. /proj/views/user/CustomerRegistration.xhtml - ManagedProperty 注释返回 View 范围的 customerBeans。

  2. /proj/javax.faces.resource/dynamiccontent.xhtml - 无法返回 customerBean。因此,我们看到“无法为托管 bean imageBuilderBean 设置属性 customerBean”错误消息

有什么建议吗?

最佳答案

问题出在 ViewScoped 和 SessionScoped bean 的逻辑上。

在 RequestScoped beans 中,所有请求都由新的 bean 实例处理
在 SessionScoped bean 中,携带相同 session 的所有请求都由相同的实例处理。

ViewScoped bean 介于这两者之间。它创建“伪 session ”,其工作方式类似于 session bean,但它是通过其他方式获取的。它的处理方式与浏览器发送 session 信息的 session 范围 bean 的处理方式不同(例如在 cookie 中或以其他方式),但它在“网页”本身(在 javaScript 中)中保持不变,因此对于网页发送的每个 ajax 请求它添加它自己的“vievSessionKey”(每个 View 都是唯一的)。

在显示页面时,浏览器发送网页请求,然后浏览器(不是网页)为每张图片发送另一个请求。在这种情况下,图像请求不会在网页请求时生成 viewSessionKey,因此 bean 将作为另一个新 View 执行操作,并初始化新的 bean 实例。

如果你想对 ViewScoped beans 进行这样的操作,你需要实现在每个 bean 的每个新实例之间传输数据的方法。您可以尝试制作某种带有图片数据或一些静态字段的单例管理器。但这是解决此问题的“丑陋”方法,更合乎逻辑的方法是使您的 bean session 作用域……或者至少将某些功能分离到新的 session 作用域的 bean。

ps:我知道我发现了一些恐龙问题,但我遇到了同样的问题,在阅读你的问题时,我意识到了 javascripts/浏览器为每种 bean 类型所做的事情的逻辑

关于file-upload - primefaces 显示数据库中的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13225982/

相关文章:

jsf-2 - primefaces mobile 中的模板

php - kotlin 通过改造上传图片

mysql - 上传 Coldfusion 网站

jsf-2 - 重置PrimeFaces DataTable状态(过滤器,排序,分页)

validation - isValidationFailed 默认值

jsf - PrimeFaces LazyDataModel 在实时滚动后无法正确解析行?

ajax - 文件 uploader 的 Ajax 实现中的内存泄漏(Heroku 上的 Django)

c# - BITS 凭据问题

jquery - 当我将 URL 添加到列表,然后使用 ajax 时,我尝试在某些 iframe 中显示列表的内容,页面会自行重新加载

java - 在 XHTML 表单/Java PrimeFaces 中的多个按钮上使用 primefaces 对话框