【发布时间】:2016-03-17 10:15:19
【问题描述】:
我正在尝试从 URL 将星座读取为 JSON,然后将其保存到我的数据库中,我正在使用 JSF 2.2。
我得到空指针异常:
java.lang.NullPointerException
at com.horoskop.android.controlor.HoroscopeBean.saveTodayHoroscope(HoroscopeBean.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.el.ELUtil.invokeMethod(ELUtil.java:332)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:537)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
at com.sun.el.parser.AstValue.getValue(AstValue.java:136)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
这是 ManagedBean 代码:
@ManagedBean
@ApplicationScoped
public class HoroscopeBean {
HoroscopeParser horoscopeParser;
@Inject
HoroscopeEJB horoscopeEJB;
public void saveTodayHoroscope() throws Exception{
HoroscopeFeed horoscope = getTodayHoroscope();
for(int i=0;i<horoscope.getHoroscope().size();i++){
Day d = new Day();
d.setText(horoscope.getHoroscope().get(i).getTxtHrs());
horoscopeEJB.addTodayHoroscope(d);
}
}
public void saveLoveHoroscope() throws Exception{
HoroscopeFeed horoscope = getLoveHoroscope();
for(int i=0;i<horoscope.getHoroscope().size();i++){
Love l = new Love();
l.setText(horoscope.getHoroscope().get(i).getTxtHrs());
horoscopeEJB.addLoveHoroscope(l);
}
}
public void saveWeekHoroscope() throws Exception{
HoroscopeFeed horoscope = getWeekHoroscope();
for(int i=0;i<horoscope.getHoroscope().size();i++){
Week w = new Week();
w.setText(horoscope.getHoroscope().get(i).getTxtHrs());
horoscopeEJB.addWeekHoroscope(w);
}
}
public void saveMonthHoroscope() throws Exception{
HoroscopeFeed horoscope = getMonthHoroscope();
for(int i=0;i<horoscope.getHoroscope().size();i++){
Month m = new Month();
m.setText(horoscope.getHoroscope().get(i).getTxtHrs());
horoscopeEJB.addMonthHoroscope(m);
}
}
public HoroscopeFeed getTodayHoroscope() throws Exception{
horoscopeParser = new HoroscopeParser();
return horoscopeParser.getTodayHoroscope(URL);
}
public HoroscopeFeed getWeekHoroscope() throws Exception{
horoscopeParser = new HoroscopeParser();
return horoscopeParser.getTodayHoroscope(URL);
}
public HoroscopeFeed getLoveHoroscope() throws Exception{
horoscopeParser = new HoroscopeParser();
return horoscopeParser.getTodayHoroscope(URL);
}
public HoroscopeFeed getMonthHoroscope() throws Exception{
horoscopeParser = new HoroscopeParser();
return horoscopeParser.getTodayHoroscope(URL);
}
EJB 代码:
@Stateless
@LocalBean
public class HoroscopeEJB {
@PersistenceContext
EntityManager em;
public void addTodayHoroscope(Day day){
boolean ifExist = checkDaily(day.getText());
if(!ifExist){
em.merge(day);
}
}
public void addLoveHoroscope(Love love){
boolean ifExist = checkLove(love.getText());
if(!ifExist){
em.merge(love);
}
}
public void addWeekHoroscope(Week week){
boolean ifExist = checkWeek(week.getText());
if(!ifExist){
em.merge(week);
}
}
public void addMonthHoroscope(Month month){
boolean ifExist = checkMonth(month.getText());
if(!ifExist){
em.merge(month);
}
}
private boolean checkDaily(String text){
List<Day> results = em.createQuery("SELECT d FROM Da d WHERE d.text = :text")
.setParameter("text", text).getResultList();
if(results.size() > 0){
return true;
} else{
return false;
}
}
private boolean checkLove(String text){
List<Love> results = em.createQuery("SELECT k FROM Love l WHERE l.text = :text")
.setParameter("text", text).getResultList();
if(results.size() > 0){
return true;
} else{
return false;
}
}
private boolean checkWeek(String text){
List<Week> results = em.createQuery("SELECT w FROM Week d WHERE w.text = :text")
.setParameter("text", text).getResultList();
if(results.size() > 0){
return true;
} else{
return false;
}
}
private boolean checkMonth(String text){
List<Month> results = em.createQuery("SELECT m FROM Month m WHERE m.text = :text")
.setParameter("text", text).getResultList();
if(results.size() > 0){
return true;
} else{
return false;
}
}
}
这是星座解析器代码,我在其中连接到另一个 URL 并读取 JSON,然后对其进行解析。
public class HoroscopeParser {
public HoroscopeFeed getTodayHoroscope(String url) throws Exception{
String content = readUrl(url);
Gson gson = new Gson();
return gson.fromJson(content, HoroscopeFeed.class);
}
public HoroscopeFeed getLoveHoroscope(String url) throws Exception{
String content = readUrl(url);
Gson gson = new Gson();
return gson.fromJson(content, HoroscopeFeed.class);
}
public HoroscopeFeed getWeekHoroscope(String url) throws Exception{
String content = readUrl(url);
Gson gson = new Gson();
return gson.fromJson(content, HoroscopeFeed.class);
}
public HoroscopeFeed getMonthHoroscope(String url) throws Exception{
String content = readUrl(url);
Gson gson = new Gson();
return gson.fromJson(content, HoroscopeFeed.class);
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
}
更新:
如果我更改为 @EJB 而不是 @Inject 我会收到此错误:
javax.ejb.EJBException
at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:748)
at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:698)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:503)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy233.addTodayHoroscope(Unknown Source)
at com.horoskop.android.controlor.__EJB31_Generated__HoroscopeEJB__Intf____Bean__.addTodayHoroscope(Unknown Source)
at com.horoskop.android.controlor.HoroscopeBean.saveTodayHoroscope(HoroscopeBean.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.el.ELUtil.invokeMethod(ELUtil.java:332)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:537)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
at com.sun.el.parser.AstValue.getValue(AstValue.java:136)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.ELText$ELTextVariable.writeText(ELText.java:238)
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
【问题讨论】:
-
当 HoroscopeBean 不是 CDI 托管 bean 时,Inject 是否还能工作?从来没有真正尝试过。
-
我没有 beans.xml 文件。我添加了 web.xml 的代码。我使用 Glassfish 4.1.0 作为应用服务器,MySQL 作为数据库,其余的是在 NetBeans 中创建的 Web 应用程序。
-
请附上您的进口声明。我怀疑您使用的是来自 JSF 的
@ApplicationScoped,但要启用 CDI,您需要使用 CDI 的应用范围。 -
我尝试了从 JSF 和 javax.enterprise.context.ApplicationScoped 的两种导入,但它仍然不起作用。我不知道为什么:(
-
也许主要问题是我同时从 4 个 URL 地址读取 JSON,并且可能有些他们没有完成 JSON 的读取和解析,我尝试将其保存到数据库并且它们是空的。我怎么能等待完成所有这些的读取和解析,然后将其保存到数据库中?
标签: jsf jakarta-ee nullpointerexception ejb cdi