【SSM-Day5】SpringMVC
- Web->Servlet->Servlet容器
- MVC档案
- SpringMVC档案
- SpringMVC核心操作
-
- 📢建立连接
- 📢接收请求
-
- [1. 直接接收一个请求参数](#1. 直接接收一个请求参数)
- [2. 直接接收多个请求参数](#2. 直接接收多个请求参数)
- [3. 用对象接收多个请求参数](#3. 用对象接收多个请求参数)
- [4. 用数组接收请求的数组参数](#4. 用数组接收请求的数组参数)
- [5. 用集合接收请求的数组参数](#5. 用集合接收请求的数组参数)
- [6. 用对象接收JSON数据](#6. 用对象接收JSON数据)
- [7. @PathVariable:获取URL中的默认参数](#7. @PathVariable:获取URL中的默认参数)
- [8. @RequestPart:接收请求中的文件](#8. @RequestPart:接收请求中的文件)
- [9. 获取请求报文中的Cookie](#9. 获取请求报文中的Cookie)
- [10. @RequestHeader:获取header](#10. @RequestHeader:获取header)
- [11. 根据请求中的SessionId设置/获取session内容](#11. 根据请求中的SessionId设置/获取session内容)
- 📢返回响应
-
- [1. 返回静态页面](#1. 返回静态页面)
-
- [@Controller :默认返回view](#@Controller :默认返回view)
- [2. 返回数据](#2. 返回数据)
-
- [2. 1 @Controller+@ResponseBody:返回数据](#2. 1 @Controller+@ResponseBody:返回数据)
- [2.2 @RestController :返回数据](#2.2 @RestController :返回数据)
- [3. 返回HTML代码片段](#3. 返回HTML代码片段)
- [4. 返回JSON](#4. 返回JSON)
- [5. 设置响应报文状态码](#5. 设置响应报文状态码)
- [6. 设置header](#6. 设置header)
- 总结一下~
Web->Servlet->Servlet容器
Web就是网站。
Servlet是一套JavaWeb开发的规范、技术标准。Servlet规范是开放的,
但是没有实现的标准不能做任何事。Servlet容器就是实现了Servlet规范的产品,即真正用代码实现Servlet规范提到的各种功能,包括类、⽅法、属性等的一类产品。比如Tomcat、Weblogic、Jetty、Jboss、WebSphere等,这些都是Servlet容器。
进行网站开发时,经常会调用Servlet API,Servlet容器的作用是管理程序员写的Servelt类。
SpringMVC继承了Servlet API。
MVC档案
全称:Model View Controller -> 模型 视图 控制器
是什么:实现软件系统的一种思想。
核心内容:MVC把软件系统分为Model 、View 、Controller三个基本部分。
- View部分负责与浏览器进行交互、展示数据资源。当用户请求到达服务器或者服务器响应离开服务器时,都要经过View。
- Model是软件程序的主体,它处理请求的内容并返回处理结果。
- Controller部分相当于一个分发器。由它决定视图发来的请求由哪一个Model处理。
SpringMVC实现了MVC思想。
SpringMVC档案
全称:Spring Web MVC。
是什么:一个实现了MVC思想,基于Servlet API的Web框架。SpringMVC中的MVC相较于原始MVC,结合自身特点做出了一些改变:
其实就是请求不经过view直接到达Controller。
SpringMVC、SpringBoot、Spring之间的关系:Spring包含SpringMVC和SpringBoot。⽽ Spring Boot 是 Spring 的脚手架,Spring MVC 是 Spring 的核⼼模块 。SpringBoot可以添加很多依赖,借助这些依赖实现不同的功能,SpringBoot通过添加SpringMVC框架,来实现web功能。SpringBoot是实现SpringMVC的一种方式。
SpringMVC核心内容:SpringMVC是Spring 的核心模块,一个基于Spring实现的JavaWeb项目的核心是客户端与服务器进行交互->建立连接、接收请求、返回响应。所以SpringMVC的核心内容就是实现客户端与浏览器之间的交互,--->即实现三个功能:
- 访问一个地址后能调用到Spring程序;
- 获取请求参数给Spring程序处理;
- 把程序执行的结果返回给客户端。
SpringMVC核心操作
SpringMVC把操作封装成了各种各样的注解,我们编写代码时调用注解即可。
注解在代码中:@注解名(注解的属性)。
前方一波操作来袭--->
创建SpringMVC项目,在java文件下创建一个/多个非启动类--->
非启动类就相当于控制器,类里的方法相当于模型,建立连接、接收请求、处理请求,返回响应的相关注解都是写在java文件下的非启动类中。
📢建立连接
在SpringMVC中,通过注解@RestController+@RequestMapping
或注解@Controller+@RequestMapping
建立浏览器和Spring程序之间的连接。
@RequestMapping:实现路由映射
路由映射:当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类中的某个方法的过程就叫路由映射。
在SpringMVC中,通过使用注解@RequestMapping来实现路由映射。代码中@RequestMapping的path属性对应用户访问的url。
总结注解@RequestMapping的用法:
- @RequestMapping即可以单独修饰方法,也可以修饰类+方法。修饰类+方法时,访问路径是:类路径+方法路径。
@RequestMapping的URL路径最前⾯加不加/ (斜杠)都可以,Spring程序启动时,会进行判断,如果前⾯没有加/ ,Spring会拼接上⼀个/ 。一般来说自己加上。
@RequestMapping 的URL路径也可以是多层路径,最终访问时,依然是类路径+⽅法路径。
- @RequestMapping 既⽀持Get请求,又支持Post请求.同理,也支持其他的请求方式。
以下分别是用Postman模拟浏览器发送get请求和post请求得到的结果:
@Controller/@ResponseBody:表示Spring某个类是否可以接收HTTP请求
Spring收到浏览器发来的http请求后,会会先对所有的类进行扫描,如果类加了@RestController或@Controller,表示这个类可以接收HTTP请求,Spring才会继续去类里寻找其中有没有与该请求对应的方法。
@RestController就是@Controller+@ResponseBody。这三个注解在响应位置还会涉及。
总结@RestController/@Controller的异同:
- 这两个注解的作用对象都是类,作用都是表示Spring某个类是否可以接收HTTP请求。
- 但是由于@RestController比@Controller多了一个@ResponseBody,所以它们之间有区别。
- @Controller能直接返回页面资源。页面地址前要加/
@RestController不能返回页面资源。@RestController能直接返回内容,它会自动将对象实体转换为JSON格式。
返回内容:
@Controller+@ResponseBody,才能返回内容。
📢接收请求
访问不同的路径,就是发送不同的请求,后面为了方便,用Postman模拟浏览器发送请求的过程。
浏览器发送请求(请求报文)后,Spring程序是如何接收到请求的?用SpringMVC的注解帮我们接收请求。
先明确:
-
请求参数通常直接位于请求报文的url中,请求参数有时是用户上传的(比如用户输入登录信息后进入主页),有时是url地址默认有的(比如用户直接点击链接进入xxx网页)。
JSON数据位于请求报文的Body中。
-
若请求的参数值与后端程序中接收请求参数的变量类型不匹配,响应结果会报错误信息400(强转失败)。后面不在赘述这一点。
-
一般情况下,请求的参数名字和后端接受该参数的变量名一致,变量才能接收到对应请求的参数。但是SpringMvc是通过各种注解接收请求的,通过修改注解的属性值可以解决这个问题。
比如,如果请求的参数名字是name,后端接收该参数的变量名字不是name也可以(修改注解的属性)。
接下来请看SpringMVC(注解)是如何接收请求然后给Spring程序处理的----->
1. 直接接收一个请求参数
如果请求中含一个参数,在Spring程序中,给接收该请求对应的方法设置一个形参即可。
总结一些注意点:
-
-
如果接收请求参数的变量类型是引用数据类型,且请求参数为空->后端程序会先把请求参数转换为null值,然后赋给对应变量。--->所以此时响应结果为null(Integer a = null成立);
-
如果形参的类型是基本数据类型,且请求参数为空->后端程序会先把请求参数转换为null值,然后赋给对应变量。因为基本数据类型无法转换为null值(int a = null是错的),所以响应结果会报错误信息500。
-
以上两点省流:方法中的形参类型建议使用包装类。
-
2. 直接接收多个请求参数
如果请求中含多个参数,在Spring程序中,给对应接收方法设置多个形参即可。同样的,方法中的形参类型建议使用包装类。
3. 用对象接收多个请求参数
通常来说,如果请求中有多个参数,不会用上面提到的方法,而是会把接收请求参数的多个变量封装为一个对象。
方法的形参由多个变成一个。且方法中的参数作为成员变量被封装在对象中。
此时即使接收请求参数的变量类型是基本数据类型,请求参数为空,返回结果是对应的0值,而不是错误信息500。
这是因为成员变量没有初始化的时候,引用类型默认为null,基本类型默认是自己的0值。
所以,当请求参数有多个时,直接用对象接收弥补了直接在对应方法中设置多个变量的缺点(方法的形参数量多 + 请求参数为空存在bug隐患)。
@RequestParam:后端参数映射
在实现前后端交互的时候,后端想要接收到请求,后端接收该参数的变量名默认和请求参数保持一致。但是如果后端就想用XXX变量接收NNN参数呢?
可以通过注解@RequestParam的name属性进行强制绑定:
在变量前面加上注解@RequestParam,就可以把请求参数和@RequestParam后面的变量绑定,即使变量名和请求参数名不同,程序认为该变量就是接收该请求参数的。
注解有属性。@RequestParam有两个属性,name/value和required分别决定了它在代码中起到的两个核心作用。
@RequestParam源码如下:
(alias:别名)
总结@RequestParam的用法:
-
设置name的属性值为请求参数的名字,required属性保持默认:
@RequestParam("XXX") 变量类型 NNN
:把请求参数XXX赋值给变量NNN,请求参数不能是空。
此时,required属性是默认值,即默认请求参数不能是空, 如果为空,后端程序会返回状态码400。
-
设置@RequestParam的required属性为false
@RequestParam(required=false) 变量类型 XXX
:把请求参数XXX赋值给变量XXX,请求参数可以为空。 -
@RequestParam的name和required属性都是默认值:
@RequestParam 变量类型 处理请求参数的变量
:请求参数名字和后端接收参数的变量名字保持一致,请求参数不能是空。
-
设置@RequestParam的name和required属性分别为 请求参数名 和 false。
@RequestParam(name="XXX",required=false) 变量类型 NNN
:把请求参数XXX赋值给变量NNN,请求参数可以为空
4. 用数组接收请求的数组参数
如何传数组给Spring程序:
- 给一个参数赋多个值,值与值之间用英文逗号隔开
- 给同一个参数多次赋值
SpringMVC如何接收数组:
5. 用集合接收请求的数组参数
把集合传给Spring程序有两个方法:
- 给一个参数赋多个值,值与值之间用英文逗号隔开
- 给同一个参数多次赋值
和传数组一样!事实上,在Spring程序看来,客户端传的就是数组。
但是此时接收请求的变量类型是集合,不是数组。请求参数的值与后端程序中接收变量的类型不匹配,Spring程序接收不到参数,会返回状态码500。
当需要把请求赋值给集合变量时,要在变量前面加注解@RequestParam。把请求参数绑定到@RequestParam后面的变量上。
6. 用对象接收JSON数据
@RequestBody:把请求正文中的数据赋值给接收对象
当请求是JSON数据的时候,通常用对象来接收。
并且,要在这个对象前面加上注解@RequestBody。
JSON数据并不是直接作为请求参数传给服务器的,而是被放在请求报文的body里传给服务器。
RequestBody是请求正文的意思,注解@RequestBody的作用是把请求报文中的body内容赋值给接收该请求的变量 。
@RequestBody只有一个属性:
7. @PathVariable:获取URL中的默认参数
PathVariable:路径变量。
例如:你把你的文章链接分享给你的朋友,你的朋友点开链接拿到文章。这个过程中你朋友所在的客户端没有手动输入任何参数,但浏览器依然返回了你的文章页面给你的朋友。
这是因为你的文章链接中有默认参数,比如这个默认参数可能是你文章的id等。
后端程序通过注解 @PathVariable 获取URL中的默认参数。
@PathVariable也有给后端变量重命名的属性,使用方法同@RequestParam。
总结@PathVariable的用法:
使用@PathVariable时,还要修改@RequestMapper中的属性值。具体使用如下:
-
URL中有一个默认参数
-
URL中有多个默认参数,(路径缺失会报错)
8. @RequestPart:接收请求中的文件
@RequestPart也有给后端变量重命名的属性,使用方法同@RequestParam。
总结注解@RequestPart的用法:
9. 获取请求报文中的Cookie
获取请求报文中的cookie有两种方式,一种通过调用ServletAPI接口获取cookie的全部内容,一种是通过注解@CookieValue获取cookie片段。
- 调用ServletAPI接口获取cookie的全部内容:
SpringMVC继承了ServletAPI,在上面代码中,HttpServletRequest ,HttpServletResponse都是Servlet提供的类,在SpringMVC中可以直接使用。
HttpServletRequest对象代表客户端的请求,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
在上面代码中,通过HttpServletRequest对象提供的getCookies()方法,就能获取请求报文中的cookie所有内容。
HttpServletResponse 对象代表服务器的响应,HTTP响应的信息都在这个对象中,比如向客户端发送的数据,响应头,状态码等。通过这个对象提供的方法,可以获得服务器响应的所有内容。
- 使用注解@CookieValue获取cookie片段
cookie是键值对形式的内容,通过注解@CookieValue能指定cookie中的key,获取对应的value值。
@CookieValue也有给后端变量重命名的属性,使用方法同@RequestParam。
10. @RequestHeader:获取header
获取请求报文中的header也有两种方法:
- 调用ServletAPI获取header片段
先从HttpServletRequest对象中获取请求,然后调用HttpServletRequest对象提供的getHeader()方法获取到请求中的header片段。
2. 使用注解@RequestHeader获取header片段
@RequestHeader也有给后端变量重命名的属性,使用方法同@RequestParam。
11. 根据请求中的SessionId设置/获取session内容
根据请求中的SessionId获取对应session有两种方式:一是调用ServletAPI获取,二是使用注解。
- 调用ServletAPI设置session。
先从HttpServletRequest对象中获取请求,然后调用HttpServletRequest对象提供的getSession()方法获取到请求中的sessionId。
拿到sessionId后进一步到服务器中寻找是否存在该客户,找到了,获取对应客户的session。如果没找到,新建一个session对象。
HttpSession是Servlet提供的存储session信息的类。调用HttpSession提供的方法setAttribute()可以设置session的内容。调用getAttribute()方法可以获取session的内容。
java
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request){
//根据sessionId获取session
HttpSession session = request.getSession();
//设置session内容
//name:zhangsan
session.setAttribute("name","zhangsan");
return "设置session成功!";
}
java
@RequestMapping("/getSession1")
public String getSession1(HttpServletRequest request){
//根据sessionId获取session
HttpSession session = request.getSession();
//获取session内容
//name:zhangsan
String 名字 = (String) session.getAttribute("name");
return "从session中获取名字:"+名字;
@SessionAttribute:获取session
- 使用注解@SessionAttribute获取session内容
@SessionAttribute也有给后端变量重命名的属性,使用方法同@RequestParam。
📢返回响应
Http响应结果可以是数据,也可以是静态⻚⾯,也可
以针对响应设置状态码,Header信息等.
常见响应:
1. 返回静态页面
前提,有一个静态页面,
在static文件下创建页面index.html,(页面的内容是ai生成的一个简单登录页面)。
如何把这个页面作为响应内容返回呢?
通过注解@Controller注解返回静态页面:
静态页面地址的前面一定要加/ ,表示这是一个页面地址的相对路径,相对于当前Spring程序。
接下来继续欣赏前面已经提到的三个注解:
- @Controller返回页面资源
- @RestController返回数据
- @Controller+@ResponseBody,返回数据。
前面只是总结,接下来会更深入一点。
@Controller :默认返回view
注解@Controller 其实就相当于MVC思想中的Controller控制器。
对接收请求,然后选择model,接收model的响应并返回view(返回页面资源)。
但是但是,就拿上面代码来说,/index.html属于前端内容,但是却出现在后端处理请求的代码中。
所以说,返回页面资源已经out了!!!
而现在更多是下面的写法,即后端只返回数据,前端什么样与后端无关。
后端如何返回数据?
2. 返回数据
2. 1 @Controller+@ResponseBody:返回数据
总结@ResponseBody的用法:
欣赏一下@ResponseBody的源码:
@ResponseBody作用是返回数据;
它既可以修饰类,也可以修饰方法,修饰类时,表示当前类的所有方法,全部返回数据。
@ResponseBody和@Controller组合使用:
当有多个注解的时候,顺序无所谓。
@ResponseBody和@Controller可以合并为@RestController。
2.2 @RestController :返回数据
@RestController是复合注解,即@RestController=@Controller+@ResponseBody。
总结@RestController 的用法:
欣赏一下它的源码:
元注解对当前注解的功能实现没有什么用,元注解可以理解成当前注解的一个标签。
在类的前面加上@RestController,表示该类可以接受http请求并返回数据。
3. 返回HTML代码片段
后端返回的数据中包含html片段,SpringMVC会自动把响应报文中的Content-Type设置为text/html,表示body中数据格式是html。浏览器收到后会自动解析。
4. 返回JSON
后端返回的数据是对象,SpringMVC会自动把响应报文中的Content-Type设置为application/json ,表示body中数据格式是JSON。
5. 设置响应报文状态码
SpringMVC会根据我们方法的返回结果⾃动设置响应状态码,程序员也可以⼿动指定状态码。
通过SpringMVC的内置对象HttpServletResponse提供的setStatus()⽅法来进行设置:
设置状态码不影响页面的展示。
6. 设置header
@RequestMapping:设置header
Http响应报头也会向客⼾端传递⼀些附加信息,比如服务程序的名称,请求的资源已移动到新地址等,如:Content-Type,Local等。
通过设置注解@RequestMapping的属性,可以对请求进行过滤,或者设置http响应报头。
欣赏一下注解@RequestMapping的源码:
path/value:指定映射的url。具体不在赘述。
method:指定请求的method类型,如GET,POST等。
consumes:指定处理请求(request)的提交内容类型(Content-Type),例如application/json,text/html;
Params:指定request中必须包含某些参数值时,才让该⽅法处理。
headers:指定request中必须包含某些指定的header值,才能让该⽅法处理请求。
method、consumes、Params和headers属性都是用来过滤请求的,比如设置method="get",表示该方法只能处理get请求。
produces:指定返回的内容类型。通过设置produces属性的值,设置响应的报头Content-Type。
如果不设置produces,方法返回结果为String时,SpringMVC默认返回类型是text/html。
设置返回类型时,也可以同步设置响应编码。
java
@RequestMapping(value = "/returnJson2",produces = "application/json;charset=UTF-8")
@ResponseBody
public String returnJson2() {
return "{\"success\":true}";
}
总结一下~
通过使用SpringMVC注解在Spring项目中实现三个功能:
- . 访问一个地址后能调用到Spring程序;
- . 获取请求参数给Spring程序处理;
- . 把程序执行的结果返回给客户端。
其中涉及到的注解如下:(修改注解的属性实现不同作用)
- @RequestMapping:路由映射,过滤请求,设置响应类型。
- @Controller:接收http请求,返回页面资源
- @ResponseBody:返回数据
- @ResponseBody:接收http请求,返回数据。
- @RequestParam:后端参数映射
- @RequestBody:把请求正文中的数据赋值给接收对象
- @PathVariable:获取URL中的默认参数
- @RequestPart:接收请求中的文件
- @CookieValue:获取cookie片段
- @RequestHeader:获取header
- @SessionAttribute:获取session
- @RequestMapping:设置header(对请求进行过滤,设置http响应报头)
重要的servletAPI使用:
- HttpServletRequest对象代表客户端的请求,它提供的getCookies()方法,能获取请求报文中的cookie所有内容。getHeader()方法获取到请求中的header片段。getSession()方法获取到请求中的sessionId。
- HttpServletResponse 对象代表服务器的响应,setStatus()⽅法能设置响应报文状态码。
- HttpSession是Servlet提供的存储session信息的类。调用HttpSession提供的方法setAttribute()可以设置session的内容。调用getAttribute()方法可以获取session的内容。
撒花~