初始报错代码如下
package com.spring.servlet;
import com.alibaba.fastjson.JSONObject;
import com.spring.dao.BookDao;
import com.spring.pojo.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author:
* @className:BookServlet
* @description:
* @Date: Create in 18:09 2020/10/9
* @Version:
**/
@WebServlet("/book/bookServlet")
public class BookServlet extends BaseServlet{
@Autowired
private BookDao bookDao;
//为什么在web项目中获取不到spring ioc容器中的实例
//在此处,会进行报错,根据分析,报错原因如下:
//首先,Tomcat服务器启动时,会通过web.xml进行监听,对spring配置(applicationContext.xml)进行扫描,
//也就是对容器进行加载,而配置文件中,开启了注解扫描,当扫描到BookServlet时,就遇到了@Autowired,需要从容器中适配bean了
//而此时,容器都还没有加载成功,尚未对其中的bean进行实例化,所以@Autowired private BookDao bookDao;获得到的值为null
//因此就会报空指针异常(NullPointerException)
//解决方法:去掉注解,重写初始化方法
public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
System.out.println("========断点=======");
List<Book> bookList = bookDao.findAll();
Map<String,Object> map = new HashMap<>();
map.put("code",0);
map.put("msg","列表查询");
map.put("data",bookList);
//转换JSON格式
//java对象转换json对象
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
System.out.println("java对象转换JSON对象:" + jsonObject);
//将json格式的数据转换成json字符串
//JSONObject.toJsonString()
PrintWriter pw = response.getWriter();
pw.println("Hello");
}
}
报错如下:
type Exception report
message java.lang.reflect.InvocationTargetException
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
com.spring.servlet.BaseServlet.doPost(BaseServlet.java:44)
com.spring.servlet.BaseServlet.doGet(BaseServlet.java:20)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.reflect.InvocationTargetException
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
com.spring.servlet.BaseServlet.doPost(BaseServlet.java:41)
com.spring.servlet.BaseServlet.doGet(BaseServlet.java:20)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.NullPointerException
com.spring.servlet.BookServlet.list(BookServlet.java:47)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
com.spring.servlet.BaseServlet.doPost(BaseServlet.java:41)
com.spring.servlet.BaseServlet.doGet(BaseServlet.java:20)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
根据报错信息提示,在List booklist = bookDao.findAll();处报空指针异常,经断点检查,发现错误源于,bookDao为null。
该错误对于像我这样的spring新手而言,很摸不着头脑,spring配置也没问题,servlet层也没有明显错误。
<!--web.xml-->
<!--初始化spring容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
错误原因:在Tomcat服务器启动的时候,首先加载web.xml,初始化spring容器,在初始化spring容器时,第一句遇到
<context:component-scan base-package="com.spring"/>
对com.spring包中所有内容进行注解扫描,当扫描到BookServlet时,遇见
@Autowired
private BookDao bookDao;
这里已经开始从容器中取实例了,而此时spring容器尚未初始化完成,因此bookDao得到的就是null。
解决办法:
去掉注解@Autowired,重写init()初始化方法,如下:
private BookDao bookDao;
@Override
public void init() throws ServletException{
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
bookDao = (BookDao) webApplicationContext.getBean("bookDao");
}
成功运行~!
在记录自己学习中遇到的问题的同时,也希望能帮助有需要的伙伴~