3

我正在尝试显示客户图像(存储CustomerMaster.customerPhoto在 BLOB 对象中)。我正在使用 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 中使用 Session 范围(而不是 ViewScoped),那么一切都是工作文件。甚至图像也显示在网页上。根据我的理解,从 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>html标签。浏览器生成两个显示图像的请求。生成以下两个网址:

  1. /proj/views/user/CustomerRegistration.xhtml - ManagedProperty 注释返回 viewscoped customerBeans。

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

有什么建议么?

4

1 回答 1

2

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

在 RequestScoped bean 中,所有请求都由新的 bean 实例
处理。在 SessionScoped bean 中,所有携带相同会话的请求都由同一个实例处理。

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

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

如果要对 ViewScoped bean 进行此类操作,则需要实现在每个 bean 的每个新实例之间传输数据的方式。您可以尝试制作某种带有图片数据或一些静态字段的 Singleton 管理器。但这是解决此问题的“丑陋”方式,更合乎逻辑的方式是使您的 bean 会话范围...或至少将某些功能与新的会话范围 bean 分开。

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

于 2013-02-06T21:17:32.733 回答