springMVC课堂笔记
目标:
springMVC的简介
springMVC入门案例
springMVC工作流程
springMVC的controller的使用
springMVC如何处理前端的请求信息和响应信息
springMVC的上传和下载
springMVC的拦截器
springMVC的视图解析器
springMVC简介
- 什么是SpringMVC?
Spring MVC是一个基于MVC模式的WEB框架,它解决WEB开发中常见的问题(参数接收、文件上传、下载等等),使用非常简单,SpringMVC作为Spring中的一个模块,可以与Spring无缝集成。
Spirngmvc是基于servlet的web框架,springMVC其实是spring的一个模块
springMVC是一个MVC的开源框架,springMVC=struts2+spring,springMVC就相当于是Struts2加上spring的整合,但是这里有一个疑惑就是,springMVC和spring是什么样的关系呢?这个在百度百科上有一个很好的解释:意思是说,springMVC是spring的一个后续产品,其实就是spring在原有基础上,又提供了web应用的MVC模块,可以简单的把springMVC理解为是spring的一个模块(类似AOP,IOC这样的模块),网络上经常会说springMVC和spring无缝集成,其实springMVC就是spring的一个子模块,所以根本不需要同spring进行整合。
M: Model
V:View
C:Controller
- 为什么要学习SpringMVC ?
Spring是一个轻量级的Java 开发框架,为了解决企业应用开发的复杂性而创建。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。SpringMVC以Spring框架为核心,为应用程序中的Web层(表现层)提出的一套优秀的解决方案。
目前很多公司都使用Spring MVC,100%的招聘单位要求熟悉使用Spring MVC。
springMVC是应用程序中的Web层(表现层)提出的一套优秀的框架,再目前的开发中是最主流的web开发层次的框架之一,轻量级的框架。
SSM == springMVC + spring + mybatis
SM == springBoot + mybatis(mybatis-plus) spring Data JPA
springMVC的入门案例
1,创建对应的jsp页面
2,导入springmvc相关的jar包
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
3,再web.xml中配置springmvc的前端控制器
<?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_3_1.xsd"
version="3.1">
<!-- 配置springmvc的前端控制器,来统一处理前端请求信息,交给springmvc配置文件来集中处理 -->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4,再springmvc.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 定义请求名称及其对应的处理类 -->
<bean id="/login" class="cn.hd.controller.LoginController"/>
</beans>
5,编写处理类信息,并给出ModelAndView对象
// 控制器类
public class LoginController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
mv.addObject("mess","hello springMVC!!");
mv.setViewName("success.jsp");
return mv;
}
}
优化
修改maven方式创建的web.xml文件的版本。
总结
代码执行流程:
解释:
Index.jsp 发送login请求 , web.xml中的DispatcherServlet进行拦截,把请求拦截到交给 springmvc.xml ,在该文件中找到 < bean>标签中的 login请求名 ,并映射到LoginController来中来执行 HandeRequestInternal方法来处理该请求,并以modelAndView对象的形式响应前端控制器(dispatcherServlet),前端控制会使用视图解析器,得到响应的页面,响应给用户(success.jsp)
springMVC的工作流程
原理图:
看到这个图大家可能会有很多的疑惑,现在我们来看一下这个图的步骤:(可以对比MVC的原理图进行理解)
第一步:用户发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找
第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain)
第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)
第五步:处理器适配器去执行Handler
第六步:Handler执行完给处理器适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView
第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析
第九步:视图解析器像前端控制器返回View
第十步:前端控制器对视图进行渲染
第十一步:前端控制器向用户响应结果
看到这些步骤我相信大家很感觉非常的乱,这是正常的,但是这里主要是要大家理解springMVC中的几个组件:
前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU。
处理器映射器(HandlerMapping):根据URL去查找处理器
处理器(Handler):(需要程序员去写代码处理逻辑的)
处理器适配器(HandlerAdapter):会把处理器包装成适配器,这样就可以支持多种类型的处理器,类比笔记本的适配器(适配器模式的应用)
视图解析器(ViewResovler):进行视图解析,多返回的字符串,进行处理,可以解析成对应的页面
springMVC的简易流程
SpringMVC工作流程描述(简易)
- 客户端请求提交到DispatcherServlet
- 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的 handler。
- DispatcherServlet将请求转发给到handler。
- 通过HandlerAdatper执行handler调用业务逻辑处理后,返回ModelAndView
- DispatcherServlet查询一个或多个ViewResovler视图解析器,将model渲染到views。
- 将views结果显示到客户端。
控制器的写法
控制器类是真正的用来处理前端请求和给出不同的响应的核心类,类似servlet
方式一:
定义一个普通的类,来继承 AbatractController类
// 控制器类
public class LoginController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
mv.addObject("mess","hello springMVC!!");
mv.setViewName("success.jsp");
return mv;
}
}
方式二:
定义一个普通的类,实现Controller接口
public class RegisterController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
mv.addObject("mess","controller的第二种写法");
mv.setViewName("success.jsp");
return mv;
}
}
问题:
方式一和方式二这两种写法都可以,但是存在一个类中只能处理一个请求信息,不可以同时处理多个请求信 息,我们可以采用方式三来解决(全注解方式).
方式三:
全注解方式来实现处理前端请求并给出响应信息,以后工作中必用 全注解方式.
@Controller 创建对象并声明该类是控制器类
@RequestMapping("/请求名") 声明方法是用来处理该请求的核心方法 请求映射
用法:
1,再方法前,则表名该方法是用来处理对应的请求信息
2,定义再类前,则表名该类中的所有的方法的请求前加统一的前缀
StudentController.java
// 声明该类是一个控制器类,可以处理请求信息并给出响应信息
// 创建该类的对象
@Controller
public class StudentController {
/**
* 要求:
* 1,公共的方法
* 2,返回值是ModelAndView
* 3,方法名不定,建议和请求名匹配即可
*/
// <bean id="" class=""/>
@RequestMapping("/addStudent")
public ModelAndView addStudent(){
ModelAndView mv = new ModelAndView();
mv.addObject("mess","添加学生信息");
mv.setViewName("success.jsp");
return mv;
}
@RequestMapping("/delStudent")
public ModelAndView delStudent(){
ModelAndView mv = new ModelAndView();
mv.addObject("mess","删除学生信息");
mv.setViewName("success.jsp");
return mv;
}
}
springmvc.xml
<!-- 扫描包,启动注解[ @Controller @RequestMapping ]-->
<context:component-scan base-package="cn.hd.controller"/>
springmvc处理请求参数
1,简单数据类型 + String
页面:
<h4>简单数据类型(基本数据+String)</h4>
<form action="test1" method="post">
姓名:<input type="text" name="name" value="李四"><br/>
年龄:<input type="text" name="age" value="23"><br/>
<input type="submit" value="提交">
</form>
控制器:
@RequestMapping(value = "/test1" , method = RequestMethod.POST)
public String test1(String name,int age){
// 方法的参数列表的数据类型的名称与请求的参数信息重名,即可自动接收数据
System.out.println( name +" "+ age);
return "/success.jsp";
}
2,乱码
get请求(处理乱码使用的时tomcat中的server.xml中的默认的编码方式)
Tomcat 8.0 以上的版本,对请求参数进行解码,使用的是 UTF-8
Tomcat 8.0 以下的版本,默认的解码方式是ISO8859-1,在tomcat中找到 server.xml 加入
URIEncoding=UTF-8
post请求:
在springmvc中提供一个专门用来处理post乱码的类
响应:
无乱码
3,@RequestMapping注解详情
value : 设置请求名称
method : 可以通过RequestMethod.post/get来设置请求的方式
@GetMapping(…) ==== @RequestMapping(value="…",method=RequestMethod.Get)
@PostMapping(…) ==== @RequestMapping(value="…",method=RequestMethod.Post)
@RequestMapping(value = "/test1" , method = RequestMethod.POST)
//@PostMapping("/test1")
//@GetMapping("/test1")
public String test1(String name,int age){
// 方法的参数列表的数据类型的名称与请求的参数信息重名,即可自动接收数据
System.out.println( name +" "+ age);
return "/success.jsp";
}
4,@RequestParam注解详情
用来设置请求参数的键和接收的变量不重名问题
value : 设置前端请求的参数的键
required : 设置该参数是否必须传值 true false
defaultValue : 设置参数值如果是null的默认值
// @RequestParam()
// value : 前端提交的参数的键的值对应该参数
// required : 该参数必须传值
// defaultValue : 如果你传入的值为null,则以默认值填充
@RequestMapping("/test2")
public String test2(@RequestParam(value = "username",required = true,defaultValue = "haha") String name, int age){
System.out.println( name +" "+ age);
return "/success.jsp";
}
5,简单数据量的数组操作
页面:
<h4>简单数据类型(数组)</h4>
<form action="test3" method="post">
爱好:<input type="checkbox" name="hobby" value="游泳">游泳
<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="排球">排球
<br/>
<input type="submit" value="提交">
</form>
控制器:
@RequestMapping("/test3")
public String test3(String hobby[]){
System.out.println(Arrays.asList(hobby));
return "/success.jsp";
}
6,简单对象的传参
实体类:
public class User {
private int id;
private String name;
private String sex;
private int age;
private String hobby[];
// 省略功能的get和set方法
}
页面:
<h4>普通的对象接收传参</h4>
<form action="test4" method="post">
姓名:<input type="text" name="name" value="李四"><br>
性别:<input type="text" name="sex" value="男"><br>
年龄:<input type="text" name="age" value="22"><br>
爱好:<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="足球">足球
<input type="checkbox" name="hobby" value="排球">排球<br>
<input type="submit" value="添加">
</form>
控制器:
@RequestMapping("/test4")
public String test4(User user){
System.out.println(user.toString());
return "/success.jsp";
}
7,带有日期对象的传参
实体类:
public class Student {
private int id;
private String name;
private String sex;
private int age;
private String hobby[];
// 2021-3-15 ---> Date类型 不能自动接收
// 2021/3/15 ---> Date类型 可以自动接收
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
// 省略功能的get和set方法
}
页面:
<h4>带有日期类型的对象传参</h4>
<form action="test5" method="get">
姓名:<input type="text" name="name" value="李四"><br>
性别:<input type="text" name="sex" value="男"><br>
年龄:<input type="text" name="age" value="22"><br>
爱好:<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="足球" checked>足球
<input type="checkbox" name="hobby" value="排球">排球<br>
出生日期:<input type="date" name="birthday"><br/>
<input type="submit" value="添加">
</form>
控制器:
@RequestMapping("/test5")
public String test5(Student student){
System.out.println(student.toString());
return "/success.jsp";
}
注意:再springmvc.xml中启动注解
<!-- 启用springmvc的注解 -->
<mvc:annotation-driven/>
8,resful风格
默认方式: localhost:8080/test?name=admin
resful风格: localhost:8080/test/admin
页面:
<a href="test6/22">reful风格传参</a>
控制器:
@RequestMapping("/test6/{id}")
public String test6( @PathVariable("id") int uid){
System.out.println(uid+"======");
return "/success.jsp";
}
9,常见对象的自动注入
HttpServletRequest HttpServletResponse HttpSession ModelAndView Model
再定义好的方法的参数中直接定义该类型的对象,即可直接使用
页面:
<a href="test7?name=lisi">常见对象的自动注入</a>
控制器:
@RequestMapping("/test7")
public String test7(String name,
HttpServletRequest request,
HttpServletResponse response,
HttpSession session,
Model model){
System.out.println(name);
String img = request.getRealPath("img");
System.out.println(img);
request.setAttribute("req","request的数据");
session.setAttribute("user","admin");
System.out.println(session.getAttribute("user")+"----");
model.addAttribute("mo","model的数据");
return "/success.jsp";
}