2013-03-08 2 views
1

Я пытаюсь написать приложение для создания PDF-файлов, оно использует JavaServer Faces. Я борюсь с проблемой, когда я даю значение текстового поля из bean-компонента для фабричного класса, значения теряются. Интересно, почему это происходит, уже пробовали много решений, но они вызовут расширение кода и не помогут.java теряет значения из ManagedBeans

код 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; 
} 

, что я делаю не так?

ответ

1

Я думаю, что вы сталкиваетесь с распространенным заблуждением относительно того, как действительно работают бобы @ViewScoped. Сам объект bean создается по каждому запросу Faces и уничтожается после каждого ответа Faces.

После того, как компонент был создан, однако JSF войдет в первую фазу жизненного цикла RestoreView. На этом этапе он будет извлекать последние хорошие значения для этого компонента из состояния просмотра и применять их к управляемым свойствам компонентов.

В основном происходит то, что вы вызываете действие, которое генерирует отдельный запрос, чем тот, который загружал страницу, и в этот момент ссылка, добавленная вами в PdfFactory, теперь потеряна, потому что PdfFactory в последнем объекте был уничтожен!

Лучший способ решить эту задачу - сделать PdfFactory управляемым компонентом. Вы можете инициализировать завод по методу @PostConstruct, и вы можете ввести другие управляемые компоненты в ваш компонент PdfFactory, используя аннотацию @ManagedProperty.

@ManagedBean 
@RequestScoped 
public PdfFactory extends ... implements Serializable { 

    @ManagedProperty("#{myViewBean}") 
    private MyViewBean viewBean; 

    @PostConstruct 
    public initializeFactory() { 
    //Do stuff 
    } 

    public void prepare() { 
    // prepare stuff 
    } 
} 
+0

Что делать, если у меня есть пара ManagedBeans, отправляющая данные на завод? Просто добавьте их в @ManagedProperty? – insict

+0

@insict У вас может быть несколько способов, которыми вы можете это сделать, только осознавая, что ваш завод должен быть ManagedBean какого-то рода с какой-то областью. Создание объекта Factory при создании объекта - это то, почему вы теряете данные. –

+0

Благодарим вас за консультацию. У меня есть еще один вопрос для вас (или кто-то еще). В классе Factory есть частные классы внутри, например 'OtherFactory', который имеет собственный объект ManagedBean (' Other'). как я должен использовать аннотацию @ ManagedProperty 'OtherFactory', создающую объект или внутри' OtherFactory' для создания определенного объекта 'Other'? – insict

Смежные вопросы