【问题标题】:Managed Bean with properties Inherited from a superclass具有从超类继承的属性的托管 Bean
【发布时间】:2013-03-08 11:16:01
【问题描述】:

在使用 ViewScope ManagedBeans 构建 JSF 项目时遇到问题。所以我决定将问题隔离为一个简单的代码,显然问题仍然存在。 基本上我意识到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;
    }
}

继承的 ManagedBean:

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;
    }
}

Web 表单:

<!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

【问题讨论】:

  • 我忘记在超类中发布“抽象”。现已更正。

标签: java jsf properties managed-bean view-scope


【解决方案1】:

只需将您的三个文件复制到我的工作区,“incrementar”就可以完美运行。

唯一的区别在于你的托管 bean,你有这个 @ManagedBean 注解的导入

import javax.annotation.ManagedBean;

改成

import javax.faces.bean.ManagedBean;

您可以阅读本文以了解 Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean 的概念

【讨论】:

  • 谢谢。我真的需要阅读足够的内容才能理解这些差异。我对 javax.faces.bean.ManagedBean 的注释进行了更改,即使这样,“A”也不会增加“AAAAA ...”。在你的测试中,这发生了?还有什么可能导致这种影响?
  • 除了导入之外,一切都是一样的,并且按设计工作。我建议在抽象类中的增量和方法上使用调试点。尝试为 jsf 使用最新的 jars,如果可能的话,使用 maven 并从 jsf 原型开始
【解决方案2】:

更新
看到您的问题后,删除了我的旧答案。

  1. 您的h:outputLabels 周围不需要h:form。只需在他们周围使用某种h:outputPanel 就足够了。
  2. 您在h:commandButton 中使用actionListener 而不是action - 在这种情况下没关系,但您知道difference 吗?此外,您可以删除actionListener 属性内的括号。
  3. 之后,尝试使用incrementar中的一些调试消息来帮助您找到问题。
  4. 如果您使用 ajax 功能,则需要更新新创建的 h:outputPanel 中的 h:outputLabels。

就这样:

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

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

但是提供的代码没有使用任何 ajax 功能。这意味着必须重新加载页面(refreshF5 在您的浏览器中)才能显示更改。这不适用于@ViewScopedbean,因为 bean 在页面刷新后被销毁并在之后立即创建。要么你应该在你的h:commandButton 中使用&lt;f:ajax...&gt;,要么尝试使用一些具有内置功能的框架,比如primefaces'p:commandButton

【讨论】:

  • 感谢您的回复,但我还有一些问题。我无法应用他们的例子。我尝试将@ManagedProperty 放在基类中的变量上方,然后使用“#{testMBean.textoBase}”或“#{genericoTesteMBean.textoBase}”将新创建的派生类中同名的私有变量放在上面,但仍然不保存价值。我现在能做什么?
  • 我补充了一点有问题的信息,不知道有什么变化。非常感谢
  • @RonneeryTeles 我在看到你的更多代码后更新了我的答案
  • outputPanel 不是 primefaces 标签吗?我还不想在项目中添加 primefaces...
  • JSF Tag Reference。拿你喜欢的东西(panelgrid、panelgroup)。
【解决方案3】:

您的抽象基类必须实现 Serializable 才能让属性在请求中传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2012-05-22
    • 2016-06-22
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多