【问题标题】:JSF Stack exception or managed bean troubleJSF Stack 异常或托管 bean 问题
【发布时间】:2013-10-11 18:18:20
【问题描述】:

我对 JSF 非常陌生,并且在过去一个小时左右一直在努力让它工作。

我正在处理的这个示例程序应该显示一个网页,上面有几种不同的形式。它做得很好(因为它至少可以工作,我真的不知道语法有多正确),现在我使用托管 bean 为表单实现了一些功能。目标是让页面显示用户在下面输入的内容以显示它已通过,但似乎存在某种我无法弄清楚的 **config.xml 问题,因为我在 netbeans 中创建的项目没有任何类型的 config.xml 文件,它只有一个 beans.xml 文件和一个 web.xml 文件。我不确定我需要向 beans.xml 文件添加什么(如果有的话),或者我是否需要自己创建一个新的 xml 文件,或者它是完全不同的东西。

我还应该提到,当我运行这个程序时,GUI 部分会运行,我可以在框中输入内容并检查单选框等,但是当我点击“注册”按钮时,什么也没有发生

这是我的文件。

index.xhtml

       <?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
  <h:head>
    <title>Student Registration Form</title>
  </h:head>
  <h:body>
    <h:form>
      <!-- Use h:graphicImage -->
      <h3>Student Registration Form
        <h:graphicImage name="usIcon.gif" library="image"/>
      </h3>

      <!-- Use h:panelGrid -->
      <h:panelGrid columns="6" style="color:green">
        <h:outputLabel value="Last Name"/>
        <h:inputText id="lastNameInputText" 
                     value="#{Registration.lastName}"/>
        <h:outputLabel value="First Name" />
        <h:inputText id="firstNameInputText" 
                     value="#{Registration.firstName}"/>
        <h:outputLabel value="MI" />
        <h:inputText id="miInputText" size="1"
                     value="#{Registration.mi}"/>
      </h:panelGrid>

      <!-- Use radio buttons -->
      <h:panelGrid columns="2">
        <h:outputLabel>Gender  </h:outputLabel>           
        <h:selectOneRadio id="genderSelectOneRadio"
                          value="#{Registration.gender}">
          <f:selectItem itemValue="Male" 
                        itemLabel="Male"/>
          <f:selectItem itemValue="Female" 
                        itemLabel="Female"/>
        </h:selectOneRadio>
      </h:panelGrid>

      <!-- Use combo box and list -->
      <h:panelGrid columns="4">
        <h:outputLabel value="Major  "/>
        <h:selectOneMenu id="majorSelectOneMenu"
                         value="#{Registration.major}">
          <f:selectItem itemValue="Computer Science"/>
          <f:selectItem itemValue="Mathematics"/>
        </h:selectOneMenu> 
        <h:outputLabel value="Minor  "/>
        <h:selectManyListbox id="minorSelectManyListbox"
                             value="#{Registration.minor}">
          <f:selectItem itemValue="Computer Science"/>
          <f:selectItem itemValue="Mathematics"/>
          <f:selectItem itemValue="English"/>
        </h:selectManyListbox> 
      </h:panelGrid>

      <!-- Use check boxes -->
      <h:panelGrid columns="4">
        <h:outputLabel value="Hobby: "/>
        <h:selectManyCheckbox id="hobbySelectManyCheckbox"
                              value="#{Registration.hobby}">
          <f:selectItem itemValue="Tennis"/>
          <f:selectItem itemValue="Golf"/>
          <f:selectItem itemValue="Ping Pong"/>
        </h:selectManyCheckbox>
      </h:panelGrid>

      <!-- Use text area -->
      <h:panelGrid columns="1">
        <h:outputLabel>Remarks:</h:outputLabel>  
        <h:inputTextarea id="remarksInputTextarea" 
                         style="width:400px; height:50px;" 
                         value="#{Registration.remarks}"/>
      </h:panelGrid>

      <!-- Use command button -->
      <h:commandButton value="Register" />
      <br />
      <h:outputText escape="false" style="color:red"
                    value="#{Registration.response}" />
    </h:form>
  </h:body>
</html>

注册.java

    package jsf2demo;

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean
@javax.faces.bean.RequestScoped

public class Registration {
  private String lastName;
  private String firstName;
  private String mi;
  private String gender;
  private String major;
  private String[] minor;
  private String[] hobby;
  private String remarks;

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getMi() {
    return mi;
  }

  public void setMi(String mi) {
    this.mi = mi;
  }

  public String getGender() {
    return gender;
  }

  public void setGender(String gender) {
    this.gender = gender;
  }

  public String getMajor() {
    return major;
  }

  public void setMajor(String major) {
    this.major = major;
  }

  public String[] getMinor() {
    return minor;
  }

  public void setMinor(String[] minor) {
    this.minor = minor;
  }

  public String[] getHobby() {
    return hobby;
  }

  public void setHobby(String[] hobby) {
    this.hobby = hobby;
  }

  public String getRemarks() {
    return remarks;
  }

  public void setRemarks(String remarks) {
    this.remarks = remarks;
  }

  public String getResponse() {
    if (lastName == null)
      return ""; // Request has not been made
    else {
      String allMinor = "";
      for (String s: minor) {
        allMinor += s + " ";
      }

      String allHobby = "";
      for (String s: hobby) {
        allHobby += s + " ";
      }

      return "<p style=\"color:red\">You entered <br />" + 
         "Last Name: " + lastName + "<br />" + 
         "First Name: " + firstName + "<br />" + 
         "MI: " + mi + "<br />" +
         "Gender: " + gender + "<br />" + 
         "Major: " + major + "<br />" + 
         "Minor: " + allMinor + "<br />" + 
         "Hobby: " + allHobby + "<br />" + 
         "Remarks: " + remarks + "</p>"; 
    }
  }
}

【问题讨论】:

  • 你的按钮既没有动作也没有actionListener。我认为您必须绑定一个方法才能在用户单击按钮时运行。

标签: xml jsf managed-bean


【解决方案1】:

JSF 框架的目标之一是支持“MVC”架构,这就是为什么它提供了如此多的功能和技术来阐述 MVC 原则。这就是为什么不强烈建议将视图与控制器层混合在一起的原因,因此您应该将这两层分开,因为每一层都有其特殊的作用。 首先,如果您使用的是 JSF 2.X 版本,则不应添加/修改任何其他 xml 文件。 为了说明您的示例中的注册过程,您可以例如在名为result.xhtml 的第二个简单页面中显示注册填写信息。首先将 getResponse() 方法替换为 response() 内容:

public String response(){
    return "result?faces-redirect=true";
}

通过上述方法提供的结果字符串可以简单地写成return "result";,这样浏览器栏中的URI地址在转发到目标页面时不会改变。否则,如果字符串(页面名称)后跟faces-redirect=true,如示例,则URI地址将更改,并且目标名称也会显示在浏览器地址栏中。

另请参阅
JSF 中转发和重定向的区别:http://www.mkyong.com/jsf2/jsf-page-forward-vs-page-redirect/

然后,在index.xhtml 中,您在示例中创建了没有action 必要属性的&lt;h:commandButton /&gt;,因此您应该将最后一部分替换为:

<h:commandButton value="Register" style="color:red" action="#{Registration.response()}" />

当然,您还应该省略index.xhtml 中的最后一个&lt;h:outputText /&gt; 标记。

最后,新建页面result.xhtml显示注册信息:

<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">
<head>
    <title>Registration informations</title>
</head>
<body>

    <h2>Your registration informations :</h2>

    <h:outputText value="Last name : #{Registration.lastName }" /><br />
    <h:outputText value="First name : #{Registration.firstName }" /><br />
    <h:outputText value="MI : #{Registration.mi}" /><br />
    ...

</body>
</html>

【讨论】:

  • 出于学习目的,我将发布response 方法的两个实现:一个简单地返回"result",另一个返回"result?faces-redirect=true",并解释两者之间的差异或指向一个链接对此进行了介绍和解释。除此之外,很好的答案。
【解决方案2】:

尝试改变:

@javax.faces.bean.RequestScoped

@RequestScoped

更多可以看this@BalusC 的回答。

【讨论】:

  • 他已经将这两个都导入了,但他实际上只是使用 Faces 注释(ManagedBeanRequestScoped)所以他应该好的,我想这里。也就是说,最好不要同时导入它们,并消除可能的歧义。
猜你喜欢
  • 2015-03-11
  • 1970-01-01
  • 2011-05-16
  • 2011-06-22
  • 2023-03-05
  • 2012-03-24
  • 2012-08-27
  • 2016-07-09
  • 2012-10-13
相关资源
最近更新 更多