六、Spring整合Web项目
1. 整合思路
目前为止,每次获取对象,都必须先创建IOC容器,操作如下:
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
但这种操作如果放在一个项目中效率太低,IOC容器的初始化工作应该是提前准备好,并且是一次性的。在Web项目中,把加载Spring配置文件和创建IOC容器的过程,放在服务器启动时候完成。
实现思路如下:
- 在服务器启动时,为每个项目创建一个ServletContext对象
- 使用监听器,监听ServletContext对象的创建
- 监听器监听到ServletContext创建时候,加载Spring核心配置文件
- 把IOC容器存放到SetvletContext域对象中
- 需要获取对象时,从ServletContext域取出IOC容器
2. 实现步骤
2.1 引入maven依赖
<dependencies>
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springbean包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springcontext包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring表达式包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAOP包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAspects包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring对web的支持包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springJDBC包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring事务包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- oracle驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2 监听器的实现
@WebListener
public class SpringContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
/**
* 在web项目中的上下对象创建之后,将spring的IOC容器放置在上下文对象
*/
//1.获取上下文对象
ServletContext sc = sce.getServletContext();
//2.创建IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//3.将容器对象放入到上下文域中
sc.setAttribute("ac", ac);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
2.3 Bean对象
@Component
public class Person {
@Value("101")
private Integer id;
@Value("小明")
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.4 applicationContext.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:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.newcapec"/>
</beans>
2.5 Servlet
@WebServlet("/getPerson")
public class PersonServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.取出容器
ApplicationContext ac = (ApplicationContext) this.getServletContext().getAttribute("ac");
//2.容器中获取对象
Person person = ac.getBean("person", Person.class);
System.out.println(person.getId() + "---" + person.getName());
}
}
3. Spring中的实现
在Spring中已经实现了初始化IOC容器的监听器,需要导入Spring整合web项目的jar包
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 初始化IOC容器的spring中的监听器 -->
<!--
此监听器在创建IOC容器时,默认读取spring配置文件的位置是:/WEB-INF/applicationContext.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>
</web-app>
Spring在Web项目中使用的容器为:WebApplicationContext
//从上下文对象中获取IOC容器对象
WebApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
Person person = ac.getBean("person", Person.class);
System.out.println(person.getId() + "---" + person.getName());
4. Web项目的完整实现
4.1 applicationContext.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:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.newcapec"/>
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.oracle.driver}"/>
<property name="url" value="${jdbc.oracle.url}"/>
<property name="username" value="${jdbc.oracle.username}"/>
<property name="password" value="${jdbc.oracle.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
4.2 实体类
public class Student {
private Integer id;
private String name;
private Integer age;
private String major;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
4.3 Dao
接口
public interface StudentDao {
void insertStudent(Student student);
void updateStudent(Student student);
void deleteStudent(Integer id);
Student selectStudentById(Integer id);
List<Student> selectStudent();
}
实现类
@Repository("studentDao")
public class StudentDaoImpl implements StudentDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void insertStudent(Student student) {
String sql = "insert into t_student(id,name,age,major) values(seq_demo.nextval,?,?,?)";
jdbcTemplate.update(sql, student.getName(), student.getAge(), student.getMajor());
}
@Override
public void updateStudent(Student student) {
String sql = "update t_student set name=?,age=?,major=? where id=?";
jdbcTemplate.update(sql, student.getName(),student.getAge(),student.getMajor(),student.getId());
}
@Override
public void deleteStudent(Integer id) {
String sql = "delete from t_student where id=?";
jdbcTemplate.update(sql, id);
}
@Override
public Student selectStudentById(Integer id) {
String sql = "select id,name,age,major from t_student where id=?";
RowMapper<Student> rowMapper = new BeanPropertyRowMapper<>(Student.class);
return jdbcTemplate.queryForObject(sql, rowMapper, id);
}
@Override
public List<Student> selectStudent() {
String sql = "select id,name,age,major from t_student order by id desc";
RowMapper<Student> rowMapper = new BeanPropertyRowMapper<>(Student.class);
return jdbcTemplate.query(sql, rowMapper);
}
}
4.3 Service
接口
public interface StudentService {
void addStudent(Student student);
void editStudent(Student student);
void removeStudent(Integer id);
Student findStudentById(Integer id);
List<Student> findStudent();
}
实现类
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public void addStudent(Student student) {
studentDao.insertStudent(student);
}
@Override
public void editStudent(Student student) {
studentDao.updateStudent(student);
}
@Override
public void removeStudent(Integer id) {
studentDao.deleteStudent(id);
}
@Override
public Student findStudentById(Integer id) {
return studentDao.selectStudentById(id);
}
@Override
public List<Student> findStudent() {
return studentDao.selectStudent();
}
}
4.4 Servlet
@WebServlet({"/findStudent","/addStudent","/editStudent","/removeStudent","/getStudent"})
public class StudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
WebApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
StudentService studentService = ac.getBean("studentService", StudentService.class);
String path = req.getServletPath();
if(path.contains("find")){
List<Student> list = studentService.findStudent();
req.setAttribute("list", list);
req.getRequestDispatcher("/student.jsp").forward(req, resp);
}else if(path.contains("add")){
String name = req.getParameter("name");
String age = req.getParameter("age");
String major = req.getParameter("major");
Student student = new Student();
student.setName(name);
student.setAge(Integer.parseInt(age));
student.setMajor(major);
studentService.addStudent(student);
req.getRequestDispatcher("/findStudent").forward(req, resp);
}else if(path.contains("edit")){
String id = req.getParameter("id");
String name = req.getParameter("name");
String age = req.getParameter("age");
String major = req.getParameter("major");
Student student = new Student();
student.setId(Integer.parseInt(id));
student.setName(name);
student.setAge(Integer.parseInt(age));
student.setMajor(major);
studentService.editStudent(student);
req.getRequestDispatcher("/findStudent").forward(req, resp);
}else if(path.contains("remove")){
String id = req.getParameter("id");
studentService.removeStudent(Integer.parseInt(id));
req.getRequestDispatcher("/findStudent").forward(req, resp);
}else if(path.contains("get")){
String id = req.getParameter("id");
Student student = studentService.findStudentById(Integer.parseInt(id));
req.setAttribute("student", student);
req.getRequestDispatcher("/student_edit.jsp").forward(req, resp);
}
}
}
4.5 页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>欢迎使用...</h1>
<a href="findStudent">学生列表</a>
</div>
</body>
</html>
student.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>学生列表</h1>
<a href="student_insert.jsp">新增</a>
<table border="1" width="600" align="center">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>专业</th>
<th>操作</th>
</tr>
<c:forEach items="${list}" var="s">
<tr>
<td>${s.id}</td>
<td>${s.name}</td>
<td>${s.age}</td>
<td>${s.major}</td>
<td>
<a href="getStudent?id=${s.id}">编辑</a>  
<a href="removeStudent?id=${s.id}" onclick="return confirm('确定要删除吗?')">删除</a>
</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
student_add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>学生新增</h1>
<form action="addStudent" method="post">
<p>
<label>姓名</label>
<input type="text" name="name"/>
</p>
<p>
<label>年龄</label>
<input type="text" name="age"/>
</p>
<p>
<label>专业</label>
<input type="text" name="major"/>
</p>
<p>
<button type="submit">提交</button>
</p>
</form>
</div>
</body>
</html>
student_edit.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>学生编辑</h1>
<form action="editStudent" method="post">
<input type="hidden" name="id" value="${student.id}">
<p>
<label>姓名</label>
<input type="text" name="name" value="${student.name}"/>
</p>
<p>
<label>年龄</label>
<input type="text" name="age" value="${student.age}"/>
</p>
<p>
<label>专业</label>
<input type="text" name="major" value="${student.major}"/>
</p>
<p>
<button type="submit">提交</button>
</p>
</form>
</div>
</body>
</html>