Содержимое головы повторяется в теле

Я работаю над проектом в Java EE с JSF и Primefaces. Я также использую Hibernate в качестве платформы ORM. На мой взгляд, Primefaces и Hibernate не мешают, но я упоминаю об этом, чтобы вы могли получить полную картину. У меня есть логин и страница регистрации. Оба являются клиентами шаблонов Facelets, и вы переходите с первого на второй. Страница регистра связана с 2 свойствами управляемого объекта и вызывает метод из первого. MCVE будет:

index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
  <body>
    <ui:composition template="./templates/mainTemplate.xhtml">
      <ui:define name="top"></ui:define>

      <ui:define name="content">
        <h:form>
          <h2>Login</h2>
            <h:panelGrid columns="2">
              <h:outputLabel for="user" value="User:" />
              <p:inputText id="user"/>
              <h:outputLabel for="password" value="Password:" />
              <p:password id="password"/>

              <!-- Still no connection to the Login's MB -->
              <p:commandButton value="Login"/>

              <!-- Go to register.xhtml -->
              <p:commandButton value="Register" action="register"/>
            </h:panelGrid>
          </h:form>
      </ui:define>

      <ui:define name="bottom">bottom</ui:define>
    </ui:composition>
  </body>
</html>

register.xhtml

<!--ui:composition nested in html and body as in index.xhtml-->
<ui:composition template="./templates/mainTemplate.xhtml">
  <ui:define name="top"></ui:define>

  <ui:define name="content">
    <h:form id="frmRegister">
      <h:panelGrid columns="2">
        <h:outputLabel for="name" value="Name:" />
        <p:inputText id="name" label="Name" required="true" size="50" 
                     value="#{personBean.person.name}"/>

        <h:outputLabel for="birthdate" value="Date of birth:" />
        <p:calendar id="birthdate" 
                    label="Date of birth"
                    placeholder="dd/mm/aaaa"
                    required="true"
                    value="#{personBean.person.birthdate}"/>

        <h:outputLabel for="password" value="Password(*):"/>
        <p:password id="password" label="Password" required="true" size="30"
                    value="#{userBean.user.password}"/>

        <h:outputLabel for="password-repeat" value="Repeat your password(*):"/>
        <p:password id="password-repeat" label="Repeated password" required="true" size="30"
                    value="#{userBean.repeatPassword}"/>

        <p:commandButton value="Register User" actionListener="#{personBean.addPerson()}"/>
        <p:commandButton value="Back" action="index" />
      </h:panelGrid>
    </h:form>
  </ui:define>

  <ui:define name="bottom">bottom</ui:define>
</ui:composition>

mainTemplate.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

  <h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <h:outputStylesheet name="./css/default.css"/>
    <h:outputStylesheet name="./css/cssLayout.css"/>
    <h:outputStylesheet name="./css/libs/bootstrap.min.css"/>
    <h:outputStylesheet name="./css/libs/bootstrap-theme.min.css"/>
    <title>Title</title>
  </h:head>

  <h:body>
    <div id="top">
      <ui:insert name="top">Top</ui:insert>
      <h1>A Test</h1>
    </div>

    <div id="content" class="center_content">
      <ui:insert name="content">Content</ui:insert>
    </div>

    <div id="bottom">
      <ui:insert name="bottom">Bottom</ui:insert>
    </div>

Проблема в том, что когда я пытаюсь загрузить страницу, я получаю пустую страницу, и когда я открываю инструменты разработчика Chrome, я вижу, что тело отображается с той же информацией, что и голова. Чтобы получить картину:

<head>
  <link type="text/css" rel="stylesheet" href=".../theme.css?ln=primefaces-bootstrap">
  ...
  <script type="text/javascript" src="...jquery.js?ln=primefaces&amp;v=5.0"></script>
  ...
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>THE TITLE</title>
  <link rel="icon" href="resources/img/favicon.ico">
</head>

<body>
  <link type="text/css" rel="stylesheet" href=".../theme.css?ln=primefaces-bootstrap">
  ...
  <script type="text/javascript" src="...jquery.js?ln=primefaces&amp;v=5.0"></script>
  ...
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>THE TITLE</title>
  <link rel="icon" href="resources/img/favicon.ico">
  <div id="textarea_simulator" style="position: absolute; top: 0px; left: 0px; visibility: hidden;"></div>
</body>

И консоль выдает мне следующую ошибку:

[Warning] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
[Error] Uncaught TypeError: Cannot read property 'debug' of undefined

Как видите, это то же самое, за исключением <div id="textarea_simulator"> элемент. Когда я закрываю ссылки на личные свойства МБ, страницы работают нормально (я имею в виду удаление value=#{} в <p:inputText /> элемент).

В соответствии с видеоуроком, предложенным в вики JSF, и документацией по Java EE (гл. 8.4 Использование шаблона Facelets, стр. 136), когда у вас есть ui:composition тег (который является клиентом шаблона Facelets), все снаружи игнорируется. Из-за этого я попытался поместить определение пространства имен XML в этот тег для index а также register, но результат тот же.

Мои Управляемые Бобы следующие:

personBean.java

@ManagedBean
@RequestScoped
public class PersonBean {
    @ManagedProperty("#{userBean}")
    private UserBean userBean;
    private Person person;

    //Empty constructor, getter/setter

    public void addPerson(){
        //In a try/catch block: open connection, make query with prepared statement and commit
    }  
}

userBean.java

@ManagedBean
@RequestScoped
public class UserBean {
    private User user;
    private String repeatPassword;

    //Constructor, getters and setters
}

В заключение, Person а также User POJO со свойствами, геттерами и сеттерами (без конструктора) Я что-то упустил? В чем моя ошибка?

Я работаю с Netbeans 8.0.2 и с Glasfish Sever 4.1. Любая помощь очень ценится. Заранее спасибо.

Заметка

Сервер Glassfish выдает мне следующее сообщение:

SEVERE: JSF cannot create the managed bean personBean when it is required. Following errors have been found:
    - The property userBean does not exists for the managed bean personBean

(Я перевожу с испанского, поэтому сообщение может отличаться от того, которое вы можете получить). Я изменился @ManagedProperty("#{userBean}") за @ManagedProperty("#{UserBean}") (в верхнем регистре), но результат тот же.

1 ответ

Решение

Понял. Вместо того, чтобы использовать @ManagedProperty аннотирование

import javax.faces.bean.ManagedProperty;
...
    @ManagedProperty("#{userBean}")
    private UserBean userBean;

Я использовал @Inject аннотирование

import javax.inject.Inject;
...
    @Inject private UserBean userBean;

И теперь оказывает отлично. Решение вышло из Руководства по Java EE, выпуск 7, глава 23.7.- Injecting Beans, стр. 23.6 (400).

Я видел другие уроки / примеры использования @ManagedProperty и работает нормально, но по какой-то причине здесь не работает. На самом деле, я искал в упомянутом учебнике, и нет ссылки на @ManagedProperty, но это задокументировано в Java EE API.

Я только что нашел очень хорошую дискуссию на эту тему в этом посте

Другие вопросы по тегам