JavaServerFaces2.0中的模板

JavaServerFaces2.0中的模板,java,templates,jsf-2,Java,Templates,Jsf 2,我第一次尝试在Eclipse中使用JSF2.0模板,但遇到了一些问题 原始的index.xhtml页面工作正常,当我点击一个按钮时,一切正常。但是,如果我更改索引页,使其使用模板文件,它将不再正常工作。修改后的index.xhtml页面如下: <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" template="/templates/mai

我第一次尝试在Eclipse中使用JSF2.0模板,但遇到了一些问题

原始的
index.xhtml
页面工作正常,当我点击一个按钮时,一切正常。但是,如果我更改索引页,使其使用模板文件,它将不再正常工作。修改后的
index.xhtml
页面如下:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  template="/templates/main-template.xhtml">
  <ui:define name="title">
    Simulator using JSF 2.0 - Test Version 2
  </ui:define> 
  <ui:define name="header">      
    Home Page of the Simulator using JSF 2.0 - Test Version 2
  </ui:define>
  <ui:define name="body">
    Click on the button to select the required option
    <h:outputText value="and login" rendered="#{!login.loggedIn}"/>
    <h:form prependId="false">   
      <h:commandButton value="Option 1" action="#{login.option1}"/>
      <h:commandButton value="Option 2" action="#{login.option2}"/>
      <h:commandButton value="Option 3" action="#{login.option3}"/>
      <h:commandButton value="Logout" disabled="#{!login.loggedIn}" action="#{login.logout}"/>
    </h:form>   
  </ui:define>
</ui:composition>
如果我删除index.xhtml中带有“h”标记的所有代码,文件将正确地拾取templates/main-template.xhtml中的代码,因此路径是正确的。然而,如果我像这里一样包含带有“h”标记的代码,Eclipse会抱怨标记无法识别,页面失败

如果我包括行
xmlns:h=”http://java.sun.com/jsf/html“
在顶部,Eclipse识别出“h”标记,页面正确呈现,但当我单击按钮时,应用程序失败,并返回错误:

javax.servlet.ServletException:javax.el.PropertyNotFoundException: /index.xhtml@15,68 action=“#{login.option1}”:无法访问目标, 标识符“login”解析为空

也许是因为某种原因,
xmlns:h=”http://java.sun.com/jsf/html“
在模板文件中会把事情弄得一团糟,但模板的整体思想是在模板文件中包含尽可能多的通用代码

有人知道发生了什么吗?解决办法是什么


web.xml
faces config.xml
都是标准的,不需要对它们做任何事情。

您关于模板应该如何工作的想法似乎是正确的,但是我们应该澄清一些要点。也许这会帮助你:

名称空间

关于名称空间,无论何时在页面中使用标记库,都应该声明它的名称空间。即使您正在使用模板并且已经在模板中声明了它们。如果有帮助的话,您可以认为名称空间声明不是继承的

在本例中,我看到您
index.xhtml
页面正在使用
h:commandButton
,但尚未声明其名称空间

豆子

对于要通过
EL
找到的bean,您应该具备以下条件:

@ManagedBean
javax.faces.bean.ManagedBean
包导入注释的类,如下所示:

import javax.faces.bean.ManagedBean;

@ManagedBean
@ViewScoped
public class Login 
{
    // ...
}
在这种情况下,您的bean应该按照约定通过
EL
通过名称
login
找到。(将类名的第一个字母去掉大写字母)

或者你可以给它起个名字:

import javax.faces.bean.ManagedBean;

@ManagedBean(name="login")
@ViewScoped
public class MyLoginBean
{
    // ...
}
在本例中,按照惯例,它将被称为
myLoginBean
,但我们给了它一个名称,在本例中是
login
,因此
EL
应该通过名称
login
找到它

如果您想使用CDI而不是普通的JSF,那么可以使用
@Named
注释来定义
EL
如何根据相同的命名约定找到bean

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;

@Named(value="login")
@RequestScoped
public class MyLoginBean
{
    // ...
}
请记住,要查找和更改
EL
的数据必须具有适当的getter和setter

提示

我建议您创建更简单的代码来测试函数性。在这种情况下,您可以先测试模板,然后测试bean、操作等


我希望这会有所帮助。

您关于模板应该如何工作的想法似乎是正确的,但我们需要澄清一些要点。也许这会帮助你:

名称空间

关于名称空间,无论何时在页面中使用标记库,都应该声明它的名称空间。即使您正在使用模板并且已经在模板中声明了它们。如果有帮助的话,您可以认为名称空间声明不是继承的

在本例中,我看到您
index.xhtml
页面正在使用
h:commandButton
,但尚未声明其名称空间

豆子

对于要通过
EL
找到的bean,您应该具备以下条件:

@ManagedBean
javax.faces.bean.ManagedBean
包导入注释的类,如下所示:

import javax.faces.bean.ManagedBean;

@ManagedBean
@ViewScoped
public class Login 
{
    // ...
}
在这种情况下,您的bean应该按照约定通过
EL
通过名称
login
找到。(将类名的第一个字母去掉大写字母)

或者你可以给它起个名字:

import javax.faces.bean.ManagedBean;

@ManagedBean(name="login")
@ViewScoped
public class MyLoginBean
{
    // ...
}
在本例中,按照惯例,它将被称为
myLoginBean
,但我们给了它一个名称,在本例中是
login
,因此
EL
应该通过名称
login
找到它

如果您想使用CDI而不是普通的JSF,那么可以使用
@Named
注释来定义
EL
如何根据相同的命名约定找到bean

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;

@Named(value="login")
@RequestScoped
public class MyLoginBean
{
    // ...
}
请记住,要查找和更改
EL
的数据必须具有适当的getter和setter

提示

我建议您创建更简单的代码来测试函数性。在这种情况下,您可以先测试模板,然后测试bean、操作等


我希望它能有所帮助。

StackOverflow不仅仅是一个论坛,它还是一个维基和博客。看,StackOverflow不仅仅是一个论坛,它还是一个wiki和一个博客。请参见导入javax.faces.bean.ManagedBean;非常感谢,但我想我已经正确地设置了bean(命名约定除外),如下:@ManagedBean(name=“login”)@SessionScoped公共类LoginBean实现了可序列化的{//getter、setter和private methods}对不起,这是我第一次尝试,我搞砸了如何添加注释。无论如何,我想说的是,我已经用您的第二个代码示例设置了我的bean,只是我将其命名为LoginBean并使用@SessionScoped。我有所有的getter和setter,在我将index.xhtml更改为使用模板文件之前,它工作正常;非常感谢,但我想我已经正确地设置了bean(命名约定除外),如下所示:@ManagedBean(name=“login”)@SessionScoped公共类LoginBean实现了Serializ