什么是SpringMVC
Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。它与Struts2框架一样,都属于MVC框架,但其使用和性能等方面比Struts2更加优异。
SpringMVC特点
- 是Spring框架的一部分,可以方便的利用Spring所提供的其他功能。
- 灵活性强,易于与其他框架集成。
- 提供了一个前端控制器DispatcherServlet,使开发人员无需额外开发控制器对象。
- 可自动绑定用户输入,并能正确的转换数据类型。
- 内置了常见的校验器,可以校验用户输入。如果校验不能通过,那么就会重定向到输入表单。
- 支持国际化。可以根据用户区域显示多国语言。
- 支持多种视图技术。它支持JSP、Velocity和FreeMarker等视图技术。
- 使用基于XML的配置文件,在编辑后,不需要重新编译应用程序。
SpringMVC入门程序
1.创建一个maven工程,代码结构如下:
2.向pom.xml文件中添加依赖。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--SpringMVC 1.添加依赖jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
</dependencies>
3.在web.xml中,配置Spring MVC的前端控制器DispatcherServlet。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置Spring MVC的前端控制器DispatcherServlet。 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<!--SpringMVC前端控制器-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--配置加载spring*.xml文件-->
<param-value>classpath:spring*.xml</param-value>
</init-param>
<!-- 表示在容器启动时立即加载servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 拦截所有URL的请求,“/”表示默认映射地址-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4.配置资源文件
jdbc.properties文件:(这里以我自己的数据库web为例)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/web?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=root
jdbc.maxTotal=30
jdbc.minTotal=10
mybatis-config.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
spring-mybatis.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 配置整合mybatis过程 -->
<!-- 1.配置数据库相关参数properties的属性:${url} -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 2.数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置连接池属性 -->
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="${jdbc.maxTotal}" />
<property name="minPoolSize" value="${jdbc.minTotal}" />
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false" />
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000" />
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2" />
</bean>
<!-- 3.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置MyBatis全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 扫描pojo包 使用别名 -->
<property name="typeAliasesPackage" value="com.song.pojo" />
</bean>
<!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.song.dao" />
</bean>
<!--扫描注解-->
<context:component-scan base-package="com.song.dao,com.song.service"></context:component-scan>
<!-- 5.配置事务处理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置基于注解的声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
springmvc-config.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解的扫描-->
<context:component-scan base-package="com.song.controller"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 也可以用下面代码代替上面三个bean-->
<!-- <mvc:annotation-driven/>-->
<!-- <mvc:view-resolvers>-->
<!-- <mvc:jsp prefix="/WEB-INF/jsp/" suffix=".jsp"/>-->
<!-- <!–query_result /WEB-INF/jsp/query_result.jsp–>-->
<!-- </mvc:view-resolvers>-->
</beans>
5.编写数据库
user表:
/*
Navicat MySQL Data Transfer
Source Server : 111.229.25.156_3306
Source Server Type : MySQL
Source Server Version : 50728
Source Host : 111.229.25.156:3306
Source Schema : web
Target Server Type : MySQL
Target Server Version : 50728
File Encoding : 65001
Date: 01/04/2020 11:36:35
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`uid` int(11) NOT NULL,
`uname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`sex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`email` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`photo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '/StudioProject_war/upload//ad50c0a6128c43818f3d5277f2093c59.jpg',
`u_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`u_status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '正常',
PRIMARY KEY (`uid`, `uname`) USING BTREE,
INDEX `uname`(`uname`) USING BTREE,
INDEX `uid`(`uid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (12, 'MN', '123', '女', '1652013658@qq.com', 'http://111.229.25.156:7777/file/img/picture-3baa56b6-b88b-47c2-b00c-502ab7b6ae5c.jpg', 'user', '正常');
INSERT INTO `user` VALUES (111, 'tom', '123', '男', '1275194573@qq.com', '/StudioProject_war/upload//ad50c0a6128c43818f3d5277f2093c59.jpg', 'user', '封号');
INSERT INTO `user` VALUES (123, 'm1', '123', '女', '1552013305@qq.com', 'http://111.229.25.156:7777/file/img/picture-d5b3c6f9-702a-4073-8747-d4f690cbf8a9.jpg', 'admin', '正常');
INSERT INTO `user` VALUES (222, 'jam', '12', '女', '956146133@qq.com', '/StudioProject_war/upload//ad50c0a6128c43818f3d5277f2093c59.jpg', 'user', '正常');
INSERT INTO `user` VALUES (1049, 'grandir', '123', '女', '524864369@qq.com', '/StudioProject_war/upload//ad50c0a6128c43818f3d5277f2093c59.jpg', 'user', '正常');
INSERT INTO `user` VALUES (1275, 'Mitchell', '1275', '男', '1275194573@qq.com', 'http://111.229.25.156:7777/file/img/picture-4bdd5618-4b00-4491-bc5d-4b10b8d24d3c.png', 'admin', '正常');
INSERT INTO `user` VALUES (5456, 'kjhbj', '123', '男', '12358878@qq.com', '/StudioProject_war/upload//ad50c0a6128c43818f3d5277f2093c59.jpg', 'user', '正常');
SET FOREIGN_KEY_CHECKS = 1;
7.编写各层代码。
pojo层(User类):
package com.song.pojo;
import java.io.Serializable;
/**
* 用户
*/
public class User implements Serializable {
private Integer uid;
private String uname;
private String password;
private String sex;
private String email;
private String photo;
private String u_type;
private String u_status;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getU_type() {
return u_type;
}
public void setU_type(String u_type) {
this.u_type = u_type;
}
public String getU_status() {
return u_status;
}
public void setU_status(String u_status) {
this.u_status = u_status;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", uname='" + uname + '\'' +
", password='" + password + '\'' +
", sex='" + sex + '\'' +
", email='" + email + '\'' +
", photo='" + photo + '\'' +
", u_type='" + u_type + '\'' +
", u_status='" + u_status + '\'' +
'}';
}
}
dao层(UserDao接口):
package com.song.dao;
import com.song.pojo.User;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
<!--将UserDao注入容器-->
@Repository
public interface UserDao {
/**
* 根据用户名查找普通用户
* @param uname
* @return
*/
@Select("SELECT * FROM user where u_type='user' and uname like CONCAT('%',#{uname},'%')")
public List<User> findByName(String uname);
}
service层
UserService接口:
package com.song.service;
import com.song.pojo.User;
import java.util.List;
public interface UserService {
public List<User> findByName(String uname);
}
UserServiceImpl实现类:
package com.song.service.impl;
import com.song.dao.UserDao;
import com.song.pojo.User;
import com.song.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List<User> findByName(String uname) {
return userDao.findByName(uname);
}
}
controller层(UserController类):
package com.song.controller;
import com.song.pojo.User;
import com.song.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import java.util.Map;
@Controller
public class UserController {
@Autowired
private UserService userService;
// @RequestMapping("/findByName") 与index.jsp中表单<form action="findByName">对应
// public String findByName(String userName,Model model){
// List<User> users=userService.findByName(userName);
// model.addAttribute("user", users);
// System.out.println(users);
// return "find"; (与find.jsp对应)
// }
@RequestMapping("/findByName")
public String findByName(String userName, Map<String,Object> map){
List<User> users=userService.findByName(userName);
map.put("user",users);
return "find";
}
}
8.编写前端界面
index.jsp:
<%@page language="java" pageEncoding="UTF-8" contentType="text/html;utf-8" %>
<html>
<body>
<form action="findByName">
用户名:<input name="userName" type="text"/><br/>
<input type="reset" value="重置">
<input type="submit" value="查询">
</form>
</body>
</html>
find.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${user}
</body>
</html>
9.部署tomcate运行。
springMVC工作流程
1.用户通过浏览器向服务器发送请求,请求会被Spring MVC的前端控制器DispatcherServlet所拦截;
2.DispatcherServlet拦截到请求后,会调用HandlerMapping处理器映射器;
3.处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
4.DispatcherServlet会通过返回信息选择合适的HandlerAdapter(处理器适配器);
5.HandlerAdapter会调用并执行Handler(处理器),这里的处理器指的就是程序中编写的Controller类,也被称之为后端控制器;
6.Controller执行完成后,会返回一个ModelAndView对象,该对象中会包含视图名或包含模型和视图名;
7.HandlerAdapter将ModelAndView对象返回给DispatcherServlet;
8.DispatcherServlet会根据ModelAndView对象选择一个合适的ViewReslover(视图解析器);
9.ViewReslover解析后,会向DispatcherServlet中返回具体的View(视图);
10.DispatcherServlet对View进行渲染(即将模型数据填充至视图中);
11.视图渲染结果会返回给客户端浏览器显示。