Spring / 休眠 - NullPointerException
Spring / Hibernate - NullPointerException
我对 Spring (MVC) 和 Hibernate 完全陌生,我正在努力学习它。
我编造了以下身份验证场景来练习,但我运气不太好。
场景:
我有一个 HTML 表单 (homepageForm.jsp),可以将用户名和密码发送到 HomeController。
HomeController 获取表单参数 (username/password) 并将表单参数与从数据库中检索到的用户名和密码进行比较。
如果匹配,将向用户显示 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>
**** User.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>
根据 Autowired 的 Javadoc,注释可用于 "a constructor, field, setter method or config method"。在 HomeController 中,在服务字段中放置 Autowired
注释。
@Autowired
private UserRetrievalService userRetrievalService;
您的 UserRetrievalService 未正确注入。
您可以使用@Autowired 或Constructor/Setter 注入。在你的情况下,你使用了 setter 注入但不是以正确的方式
应该是
私有 UserRetrievalService userRetrievalService;
@Autowired
public UserRetrievalService setUserRetrievalService(UserRetrievalService userRetrievalService) {
this.userRetrievalService = userRetrievalService;
}
关于休眠配置的建议。
您需要将 hibernate.cfg.xml 保留在类路径下
因为你的是maven项目,理想的地方是/src/main/resources/
请参阅 以了解更多信息。
我对 Spring (MVC) 和 Hibernate 完全陌生,我正在努力学习它。
我编造了以下身份验证场景来练习,但我运气不太好。
场景:
我有一个 HTML 表单 (homepageForm.jsp),可以将用户名和密码发送到 HomeController。 HomeController 获取表单参数 (username/password) 并将表单参数与从数据库中检索到的用户名和密码进行比较。
如果匹配,将向用户显示 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>
**** User.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>
根据 Autowired 的 Javadoc,注释可用于 "a constructor, field, setter method or config method"。在 HomeController 中,在服务字段中放置 Autowired
注释。
@Autowired
private UserRetrievalService userRetrievalService;
您的 UserRetrievalService 未正确注入。
您可以使用@Autowired 或Constructor/Setter 注入。在你的情况下,你使用了 setter 注入但不是以正确的方式
应该是
私有 UserRetrievalService userRetrievalService;
@Autowired
public UserRetrievalService setUserRetrievalService(UserRetrievalService userRetrievalService) {
this.userRetrievalService = userRetrievalService;
}
关于休眠配置的建议。
您需要将 hibernate.cfg.xml 保留在类路径下
因为你的是maven项目,理想的地方是/src/main/resources/
请参阅 以了解更多信息。