1. 程式人生 > >Spring自動裝配報空指標異常

Spring自動裝配報空指標異常

這幾天在學Spring的自動裝配,自己動手做一個小專案,但是被一個空指標異常卡住了。

啟動的時候彈出index.jsp,這是一個登陸頁面:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv
="Content-Type" content="text/html; charset=utf-8">
<title>消費管理系統--首頁</title> <style type="text/css"> #surebtn{ align:center; } </style> <script type="text/javascript"></script> </head> <body> <h1>使用者登入</h1> <div> <form
action="UserServlet">
使用者名稱:<input id="username" type="text" name="nickname"/><br/> 密碼:<input id="password" type="password" name="password"><br/> <input type="hidden" name="action" value="login"> <input id="surebtn" type
="submit" value="登入">
<button onclick="#" id="regbtn">註冊</button> </form> </div> </body> </html>

跳轉到UserServlet:

package com.ffy.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.ffy.bean.User;
import com.ffy.service.UserService;
public class UserServlet extends HttpServlet{
    @Autowired
    private UserService userService;
    private static WebApplicationContext context;
    private String action=null;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        context=WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        userService=context.getBean(UserService.class);
        if(req.getParameter("action")!=null){
            action=req.getParameter("action");
            if("login".equals(action)){
                if(login(req,resp)!=null){
                    User user=login(req,resp);
                    req.getRequestDispatcher("/list.jsp?userId="+user.getId()).forward(req, resp);
                }else{
                    req.getRequestDispatcher("loginError.jsp").forward(req, resp);
                }
            }
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
    private User login(HttpServletRequest req,HttpServletResponse resp){
        User user=new User();
        user.setNickName(req.getParameter("nickname"));
        user.setPassword(req.getParameter("password"));
        User returnu=userService.login(user);
        if(returnu!=null){
            return returnu;
        }
        return null;
    }
}

若使用者名稱和密碼都正確,跳轉到list.jsp,一個賬單列表:

<%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.context.ApplicationContext"%>
<%@page import="javax.enterprise.context.spi.Context"%>
<%@page import="org.springframework.beans.factory.annotation.Autowired"%>
<%@page import="com.ffy.bean.Record"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.util.List" %>
<%@ page import="com.ffy.service.UserService" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<%


**UserService service=new UserService();**

    list=service.listRecordByUserId(Integer.parseInt(request.getParameter("userId")));
%>
<title>賬單</title>
</head>
<body>
    <h1>賬單</h1>
    <hr>
    <table>
        <tr>
            <td>編號</td>
            <td>金額</td>
            <td>型別</td>
            <td>日期</td>
            <td>描述</td>
        </tr>
        <%
            for(Record r:list){
        %>
            <tr>
                <td><%=r.getId() %></td>
                <td><%=r.getPrice() %></td>
                <td><%=r.getType().getName() %></td>
                <td><%=r.getDate() %></td>
                <td><%=r.getDescription() %></td>
            </tr>
        <%
            }
        %>
    </table>
</body>
</html>

注意加粗的那句話,這個list.jsp會呼叫UserService的listRecordByUserId(int userId)方法,具體如下:

package com.ffy.service;


import java.util.List;

import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ffy.bean.Record;
import com.ffy.bean.User;

@Service
@Transactional
public class UserService {
    @Autowired
    private HibernateManage hibernateManage;

    public HibernateManage getHibernateManage() {
        return hibernateManage;
    }
    public void setHibernateManage(HibernateManage hibernateManage) {
        this.hibernateManage = hibernateManage;
    }
    public User login(User user){
        System.out.println("login........");
        Session session=hibernateManage.getSession();
        Query<User>query=session.createQuery("from User where nickname=:nickname and password=:password",User.class);
        query.setParameter("nickname",user.getNickName());
        query.setParameter("password", user.getPassword());
        if(query.getResultList().size()>0){
            return query.getResultList().get(0);
        }
        return null;
    }
    public List<Record> listRecordByUserId(int userId){
        if(hibernateManage==null){
            System.out.println("null-----------------------");
        }
        **Session session=hibernateManage.getSession();**
        Query<Record> q=session.createQuery("from Record r,User u where r.id=r.user.id",Record.class);
        List<Record> list=q.getResultList();
        return list;
    }
}

這個時候加粗的那句話就報空指標了,這是因為我在list.jsp直接new了一個UserService,直接new的話那這個UserService的例項service就不歸spring管了,spring是不會自動裝配UserService裡面hibernateManage,所以報了空指標異常。只要將list.jsp裡的UserService service=new UserService();改成ApplicationContext context=WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
UserService service=context.getBean(UserService.class);就可以了。

<%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.context.ApplicationContext"%>
<%@page import="javax.enterprise.context.spi.Context"%>
<%@page import="org.springframework.beans.factory.annotation.Autowired"%>
<%@page import="com.ffy.bean.Record"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.util.List" %>
<%@ page import="com.ffy.service.UserService" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<%
    ApplicationContext context=WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
    UserService service=context.getBean(UserService.class);
    List<Record> list=service.listRecordByUserId(Integer.parseInt(request.getParameter("userId")));
%>
<title>賬單</title>
</head>
<body>
    <h1>賬單</h1>
    <hr>
    <table>
        <tr>
            <td>編號</td>
            <td>金額</td>
            <td>型別</td>
            <td>日期</td>
            <td>描述</td>
        </tr>
        <%
            for(Record r:list){
        %>
            <tr>
                <td><%=r.getId() %></td>
                <td><%=r.getPrice() %></td>
                <td><%=r.getType().getName() %></td>
                <td><%=r.getDate() %></td>
                <td><%=r.getDescription() %></td>
            </tr>
        <%
            }
        %>
    </table>
</body>
</html>

唉,因為這個查了好久,對於大牛來說這種問題太low了,但是對於我這種還沒畢業的小白來說實在是一個挺難的問題了,在這裡記錄一下。