【问题标题】:Spring / Hibernate - NullPointerException春季/休眠 - NullPointerException
【发布时间】:2016-10-24 14:55:44
【问题描述】:

我对 Spring (MVC) 和 Hibernate 完全陌生,我正在努力学习它。

我编写了以下身份验证场景来练习,但我没有太多运气让它发挥作用。

场景:

我有一个向 HomeController 发送用户名和密码的 HTML 表单 (homepageForm.jsp)。 HomeController 获取表单参数(用户名/密码)并将表单参数与从数据库中检索的用户名和密码进行比较。

如果匹配,用户将看到dashboard.jsp。如果不匹配,则会加载 error.jsp。

来自数据库的信息由“UserRetrievalService”检索。

我收到以下错误:

:::: 错误

    type Exception report

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

    description The server encountered an internal error 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:982)
        org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
        org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)


    root cause
    java.lang.NullPointerException
        com.springdemo.mvc.HomeController.processLoginForm(HomeController.java:91)
        sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

我怀疑这与引用 servlet.xml 的方式有关。 HomeController 中的第 91 行是这一行:

User user = userRetrievalService.getUser();

或者我可能错误地使用了@Autowired。

谁能给我一些提示如何解决这个问题?

谢谢!

以下是有关该项目的一些附加信息。

**** 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:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd">

        <context:component-scan base-package="com.springdemo.mvc" />
        <context:component-scan base-package="com.springdemo.model" />

        <mvc:annotation-driven/>

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

    </beans>

**** web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>spring-mvc-demo</display-name>
      <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>

**** homepageForm.jsp

    <html>
    <head>
    <title>Homepage Form</title>
    </head>

    <body>
        <form action="processLogin" method="POST">
            <div>
                <label>Username</label> <input type="text" name="username" placeholder="username" />
            </div>
            <div>
                <label>Password</label> <input type="text" name="password" placeholder="password" />
            </div>
            <input type="submit" value="Login" />
        </form>
    </body>

    </html>

**** 用户.java

    package com.springdemo.model;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;

    @Entity
    @Table(name = "user")
    public class User implements AbstractUser {

        @Id
        @Column(name = "id")
        private int id;

        @Column(name = "username")
        private String username;

        @Column(name = "password")
        private String password;

        @Column(name = "first_name")
        private String firstname;

        @Column(name = "last_name")
        private String lastname;

        @Column(name = "email")
        private String email;

        public User() {

        }

        public User(int id, String username, String password, String firstname, String lastname, String email) {
            super();
            this.id = id;
            this.username = username;
            this.password = password;
            this.firstname = firstname;
            this.lastname = lastname;
            this.email = email;
        }

        + getters & setters

    }

**** 用户服务

    public interface UserService {

        public User getUser();
    }

**** 用户检索服务

    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.springframework.stereotype.Component;

    @Component
    public class UserRetrievalService implements UserService {

        @Override
        public User getUser() {

            System.out.println("UserRetrievalService called...");

            Configuration config = new Configuration().configure("hibernate.cfg.xml");
            config.addAnnotatedClass(User.class);

            SessionFactory sessionFactory = config.buildSessionFactory();

            // create a session
            Session session = sessionFactory.getCurrentSession();

            try {

                // start trans
                session.beginTransaction();

                // get & create user
                User user = session.get(User.class, 1);

                // commit trans
                session.getTransaction().commit();

                System.out.println("UserRetrievalService : commit successful...");

                System.out.println(" >>>> USER: " + user.getId() + " " + user.getUsername() + " " + user.getPassword() + " " + user.getFirstname() + " " + user.getLastname());

                return user;

            } finally {
                sessionFactory.close();
            }

        }

    }

**** HomeController.java

    import javax.servlet.http.HttpServletRequest;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;

    import com.springdemo.model.User;
    import com.springdemo.model.UserRetrievalService;

    @Controller
    public class HomeController { 

    ...
    private UserRetrievalService userRetrievalService;

    @Autowired
    public UserRetrievalService getUserRetrievalService() {
        return userRetrievalService;
    }

    @RequestMapping("/processLogin")
    public ModelAndView processLoginForm(HttpServletRequest request) {

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        System.out.println("username : " + username);
        System.out.println("password : " + password);

        User user = userRetrievalService.getUser();

        ModelAndView modelAndView;

        if (username.equalsIgnoreCase(user.getUsername()) && (password.equalsIgnoreCase(user.getPassword()))) {
            modelAndView = new ModelAndView("dashboard"); // page to be returned
        } else {
            modelAndView = new ModelAndView("error"); // page to be returned
        }

        // System.out.println("success: user id = " + user.getId());

        modelAndView.addObject("myUser", user);

        return modelAndView;
    }
    ...
    }

::::: hibernate.cfg.xml

    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

    <hibernate-configuration>

        <session-factory>

            <!-- JDBC Database connection settings -->
            <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="connection.url">jdbc:mysql://localhost:3306/springtestdb?useSSL=false</property>
            <property name="connection.username">*****</property>
            <property name="connection.password">*****</property>

            <!-- JDBC connection pool settings ... using built-in test pool -->
            <property name="connection.pool_size">1</property>

            <!-- Select our SQL dialect -->
            <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

            <!-- Echo the SQL to stdout -->
            <property name="show_sql">true</property>

            <!-- Set the current session context -->
            <property name="current_session_context_class">thread</property>

        </session-factory>

    </hibernate-configuration>

【问题讨论】:

  • 你使用什么服务器?雄猫?你能显示你的hibernate.cfg.xml吗?
  • @DonaldWu - hibernate.cfg.xml 添加到我的问题中......使用 Tomcat 8
  • @Autowired 用于将 bean 注入字段/构造函数。如果你想返回一些东西,请使用@ModelAttribute
  • 您是否尝试在您的hibernate.cfg.xml 中使用update?添加这个&lt;property name="hbm2ddl.auto"&gt;update&lt;/property&gt;,确保你的数据库中有表

标签: java spring hibernate jsp servlets


【解决方案1】:

您的 UserRetrievalService 未正确注入。

您可以使用 @Autowired 或 Constructor/Setter 注入。在您的情况下,您使用了 setter 注入,但方式不正确

应该是这样的

私有用户检索服务用户检索服务;

@Autowired
public UserRetrievalService setUserRetrievalService(UserRetrievalService userRetrievalService) {
    this.userRetrievalService = userRetrievalService;
}

关于休眠配置的建议。

您需要将 hibernate.cfg.xml 保留在类路径下

由于您的项目是 maven 项目,理想的位置是 /src/main/resources/

请参阅https://stackoverflow.com/a/29352557/7063373 了解更多信息。

【讨论】:

  • 谢谢!注射肯定是不正确的。我的 /src/main/resources 目录不存在。我最初创建了一个动态 Web 项目并将其转换为 Maven 项目......问题仍然存在......一旦我弄清楚了,我将发布一个解决方案。不管怎样,谢谢!
  • 当然.. 我的建议是我观察到你有 pom.xml 并且目录结构不符合 maven 方式。我曾经使用旧方法,例如创建动态项目并在以后进行诸如 ANT、maven、gradle 之类的更改。但是一旦我离开这种方法并开始以 MAVEN 方式工作,那真是太棒了。我绝对向我的任何开发者朋友推荐 MAVEN 方式。这使得项目结构更有条理。正如你所说的 你是 Spring 的新手 ,我建议你去 maven/gradle 方式
  • 我选择这个作为我的问题的答案(解决方案)。我必须做两件事来解决我的问题。在这个答案中建议了他们两个。 1. 我必须修复我的依赖注入。 2. 我从头开始创建了一个新的 Maven 项目,它创建了“正确的”目录结构,包括“src/main/java”和“src/main/resources”目录。我将我的原始代码从一个项目转移到另一个项目,包括将 hibernate.cfg.xml 移动到“src/main/resources”。之后代码按预期执行。所以感谢 satya-j!
  • @BustedSanta 欢迎您!很高兴知道您已经转向 Maven 方式。尝试探索 Maven 插件,这将在项目构建和部署阶段有很大帮助。一旦你开始研究它们,你就不想回去了。
【解决方案2】:

根据Autowired 的Javadoc,注释可用于“构造函数、字段、设置方法或配置方法”。在 HomeController 中将 Autowired 注解放在服务字段中。

@Autowired 
private UserRetrievalService userRetrievalService;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2012-12-05
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多