大家好我是javaweb的新手,我尝试创建我的第一个javaweb项目,当然是通过一些教程。但是当一些动作被调用时,我收到了一个错误。有人可以帮忙!这是我做的:
Person.java
package org.javaeesample.entities;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person implements Serializable {
@Id @GeneratedValue
private Long id;
private String name;
private int age;
public Person(){
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
PersonEjbDao.java
package org.javaeesample.ejbdao;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.javaeesample.entities.Person;
@Stateless
public class PersonEjbDao {
@PersistenceContext
EntityManager em;
//private Person pers;
public List<Person> listPerson(){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> person = cq.from(Person.class);
cq.select(person);
return em.createQuery(cq).getResultList();
}
public Person findPerson(long pid){
return em.find(Person.class, pid);
}
public void createPerson(Person pers){
Person p = new Person();
p.setName(pers.getName());
p.setAge(pers.getAge());
em.persist(p);
}
}
FriendBean.java
package org.javaeesample.jsf;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.javaeesample.ejbdao.PersonEjbDao;
import org.javaeesample.entities.Person;
@Named(value = "personBean")
@RequestScoped
public class PersonBean {
private Person person;
private Long pid;
private List<Person> listPerson;
@Inject
PersonEjbDao personDao;
public List<Person> getPersons(){
if (listPerson==null) {
listPerson = personDao.listPerson();
}
return listPerson;
}
public void personDetails(){
person = new Person();
person = (Person) personDao.findPerson(pid);
}
public void createPerson(){
personDao.createPerson(person);
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
}
show.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<body>
<ui:composition template="./WEB-INF/template.xhtml">
<ui:define name="content">
<h:form>
<h:dataTable value="#{personBean.persons}" var="p">
<h:column>
<f:facet name="header">Name</f:facet>
<h:link value="#{p.name}" outcome="details">
<f:param name="pid" value="#{p.id}"/>
</h:link>
</h:column>
<h:column>
<f:facet name="header">Age</f:facet>
#{p.age}
</h:column>
</h:dataTable>
<h:commandButton id="create" action="create" value="Create"/>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
create.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<body>
<ui:composition template="./WEB-INF/template.xhtml">
<ui:define name="content">
<h:form>
<h:panelGrid columns="3"
captionClass="rightalign,leftalign,leftalign">
<h:outputLabel value="Name:" for="name"/>
<h:inputText id="name" label="Name"
required="true"
value="#{personBean.person.name}"/>
<h:message for="name"/>
<h:outputLabel value="Age:" for="age"/>
<h:inputText id="age" label="Age"
size="2"
value="#{personBean.person.age}"/>
<h:message for="age"/>
<h:commandButton id="save" value="Save"
action="list" actionListener="#{personBean.createPerson}"/>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
details.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<body>
<ui:composition template="./WEB-INF/template.xhtml">
<ui:define name="content">
<f:metadata>
<f:viewParam name="pid" value="#{personBean.pid}"/>
<f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>
</f:metadata>
<h:form>
<h:panelGrid columns="2"
columnClasses="rightalign,leftalign,leftalign">
<h:outputText value="Name:"/>
<h:outputText value="#{personBean.person.name}" />
<h:outputText value="Age:"/>
<h:outputText value="#{personBean.person.age}"/>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
当试图运行我的项目时发生的事情是:
1.当我点击show.xhtml
<h:link value="#{p.name}" outcome="details">
<f:param name="pid" value="#{p.id}"/>
</h:link>
它说: java.lang.NullPointerException
java.lang.NullPointerException
at org.javaeesample.jsf.PersonBean.personDetails(PersonBean.java:37)
at org.javaeesample.jsf.PersonBean$Proxy$_$$_WeldClientProxy.personDetails(Unknown Source)
...
但在网址上显示:
http://localhost:8080/javaeesample/faces/details.xhtml?pid=1
发生错误:
/create.xhtml @18,73 value="#{personBean.person.name}": Target Unreachable,'null' returned null
我展开Stack Trace并显示
javax.el.PropertyNotFoundException: /create.xhtml @18,73 value="#{personBean.person.name}": Target Unreachable, 'null' returned null
at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)
我不知道是什么让我的personBean.person.name为null。
非常感谢任何帮助。
答案 0 :(得分:0)
由于Tiny似乎不想写答案,我会这样做。这个答案的基础部分是他的评论:
目标无法访问,&#39; null&#39;返回null:
#{personBean.person}
或#{personBean}
是null
。我闻到person
是null
。你正试图 预先填充personDetails()
内的人。为什么要初始化 使用<f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>
的人?你最好 预先填充private Person person;
(和private List<Person> listPerson;
,您在getter方法中懒得初始化 不必要地)在更好的初始化位置 - 在方法内部 用@PostConstruct
注释。
现在对此有更多解释
javax.el.PropertyNotFoundException: /create.xhtml @18,73 value="#{personBean.person.name}": Target Unreachable, 'null' returned null
此错误表示:&#34; #{personBean.person}
或#{personBean}
为空(请参见上文)。假设person
是罪魁祸首,我完全和Tiny在一起。
这个的根本原因是,在用于初始化Person运行的侦听器时,xhtml文件已经被完全解析。在您的听众有机会更改person
之前,应该已经访问过它的属性。
这会导致您的错误。解决这个问题的方法很简单:
不要让person
为空。
使用急切初始化可以防止这种情况,并使PersonBean看起来如下:
@RequestScoped
public class PersonBean {
private Person person = new Person();
private Long pid = 0l;
private List<Person> listPerson = new ArrayList<>();
// carry on with your code from here
这允许您删除getter中的延迟初始化部分,并且应该解决您的问题。
替代方法是(Tiny中已经提到his comment),使用注释为@PostConstruct
的方法,如下所示:
@PostConstruct
public void initialize() {
this.person = (Person) personDao.findPerson(pid);
this.personList = personDao.listPerson();
}