【问题标题】:java loses values from ManagedBeansjava从ManagedBeans中丢失值
【发布时间】:2013-03-08 11:32:05
【问题描述】:

我尝试编写一个应用程序来创建 PDF 文件,它使用 JavaServer Faces。当我将文本框的值从bean赋予工厂类时,我遇到了一个问题,值丢失了。我想知道为什么会这样,已经尝试了很多解决方案,但是它们会导致代码扩展并且没有帮助。

豆码:

@ManagedBean
@ViewScoped
public class PanelInneBean extends AbstractPanel implements Serializable {
    private static final long serialVersionUID = 1L;
    private final int CODE = 4;
    private boolean use;
    private String tytul, opis;
    private PdfFactory pdf = PdfFactory.getPdfObject();

    public PanelInneBean() {
    use = false;
    }

    public boolean getUse() {
    return use;
    }

    public String getTytul() {
    return tytul;
    }

    public void setTytul(String tytul) {
    this.tytul = tytul;
    }

    public String getOpis() {
    return opis;
    }

    public void setOpis(String opis) {
    this.opis = opis;
    }

    public int getCode() {
    return CODE;
    }

    private void add() {
    use = true;
    }

    public void addBean() {
    add();
    pdf.addElement(this);
    System.out.println("InnePanel after pdf.addElement() this.opis:" + this.opis);
    // This sysout prints the correct value after give object to factory
    }
}

工厂代码:

  public int addElement(PdfElement element) {
    pdfType = true;
    if (element.getUse()) {
        elementList.add(element);
        return 1;
    }
    return 0;
    }

    public void prepare() {
    for (PdfElement element : elementList) {
        System.out.println("element.code:" + element.getCode());
        switch (element.getCode()) {
        case 0:
        if (nF != null)
            break;
        nF = new NaglowekFactory(element, Counter.getNumber());
        break;
        case 1:
        if (pF != null)
            break;
        pF = new ProduktyFactory(element, Counter.getNumber());
        prodSum = pF.getProdukty().getSuma();
        euroData = pF.getProdukty().getEuroData();
        break;
        case 2:
        if (mF != null)
            break;
        mF = new MontazFactory(element, Counter.getNumber());
        servSum = mF.getMontaz().getSuma();
        break;
        case 3:
        if (uF != null)
            break;
        uF = new UslugiFactory(element, Counter.getNumber());
        asmSum = uF.getUslugi().getSuma();
        break;
        case 4:
        if (iF != null)
            break;
        iF = new InneFactory(element, Counter.getNumber());
            //here Opis value is empty
        break;
        }
    }
    System.out.println("factory.prepare() ->");
    }

InneFactory:的构造函数

    PanelInneBean inne;

public InneFactory(PdfElement element, int order) {
    inne = (PanelInneBean) element;
    System.out.println("innerFactory constructor, inne.getTytul(): "
        + inne.getTytul());

        //here values are empty

    this.order = order;
    list = new ArrayList<Element>();
}

public int getOrder() {
    return order;
}

我做错了什么?

【问题讨论】:

    标签: java jsf managed-bean


    【解决方案1】:

    我认为您对@ViewScoped bean 的实际工作方式存在普遍误解。 bean 对象本身在每次 Faces 请求时创建,并在每次 Faces 响应后销毁。

    在重新创建 bean 之后,JSF 将进入第一个生命周期阶段RestoreView。在此阶段,它将从视图状态中获取此 bean 的最后一个良好值并将它们应用到 bean 托管属性。

    基本上发生的事情是您正在调用一个操作,该操作生成一个单独的请求而不是加载页面的请求,此时您添加到 PdfFactory 的引用现在丢失了,因为最后一个 PdfFactory对象被破坏了!

    解决此问题的最佳方法是使 PdfFactory 成为托管 Bean。您可以在 @PostConstruct 方法中初始化工厂,也可以使用 @ManagedProperty 注释将其他托管 Bean 注入您的 PdfFactory bean。

    @ManagedBean
    @RequestScoped
    public PdfFactory extends ... implements Serializable {
    
      @ManagedProperty("#{myViewBean}")
      private MyViewBean viewBean;
    
      @PostConstruct
      public initializeFactory() {
        //Do stuff
      }
    
      public void prepare() {
        // prepare stuff
      }
    }
    

    【讨论】:

    • 当我有几个 ManagedBeans 向工厂发送数据时怎么办?只需将它们添加到@ManagedProperty?
    • @insict 你可以……有很多方法可以做到这一点,只是意识到你的工厂应该是具有某种范围的某种类型的 ManagedBean。在创建对象时创建 Factory 对象是您丢失数据的原因。
    • 感谢您的建议,我还有一个问题要问您,(或其他人)工厂类内部有私有类,例如 OtherFactory 具有适当的 ManagedBean 对象 (Other)。我应该如何使用注释@ManagedProperty OtherFactory 创建对象或在OtherFactory 内部创建特定对象Other
    • @insict 嗯,我不敢说实话。我从未尝试将工厂模式与托管 Bean(视图控制器模式)合并。也许您必须重新考虑您的设计......或者也许只是制作 PdfFactory @ApplicationScoped 并将其视为单例?然后,您所要做的就是在所有视图中将 PdfFactory 引用为 ManagedProperty。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 2022-11-30
    • 2016-08-31
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    相关资源
    最近更新 更多