如何解决 Target Unreachable, 'null'?
How to solve Target Unreachable, 'null'?
大家好我是 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
点击 link
<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)
...
但在 url 上显示:
http://localhost:8080/javaeesample/faces/details.xhtml?pid=1
- 当我点击 create.xhtml 中的 'Save' 按钮时,我收到以下错误消息:
发生错误:
/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 无效。
非常感谢任何帮助。
既然小小不想写答案,那我就写吧。这个答案的部分基础是他的评论,内容如下:
Target Unreachable,'null' returned null : Either #{personBean.person}
or #{personBean}
is null
. I smell person
is null
. You are trying to
pre-populate person inside the personDetails()
. Why do you initialize
person using <f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>
? You had better
pre-populate private Person person;
(and private List<Person> listPerson;
which you are lazily initializing inside a getter method
unnecessarily) at a better initialization place - inside a method
annotated with @PostConstruct
.
现在再解释一下
javax.el.PropertyNotFoundException: /create.xhtml @18,73 value="#{personBean.person.name}":
Target Unreachable, 'null' returned null
此错误意味着:“#{personBean.person}
或 #{personBean}
为空(见上文)。我完全支持 Tiny,假设 person
是罪魁祸首。
根本原因是,在您用于初始化 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 already mentioned in ), using a method annotated with @PostConstruct
,像这样:
@PostConstruct
public void initialize() {
this.person = (Person) personDao.findPerson(pid);
this.personList = personDao.listPerson();
}
大家好我是 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)
...
但在 url 上显示:
http://localhost:8080/javaeesample/faces/details.xhtml?pid=1
- 当我点击 create.xhtml 中的 'Save' 按钮时,我收到以下错误消息:
发生错误:
/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 无效。
非常感谢任何帮助。
既然小小不想写答案,那我就写吧。这个答案的部分基础是他的评论,内容如下:
Target Unreachable,'null' returned null : Either
#{personBean.person}
or#{personBean}
isnull
. I smellperson
isnull
. You are trying to pre-populate person inside thepersonDetails()
. Why do you initialize person using<f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>
? You had better pre-populateprivate Person person;
(andprivate List<Person> listPerson;
which you are lazily initializing inside a getter method unnecessarily) at a better initialization place - inside a method annotated with@PostConstruct
.
现在再解释一下
javax.el.PropertyNotFoundException: /create.xhtml @18,73 value="#{personBean.person.name}": Target Unreachable, 'null' returned null
此错误意味着:“#{personBean.person}
或 #{personBean}
为空(见上文)。我完全支持 Tiny,假设 person
是罪魁祸首。
根本原因是,在您用于初始化 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 already mentioned in @PostConstruct
,像这样:
@PostConstruct
public void initialize() {
this.person = (Person) personDao.findPerson(pid);
this.personList = personDao.listPerson();
}