目录
一、SpringMVC
二、Spring MVC基于Annotation开发-Spring MVC环境搭建
三、Spring MVC工作流程运行原理
四、SpringMVC接收请求参数的4种方式
(一)在controller使用参数接收,请求有什么参数,方法就有什么参数
(二)在controller使用参数接收, @RequstParam改变controller方法接收请求参数和使用参数不一致
(三)在controller使用实体类作为参数接收,请求参数作为实体类的属性
(四)restful格式接收参数
五、请求转发和重定向
(一)请求转发
(二)重定向
六、Spring MVC视图解析器
1.什么是 Spring 视图和视图解析器
2.常用视图和视图解析器简介
七、Spring MVC与JSON
1.SpringMVC处理json的框架是Jackson,要引入pom的依赖
2.在springmvc.xml配置
3.写controller
4.浏览器运行效果
八、拦截器
(一)什么是拦截器?适用场景?
(二)拦截器相关接口?
(三)登录拦截器类
(四)springmvc.xml配置拦截器
九、Spring整合Spring MVC及MyBatis
(一)什么是SSM整合
(二)三大框架的角色划分和职责
1.Spring框架
2.SpringMVC框架
3.Mybatis
(三)父子容器的关系
(四)SSM整合步骤
1.创建maven工程2.pom.xml
3.配置web4.配置web.xml
5.applicationContext.xml
6.db.properties
7.mybatis.xml
8.springmvc.xml
9.User
10.UserMapper.xml
11.UserMapper
12.UserService
13.UserServiceImpl
14.UserController
15.add.jsp
16.list.jsp
以下是模糊查询和分页17.UserMapper.xml
18.UserMapper
19.UserService
20.UserServiceImpl
21.UserController
22.add.jsp
23.list.jsp
24.update.jsp
SpringMVC是一个spring家族 MVC(Model View Controller 模型视图控制器)框架.
(一)创建maven工程
(二)添加依赖
org.springframework
spring-context
5.3.8
org.springframework
spring-webmvc
5.3.8
javax.servlet
jstl
1.2
javax.servlet
jsp-api
2.0
provided
(三)web.xml中配置前端控制器(核心控制器),其实就是一个Servlet
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springmvc
/
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encodingFilter
*
(四)springmvc.xml
(五)HelloController
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
//@RequestMapping 写在类上, controller里所有的方法映射加一个前缀
@RequestMapping("user")
public class HelloController {
//@RequestMapping 作用: 访问的url映射到加上@RequestMapping 的方法上面
//@RequestMapping 注解的值: url
@RequestMapping("/hello")
//Model 对象用途: 用来存储数据, 传输到页面中, 在页面中就可以获取数据
public String hello(Model model) {
//添加数据, 传输到页面
model.addAttribute("msg", "hello spring!");
//请求转发到页面, /index.jsp页面
return "jsp/index";
}
@RequestMapping("order")
public String order(Model model) {
model.addAttribute("msg", "我是订单列表");
//请求转发到/order.jsp页面
return "jsp/order";
}
}
(六)index.jsp和order.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--使用el表达式获取model存储的值--%>
${msg}
(七)运行效果
1、 用户发送请求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 Controller执行完成返回ModelAndView。
7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、 ViewReslover解析后返回具体View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户。
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
welcome.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
username=${username}
password=${password}
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("login")
public String login(String username, String password, Model model) {
System.out.println("username=" + username);
System.out.println("password=" + password);
//登录判断 todo
model.addAttribute("username", username);
model.addAttribute("password", password);
//请求转发到welcome.jsp页面
return "jsp/welcome";
}
}
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class LoginController {
@RequestMapping("login")
public String login(@RequestParam(value = "username") String un,
//required 表示是否需要提交的字段, false表示可以不提交字段,也可以提交, true表示必须要提交的字段, 不提交就会报400错误
//defaultValue 表示默认值, 不提交字段, 使用默认值, 提交字段, 使用默认值, 在required = false情况下有意义
@RequestParam(value = "password", required = false, defaultValue = "123456") String pd,
Model model) {
System.out.println("username=" + un);
System.out.println("password=" + pd);
//登录判断 todo
model.addAttribute("username", un);
model.addAttribute("password", pd);
//请求转发到welcome.jsp页面
return "jsp/welcome";
}
}
package com.tjetc.model.param;
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
package com.tjetc.controller;
import com.tjetc.model.param.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("login")
/**
* 通过参数的实体类接收传过来的参数
*/
public String login(User user, Model model) {
System.out.println("username=" + user.getUsername());
System.out.println("password=" + user.getPassword());
//登录判断 todo
model.addAttribute("username", user.getUsername());
model.addAttribute("password", user.getPassword());
//请求转发到welcome.jsp页面
return "jsp/welcome";
}
}
url路径传参
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
订单删除成功,path=${path},id=${id}
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("order")
public class OrderController {
@RequestMapping("del/{path}/{id}")
public String del(@PathVariable("path") String path,
@PathVariable("id") int id,
Model model) {
System.out.println("path=" + path + "\n");
System.out.println("id=" + id);
model.addAttribute("path", path);
model.addAttribute("id", id);
return "jsp/success";
}
}
默认就是请求转发
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
订单删除成功,path=${path},id=${id}
OrderController.java
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("order")
public class OrderController {
@RequestMapping("del/{path}/{id}")
public String del(@PathVariable("path") String path,
@PathVariable("id") int id,
Model model) {
System.out.println("path=" + path + "\n");
System.out.println("id=" + id);
model.addAttribute("path", path);
model.addAttribute("id", id);
return "jsp/success";
}
}
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("order")
public class OrderController {
@RequestMapping("aa")
public String aa() {
//重定向到订单删除
//redirect:"重定向路径"
return "redirect:/order/del/abc/36";
}
}
Spring MVC(Model View Controller)是 Spring 中一个重要的组成部分,而 Spring 视图和视图解析器则是 Spring MVC 中的组成部分。在介绍 Spring 视图和视图解析器前,我们先了解下在 Spring MVC 框架中,一个 Web 请求所需经历的六个阶段:
1.请求会首先被 Spring MVC 的前端请求分发器(Dispatcher)拦截。该拦截器是一个 Servlet, 需要在 web.xml 中配置,所有符合所配置的 URL 样式的访问请求,将都会被该拦截器拦截。Spring 提供了默认的分发器 org.springframework.web.servlet.DispatcherServlet,可以根据需要,决定是否需要定制自己的分发器。
2.在接收到访问请求后,分发器会根据开发人员在 Spring 配置文件或代码中的注解(Annotation),来查找合适的控制器。
3.分发器在查找到合适的控制器后,将请求转交给该控制器处理。
4.通常,控制器会调用相应服务类来处理业务逻辑,在将请求处理后,控制器需返回处理后的结果数据模型(Model)以及下一个需要显示的视图名。
5.在控制器处理结束并返回模型和视图名之后,Spring 会依次调用 Spring 容器中所注册的视图解析器,来查找符合条件的视图。
6.在获得 Spring 视图后,Spring 会根据该视图的配置信息,显示该视图。
①图 1.Spring MVC 处理流程
通过以上 Spring MVC 的介绍,我们可以发现,视图和视图解析器将出现在整个请求处理流程中的最后部分。那么到底什么是视图和视图解析器?简而言之,视图是指 Spring MVC 中的 V(View),而视图解析器的功能则是依据指定的规则来查找相应的视图。
在开发中,视图通常就是 JSP、Velocity、FreeMarker等。Spring 默认提供了多种视图解析器,比如,我们可以使用最常用解析器 InternalResourceViewResolver 来查找 JSP 视图(与之相对应的视图类为 InternalResourceView)。通常,一个视图解析器只能查找一个或多个特定类型的视图,在遇到 Spring 不支持的视图或者我们要自定义视图查找规则的情况下,我们就可以通过扩展 Spring 来自定义自己所需的视图解析器。目前,视图解析器都需要实现接口 org.springframework.web.servlet.ViewResolver, 它包含方法 resolveViewName,该方法会通过视图名查找并返回 Spring 视图对象。表 1 列出了常用的 Spring 视图解析器。
①表 1.Spring 常用视图解析器列表
在多数项目中,InternalResourceViewResolver 是最常用的,该解析器可以返回指定目录下指定后缀的文件,它支持 JSP 及 JSTL 等视图技术。
在 Web 开发中,我们的前端显示可以是 JSP、Excel、Velocity 、FreeMarker等,在 Spring 中,不同的前端显示技术都有其对应的 Java 视图类,正如表 1 所提到的,InternalResourceView 可以代表 JSP 视图,FreeMarkerView 代表 FreeMarker 视图。目前,Spring 支持多种技术开发的视图,包括 JSP、JSTL、Excel,Velocity、FreeMarker 等
springmvc.xml
HelloController.java
package com.tjetc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
//@RequestMapping 写在类上, controller里所有的方法映射加一个前缀
@RequestMapping("user")
public class HelloController {
//@RequestMapping 作用: 访问的url映射到加上@RequestMapping 的方法上面
//@RequestMapping 注解的值: url
@RequestMapping("/hello")
//Model 对象用途: 用来存储数据, 传输到页面中, 在页面中就可以获取数据
public String hello(Model model) {
//添加数据, 传输到页面
model.addAttribute("msg", "hello spring!");
//请求转发到页面, /index.jsp页面
return "jsp/index";
}
@RequestMapping("order")
public String order(Model model) {
model.addAttribute("msg", "我是订单列表");
//请求转发到/order.jsp页面
return "jsp/order";
}
}
index.jsp和order.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--使用el表达式获取model存储的值--%>
${msg}
运行效果
从Controller得到json:当controller的方法返回一个对象(实体类对象,也可是集合对象),同时标注了@ResponseBody,jackson在后台默默将对象转化为json字符串
com.fasterxml.jackson.core
jackson-databind
2.12.4
package com.tjetc.controller;
import com.tjetc.model.param.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("json")
public class JsonController {
@RequestMapping("get-user")
@ResponseBody//把对象转换成json输出给前端
public User getUser() {
User user = new User("jack", "111");
return user;
}
@RequestMapping("get-user-list")
@ResponseBody
public List getUsers() {
List users = Arrays.asList(new User("tom", "1111"),
new User("jack", "2222"),
new User("jim", "3333"));
return users;
}
}
(一)课堂练习
在controller写一个方法,该方法返回值是map集合
package com.tjetc.controller;
import com.tjetc.model.param.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Controller
@RequestMapping("json")
public class JsonController {
@RequestMapping("get-user-map")
@ResponseBody
public Map getMap() {
Map map = new HashMap<>();
map.put("state", 0);
map.put("msg", "成功");
map.put("data", null);
return map;
}
}
Spring MVC的拦截器(Interceptor)与Java Servlet的过滤器(Filter)类似,它主要用于拦截用户的请求并做相应的处理。通常应用在权限验证、记录请求信息的日志、判断用户是否登录功能上。
实现HandlerInterceptor接口,实现接口提供三个方法:
preHandle:该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作。返回true表示继续向下执行,返回false表示中断后续操作。
postHandle:该方法在控制器的处理请求方法调用之后,解析视图之前执行。可以通过此方法对请求域中的模型和视图做进一步的修改。
afterCompletion:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。
package com.tjetc.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 自定义的登录拦截器
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 执行时机是在Controller类里对应的方法之前(例如: add、update、delete等方法)
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断session是否存储用户信息, 如果存储了表示登录过了, 放行, 如果没有存储过表示尾灯率或登录过期,返回false, 重定向到login.jsp页面
HttpSession session = request.getSession();
Object username = session.getAttribute("username");
if (username != null) {
//存在用户信息, 已登录, 放行, 返回true
return true;
} else {
//未登录或登录过期, return false, 重定向到login.jsp页面, 并返回false
response.sendRedirect(request.getContextPath() + "/jsp/login.jsp");
return false;
}
}
}
打开新的页面因为有session, 不用重新登录, 换个浏览器没了session存储username需要重新登录
只对/user/……有拦截作用
对其他不用user开头的路径不会有拦截作用
SSM:Spring+Spring MVC+Mybatis 三大框架整合
mapper,pojo,配置文件 ,映射文件
1.父容器是Spring容器
2.子容器SpringMVC容器
3.子容器的bean可以访问父容器的bean
4.0.0
com.tjetc
20220625ssm
1.0-SNAPSHOT
org.springframework
spring-context
5.3.8
org.springframework
spring-webmvc
5.3.8
org.springframework
spring-tx
5.3.8
org.springframework
spring-jdbc
5.3.8
org.mybatis
mybatis
3.5.7
org.mybatis
mybatis-spring
2.0.6
mysql
mysql-connector-java
8.0.21
com.zaxxer
HikariCP
4.0.3
org.springframework
spring-test
5.3.8
test
org.junit.jupiter
junit-jupiter
5.7.2
test
org.aspectj
aspectjweaver
1.9.7
com.github.pagehelper
pagehelper
5.1.9
com.fasterxml.jackson.core
jackson-databind
2.12.4
org.apache.commons
commons-lang3
3.11
commons-fileupload
commons-fileupload
1.4
javax.servlet
jstl
1.2
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springmvc
/
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encodingFilter
*
jdbc.driverName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456
package com.tjetc.entity;
public class User {
private Long id;
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
insert into USER (username,password) values (#{username},#{password});
package com.tjetc.mapper;
import com.tjetc.entity.User;
import java.util.List;
public interface UserMapper {
void add(User user);
List findAll();
}
package com.tjetc.service;
import com.tjetc.entity.User;
import java.util.List;
public interface UserService {
void add(User user);
List list();
}
package com.tjetc.service.impl;
import com.tjetc.entity.User;
import com.tjetc.mapper.UserMapper;
import com.tjetc.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 UserMapper userMapper;
@Override
public void add(User user) {
userMapper.add(user);
}
@Override
public List list() {
return userMapper.list();
}
}
package com.tjetc.controller;
import com.tjetc.entity.User;
import com.tjetc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/add")
public String add(User user){
userService.add(user);
return "redirect:/user/list";
}
@RequestMapping("/list")
public String list(Model model){
List list=userService.list();
model.addAttribute("list", list);
return "list";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
add
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
list
序号
用户名
密码
${s.id}
${s.username}
${s.password}
insert into USER (username,password) values (#{username},#{password})
update user set username =#{username},password=#{password} where id=#{id}
delete from user where id=#{id}
package com.tjetc.mapper;
import com.tjetc.domain.User;
import java.util.List;
public interface UserMapper {
void add(User user);
List list(String username);
User findById(int id);
void update(User user);
void del(int id);
}
package com.tjetc.service;
import com.github.pagehelper.PageInfo;
import com.tjetc.entity.User;
public interface UserService {
void add(User user);
PageInfo list(String username, Integer curPage, int pageSize);
User findById(int id);
void update(User user);
void del(int id);
}
package com.tjetc.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tjetc.entity.User;
import com.tjetc.mapper.UserMapper;
import com.tjetc.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 UserMapper userMapper;
@Override
public void add(User user) {
userMapper.add(user);
}
@Override
public PageInfo list(String username, Integer curPage, int pageSize) {
PageHelper.startPage(curPage, pageSize);
List list = userMapper.list(username);
PageInfo pageInfo = new PageInfo<>(list);
return pageInfo;
}
@Override
public User findById(int id) {
return userMapper.findById(id);
}
@Override
public void update(User user) {
userMapper.update(user);
}
@Override
public void del(int id) {
userMapper.del(id);
}
}
package com.tjetc.controller;
import com.github.pagehelper.PageInfo;
import com.tjetc.entity.User;
import com.tjetc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/add")
public String add(User user){
userService.add(user);
return "redirect:/user/list";
}
@RequestMapping("/list")
public String list(Integer curPage,String username,Model model){
curPage=curPage==null?1:curPage;
username=username==null?"":username;
int pageSize=2;
PageInfo pageInfo = userService.list(username, curPage, pageSize);
model.addAttribute("page", pageInfo);
model.addAttribute("username", username);
return "list";
}
@RequestMapping("/{id}")
public String findById(@PathVariable("id") int id,Model model){
User user=userService.findById(id);
model.addAttribute("user", user);
return "update";
}
@RequestMapping("/update")
public String update(User user){
userService.update(user);
return "redirect:/user/list";
}
@RequestMapping("/delete/{id}")
public String del(@PathVariable("id") int id){
userService.del(id);
return "redirect:/user/list";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
add
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
list
用户名:
序号
用户名
密码
操作
${s.id}
${s.username}
${s.password}
${page.pageNum}/${page.pages}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
add