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位于子文件夹 templates 中,在这里:

<?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}": Target Unreachable, identifier 'login' resolve to null

也许xmlns:h="http://java.sun.com/jsf/html"模板文件中的那一行搞砸了,但模板的整个想法是在模板文件中包含尽可能多的通用代码。

有谁知道发生了什么,解决方案是什么?

web.xml和是标准的faces-config.xml,不要认为必须对它们做任何事情。

4

1 回答 1

1

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

命名空间

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

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

豆子

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

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

import javax.faces.bean.ManagedBean;

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

在这种情况下,按照约定,您的 bean 应该EL通过 name找到。login(将班级名称的第一个字母大写)

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

import javax.faces.bean.ManagedBean;

@ManagedBean(name="login")
@ViewScoped
public class MyLoginBean
{
    // ...
}

在这种情况下,按照惯例,它会被调用myLoginBean,但我们给了它一个名字,在这种情况下loginEL应该通过 name 找到它login

如果你想使用 CDI 而不是普通的 JSF,你可以使用@Named注解来定义你的 bean 应该如何被找到EL,遵循相同的命名约定。

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

@Named(value="login")
@RequestScoped
public class MyLoginBean
{
    // ...
}

请记住,您要EL查找和更改的数据必须具有正确的 getter 和 setter。

暗示

我建议您创建更简单的代码以测试功能。在这种情况下,您可以先测试模板,然后再测试 bean、动作等...

我希望它有所帮助。

于 2012-10-14T16:55:57.937 回答