-2

这是一个 addBook.jsp 单击编辑时,它会抛出空指针异常

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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=ISO-8859-1">
        <title>Spring MVC Form Handling</title>
    </head>
    <body>
        <h2>Add booK Data</h2>
        <form:form method="POST" action="/sdnext/save.html">
            <table>
                <tr>
                    <td><form:label path="bookCode">Book Code:</form:label></td>
                    <td><form:input path="bookCode" value="${book.bookCode}" readonly="true"/></td>
                </tr>
                <tr>
                    <td><form:label path="bookName">Book Name:</form:label></td>
                    <td><form:input path="bookName" value="${book.bookName}" /></td>
                </tr>
                <tr>
                    <td><form:label path="author">Book Author Name:</form:label></td>
                    <td><form:input path="author" value="${book.author}"/></td>
                </tr>
                <tr>
                    <td><form:label path="dateOfArrival">Date Of Arrival:</form:label></td>
                    <td><form:input path="dateOfArrival" value="${book.dateOfArrival}"/></td>
                </tr>   
                <tr>
                    <td><form:label path="price">Price Of Book:</form:label></td>
                    <td><form:input path="price" value="${book.price}"/></td>
                </tr>
                <tr>
                    <td><form:label path="rackId">Book Rack Id:</form:label></td>
                    <td><form:input path="rackId" value="${book.rackId}"/></td>
                </tr>
                <tr>
                    <td><form:label path="numberOfBooks">Number of Books:</form:label></td>
                    <td><form:input path="numberOfBooks" value="${book.numberOfBooks}"/></td>
                </tr>
                <tr>
                    <td><form:label path="subjectCode">Book Subject Code:</form:label></td>
                    <td><form:input path="subjectCode" value="${book.subjectCode}"/></td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value="Submit"/></td>
                </tr>
            </table> 
        </form:form>

        <c:if test="${!empty books}">
            <h2>List Books</h2>
            <table align="left" border="1">
                <tr>
                    <th>NameOfBook</th>
                    <th>BookCode</th>
                    <th>AuthorName</th>
                    <th>DateOfArrival</th>
                    <th>PriceOfBook</th>
                    <th>BookRackId</th>
                    <th>NumberofBooks</th>
                    <th>BookSubjectCode</th>
                    <th>Actions on Row</th>
                </tr>
                <c:forEach items="${books}" var="book">
                    <tr>
                        <td><c:out value="${book.bookName}"/></td>
                        <td><c:out value="${book.bookCode}"/></td>
                        <td><c:out value="${book.author}"/></td>
                        <td><c:out value="${book.dateOfArrival}"/></td>
                        <td><c:out value="${book.price}"/></td>
                        <td><c:out value="${book.rackId}"/></td>
                        <td><c:out value="${book.numberOfBooks}"/></td>
                        <td><c:out value="${book.subjectCode}"/></td>
                        <td align="center"><a href="edit.html?id=${book.bookCode}">Edit</a> | <a href="delete.html?id=${book.bookCode}">Delete</a></td>
                    </tr>
                </c:forEach>
            </table>
        </c:if>
    </body>
</html>

提交后抛出异常。因为在控制器中 bookCode 字段的值未在 bean 类对象中接收。

    type Exception report

    message Request processing failed; nested exception is java.lang.NullPointerException

    description The server encountered an internal error (Request processing failed; nested exception is java.lang.NullPointerException) that prevented it from fulfilling this request.

    exception

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:659)
        org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    root cause

    java.lang.NullPointerException
        com.tcs.controller.BookController.editBook(BookController.java:76)
        sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        java.lang.reflect.Method.invoke(Method.java:601)
        org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
        org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
        org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
        org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
        org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
        org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
        org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    note The full stack trace of the root cause is available in the Apache Tomcat/7.0.29 logs.

这是我的控制器类,我在编辑方法中获取 bookCode 字段的值,get 方法为空;

package com.tcs.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.tcs.bean.BookBean;
import com.tcs.model.Book;
import com.tcs.service.BookService;

@Controller
public class BookController {
    @Autowired
    private BookService bookService;

    @RequestMapping(method=RequestMethod.POST, value = "/save")
    public ModelAndView saveBook(@ModelAttribute("command") BookBean bookBean, BindingResult result) {
        Book book = prepareModel(bookBean);
        bookService.addBook(book);

        return new ModelAndView("redirect:/add.html");
    }

    @RequestMapping(value="/books", method = RequestMethod.GET)
    public ModelAndView listBooks() {
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("books",  prepareListofBean(bookService.listBooks()));

        return new ModelAndView("booksList", model);
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public ModelAndView addBook(@ModelAttribute("command") BookBean booksBean, BindingResult result) {
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("books",  prepareListofBean(bookService.listBooks()));

        return new ModelAndView("addBook", model);
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public ModelAndView welcome() {
        return new ModelAndView("index");
    }

    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    public ModelAndView deleteBook(@ModelAttribute("command") BookBean bookBean, BindingResult result) {
        System.out.println(bookBean.getBookCode());
        bookService.deleteBook(prepareModel(bookBean));

        Map<String, Object> model = new HashMap<String, Object>();
        model.put("book", null);
        model.put("books",  prepareListofBean(bookService.listBooks()));

        return new ModelAndView("addBook", model);
    }

    @RequestMapping(value = "/edit" , method=RequestMethod.GET)
    public ModelAndView editBook(@ModelAttribute("command") BookBean bookBean, BindingResult result) {
        Map<String, Object> model = new HashMap<String, Object>();
        System.out.println(bookBean.getBookCode());
        model.put("book", prepareBooksBean(bookService.getBook(bookBean.getBookCode())));
        model.put("books",  prepareListofBean(bookService.listBooks()));

        return new ModelAndView("addBook", model);
    }

    private Book prepareModel(BookBean bookBean){
        Book book = new Book();
        book.setBookName(bookBean.getBookName());
        book.setBookCode(bookBean.getBookCode());
        book.setAuthor(bookBean.getAuthor());
        book.setDateOfArrival(bookBean.getDateOfArrival());
        book.setPrice(bookBean.getPrice());
        book.setRackId(bookBean.getRackId());
        book.setNumberOfBooks(bookBean.getNumberOfBooks());
        book.setSubjectCode(bookBean.getSubjectCode());

        return book;
    }

    private List<BookBean> prepareListofBean(List<Book> books){
        List<BookBean> beans = null;

        if(books != null && !books.isEmpty()) {
            beans = new ArrayList<BookBean>();

            BookBean bean = null;

            for(Book book : books){
                bean = new BookBean();
                bean.setBookName(book.getBookName());
                bean.setBookCode(book.getBookCode());
                bean.setAuthor(book.getAuthor());
                bean.setDateOfArrival(book.getDateOfArrival());
                bean.setPrice(book.getPrice());
                bean.setRackId(book.getRackId());
                bean.setNumberOfBooks(book.getNumberOfBooks());
                bean.setSubjectCode(book.getSubjectCode());
                beans.add(bean);
            }
        }

        return beans;
    }

    private BookBean prepareBooksBean(Book book){
        BookBean bean = new BookBean();

        bean.setBookName(book.getBookName());
        bean.setBookCode(book.getBookCode());
        bean.setAuthor(book.getAuthor());
        bean.setDateOfArrival(book.getDateOfArrival());
        bean.setPrice(book.getPrice());
        bean.setRackId(book.getRackId());
        bean.setNumberOfBooks(book.getNumberOfBooks());
        bean.setSubjectCode(book.getSubjectCode());

        return bean;
    }
}

这是我的控制器的服务类

package com.tcs.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.tcs.dao.BookDao;
import com.tcs.model.Book;

@Service("bookService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public void addBook(Book book) {
        bookDao.addBook(book);
    }

    public List<Book> listBooks() {
        return bookDao.listBooks();
    }

    public Book getBook(int bookCode) {
        return bookDao.getBook(bookCode);
    }

    public void deleteBook(Book book) {
        bookDao.deleteBook(book);
    }
}

这是 servlet.xml 的设置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:property-placeholder location="classpath:resources/database.properties" />
    <context:component-scan base-package="com.tcs" />

    <tx:annotation-driven transaction-manager="hibernateTransactionManager"/>

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.tcs.model.Book</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>             
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

这是一个 web.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>sdnext</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/sdnext-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>sdnext</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>
4

1 回答 1

1

你编辑方法

    @RequestMapping(value = "/edit" , method=RequestMethod.GET)
    public ModelAndView editBook(@ModelAttribute("command") BookBean bookBean, 
            BindingResult result) {

        Map<String, Object> model = new HashMap<String, Object>();
        System.out.println(bookBean.getBookCode()); // bookbean is null
        model.put("book", prepareBooksBean(bookService.getBook(bookBean.getBookCode())));
        model.put("books",  prepareListofBean(bookService.listBooks()));
        return new ModelAndView("addBook", model);
    }

接受一个 BookBean 实例。为了让 spring 为您创建这个 bean,它需要具有映射到对象字段的请求参数。您正在通过<a href>锚点提出请求。

<a href="edit.html?id=${book.bookCode}">Edit</a>

请求中唯一的参数是id,它甚至与bookCode字段名称都不匹配。Spring 将无法创建 bean,因此将通过null. 您可以在此处阅读有关该过程的更多信息。

我们可以假设 发生类似的事情deleteBook

于 2013-07-11T16:16:21.727 回答