Содержимое головы повторяется в теле
Я работаю над проектом в 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&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&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.
Я только что нашел очень хорошую дискуссию на эту тему в этом посте