Управляемый компонент со свойствами, унаследованными от суперкласса

У меня были проблемы при создании проекта JSF с ViewScope ManagedBeans. Поэтому я решил изолировать проблему простым кодом, в котором, очевидно, проблема сохраняется. В принципе я понял, что свойства, которые есть в классе TesteMBean, работают отлично, однако свойства, унаследованные от суперкласса GenericoMBean, не сохраняют своего значения.

Я все еще новичок в этом и поэтому не знаю, нормально ли это поведение JSF. Может ли кто-нибудь просветить меня по этому поводу? и если можно подскажите как правильно сделать на примере. большое спасибо.

Следуя коду.

Суперкласс:

package br.com.telesnet.sige.web.mb;


public abstract class GenericoTesteMBean {

    protected String textoBase;

    public java.lang.String getTextoBase() {
        if (this.textoBase == null){
            return "";
        }else{
            return textoBase;
        }
    }

    public void setTextoBase(String textoBase) {
        this.textoBase = textoBase;
    }
}

Унаследованный управляемый компонент:

package br.com.telesnet.sige.web.testes;

import java.io.Serializable;

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

import br.com.telesnet.sige.web.mb.GenericoTesteMBean;

@ManagedBean
@ViewScoped
public class TesteMBean extends GenericoTesteMBean implements Serializable{
    private static final long serialVersionUID = 1L;
    private java.lang.Integer valor;
    private java.lang.String texto;

    public TesteMBean(){
        this.setValor(0);
    }

    public void incrementar(){
        this.setValor(this.getValor()+1);
        this.texto = this.getTexto() + "X";
        this.textoBase = this.getTextoBase() + "A";
    }

    public java.lang.Integer getValor() {
        if (this.valor == null){
            return 0;
        }else{
            return valor;
        }
    }

    public void setValor(java.lang.Integer valor) {
        this.valor = valor;
    }

    public java.lang.String getTexto() {
        if (this.texto == null){
            return "";
        }else{
            return texto;
        }
    }

    public void setTexto(java.lang.String texto) {
        this.texto = texto;
    }
}

Веб-форма:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:body>
    <f:view>
        <h:form id="formLabel">
            <h:outputLabel value="Valor:"></h:outputLabel>
            <h:outputLabel value="#{testeMBean.valor}"></h:outputLabel>

            <h:outputLabel value="Texto:"></h:outputLabel>
            <h:outputLabel value="#{testeMBean.texto}"></h:outputLabel>

            <h:outputLabel value="TextoBase:"></h:outputLabel>
            <h:outputLabel value="#{testeMBean.textoBase}"></h:outputLabel>

        </h:form>

        <h:form id="formIncremento">
            <h:commandButton actionListener="#{testeMBean.incrementar()}" value="incrementar">
            </h:commandButton>

        </h:form>


    </f:view>
</h:body>
</html>

Нежелательный вывод (кнопка «incrementar» нажата пять раз):

    Valor: 5 Texto: XXXXX TextoBase: A

Требуемый результат (кнопка "incrementar" нажата пять раз):

    Valor: 5 Texto: XXXXX TextoBase: AAAAA

person Ronneery Teles    schedule 19.03.2013    source источник
comment
Я забыл опубликовать реферат в суперклассе. Исправлено сейчас.   -  person Ronneery Teles    schedule 19.03.2013


Ответы (3)


Просто скопировал ваши три файла в мою рабочую область, и «инкрементный» работает отлично.

Единственная разница заключается в вашем управляемом компоненте, у вас есть этот импорт для аннотации @ManagedBean

import javax.annotation.ManagedBean;

изменить его на

import javax.faces.bean.ManagedBean;

Вы можете прочитать это для понятий Java EE 6 @javax.annotation.ManagedBean по сравнению с @javax.inject.Named по сравнению с @javax.faces.ManagedBean

person Serkan Arıkuşu    schedule 19.03.2013
comment
Спасибо. Мне действительно нужно прочитать достаточно, чтобы понять эти различия. Я делаю изменение в аннотации для javax.faces.bean.ManagedBean, и даже тогда A не увеличивает AAAAA .... В ваших тестах это произошло? Что еще может вызвать этот эффект здесь? - person Ronneery Teles; 19.03.2013
comment
Кроме этого импорта все было таким же и работало как задумано. Я бы предложил использовать точки отладки на incremantar и методы в абстрактном классе. Попробуйте использовать последние jar-файлы для jsf и, если возможно, используйте maven и начните с архетипа jsf. - person Serkan Arıkuşu; 19.03.2013

Обновить
Мой старый ответ удален, теперь, когда я вижу вашу проблему.

  1. Вам не нужен h:form вокруг ваших h:outputLabel. Просто используйте какой-нибудь h:outputPanel вокруг них, этого достаточно.
  2. Вы используете actionListener в своем h:commandButton вместо action - в этом случае это нормально, но знаете ли вы разница? Кроме того, вы можете удалить скобки внутри атрибута actionListener.
  3. После этого попробуйте использовать некоторые отладочные сообщения в incrementar, чтобы помочь вам найти проблему.
  4. Если вы используете функциональность ajax, вам необходимо обновить h:outputLabel внутри только что созданного файла h:outputPanel.

Так что просто:

<h:outputPanel id="myOutputPanel">
   ... your h:outputLabels here ...
</h:outputPanel>

<h:form id="formIncremento">
  <h:commandButton action="#{testeMBean.incrementar}" update=":myOutputPanel">
</h:form>

Но предоставленный код не использует никаких функций ajax. Это означает, что страницу необходимо перезагрузить (обновить или F5 в браузере), чтобы изменения отобразились. Это не будет хорошо работать с @ViewScopedbean, так как bean-компонент уничтожается после обновления страницы и создается сразу же после этого. либо вы должны использовать <f:ajax...> в своем h:commandButton, либо попытаться использовать какую-либо структуру, которая имеет встроенную функциональность, например p:commandButton Primefaces.

person Manuel    schedule 19.03.2013
comment
Спасибо за ответ, но у меня все еще есть некоторые вопросы. Я не мог заставить это работать, используя их пример. Я попытался поместить @ManagedProperty над переменной в базовом классе, а затем над новой созданной частной переменной с тем же именем в производном классе, используя #{testMBean.textoBase} или #{genericoTesteMBean.textoBase} и все еще не сохраняя значение . Что я могу сделать сейчас? - person Ronneery Teles; 19.03.2013
comment
Я добавил немного больше информации о вопросе, не знаю, изменится ли что-нибудь. большое спасибо - person Ronneery Teles; 19.03.2013
comment
@RonneeryTeles Я обновил свой ответ, увидев больше вашего кода. - person Manuel; 20.03.2013
comment
Разве outputPanel не является тегом Primefaces? Я пока не хочу добавлять первичные лица в проект... - person Ronneery Teles; 21.03.2013
comment
Справочник по тегам JSF. Возьмите то, что вам нравится (panelgrid, panelgroup). - person Manuel; 21.03.2013

Ваш абстрактный базовый класс должен реализовать Serializable, чтобы свойства передавались в запросах.

person Roost    schedule 06.06.2014