JavaServer Faces 2.0中的模板

时间:2012-10-14 16:35:02

标签: java templates jsf-2

我第一次尝试使用带有Eclipse的JSF 2.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>

,模板文件main.template.xhtml位于子文件夹模板中,位于:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"  
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>
      <ui:insert name="title">Title</ui:insert>
    </title>
  </h:head>      
  <h:body>
    <ui:insert name="header">Header</ui:insert>
    <br/>
    We are in template.xhtml
    <br/>
    <ui:insert name="body">Body</ui:insert>
  </h:body>
</html>

如果我使用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'已解析为null

也许某种程度上模板文件中的行xmlns:h="http://java.sun.com/jsf/html"搞砸了,但模板的整个想法是在模板文件中包含尽可能多的公共代码。

有没有人知道发生了什么,以及解决方案是什么?

web.xmlfaces-config.xml是标准配置,并且不认为必须对它们进行任何操作。

1 个答案:

答案 0 :(得分:1)

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

<强>命名空间

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

在这种情况下,我看到您index.xhtml页面正在使用h:commandButton,但尚未声明其名称空间。

<强>豆

对于EL找到的bean,您应该具有以下内容:

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

import javax.faces.bean.ManagedBean;

@ManagedBean
@ViewScoped
public class Login 
{
    // ...
}

在这种情况下,按照惯例,EL的名称login应该找到您的bean。 (给你的班级名字的第一个字母取消资本)

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

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,操作等......

我希望它有所帮助。

相关问题