七、Spring 整合Web项目
7.1 整合思路
目前为止,每次获取对象,都必须先创建IOC容器,操作如下:
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
但这种操作如果放在一个项目中效率太低,IOC容器的初始化工作应该是提前准备好,并且是一次性的。在Web项目中,把加载Spring配置文件和创建IOC容器的过程,放在服务器启动时候完成。
实现思路如下:
1、在服务器启动时,为每个项目创建一个ServletContext对象;
2、使用监听器,监听ServletContext对象的创建;
3、监听器监听到ServletContext创建时候,加载Spring核心配置文件;
4、把IOC容器存放到SetvletContext域对象中;
5、需要获取对象时,从ServletContext域取出IOC容器;
7.2. 实现步骤
7.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>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
7.2.2 监听器的实现
@WebListener
public class SpringContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
/**
* 在web项目中的上下对象创建之后,将spring的IOC容器放置在上下文对象
*/
//1.获取上下文对象
ServletContext sc = servletContextEvent.getServletContext();
//2.创建IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//3.将容器对象放入到上下文域中
sc.setAttribute("ac", ac);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
7.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;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
7.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>
7.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());
}
}
7.2.6 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">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
7.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());
7.4 Web项目的完整实现
7.4.1 applicationContext.xml
db.properties:
# Oracle相关配置
jdbc.oracle.driver=oracle.jdbc.driver.OracleDriver
jdbc.oracle.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.oracle.username=scott
jdbc.oracle.password=tiger
# Mysql相关配置
jdbc.mysql.driver=com.mysql.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&useSSL=false
jdbc.mysql.username=root
jdbc.mysql.password=root
<?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">
<!--开启注解,扫描公共包com.newcapec-->
<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.mysql.driver}"/>
<property name="url" value="${jdbc.mysql.url}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
</bean>
<!--配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
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>
7.4.2 实体类
@Component
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;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", major='" + major + '\'' +
'}';
}
}
7.4.3 Dao
sql语句:
CREATE TABLE `t_student` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学生id',
`name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '学生姓名',
`age` int(2) NULL DEFAULT NULL COMMENT '学生性别',
`major` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '学生专业',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of t_student
-- ----------------------------
INSERT INTO `t_student` VALUES (2, '小红', 1, '网络工程');
INSERT INTO `t_student` VALUES (3, 'tom', 12, '计算机');
INSERT INTO `t_student` VALUES (4, '曹操', 12, '挖墓');
SET FOREIGN_KEY_CHECKS = 1;
接口:
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,?,?,?)";
String sql = "insert into t_student(name,age,major) values(?,?,?)";
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);
}
}
7.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();
}
}
7.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);
}
}
}
7.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_add.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>