Spring MVC
- 🔎什么是 Spring MVC
-
- MVC
- 对比 MVC 与 Spring MVC
- 🔎Spring MVC—连接
-
- @RequestMapping 默认情况下支持的请求类型
- @RequestMapping 指定请求类型
- 🔎Spring MVC—获取参数
-
- 获取单个参数
- 获取两个参数
- 参数重命名
- 传递对象
- 传递 JSON 对象
- 获取 URL 中的参数
- 上传文件
- 获取 Cookie / header / Session
-
- 传统方式获取 Cookie
- 利用注解获取 Cookie
- 传统方式获取 header
- 利用注解获取 header
- Session 的存储与获取
-
- 存储 Session
- 获取 Session
-
- 通过 Servlet 获取
- 通过 @SessionAttribute 获取
- 🔎Spring MVC—返回数据
-
- @ResponseBody
- 返回 JSON 对象
- 请求转发与请求重定向
-
- 理解 forward(请求转发) 与 redirect(请求重定向)
- 🔎总结
🔎什么是 Spring MVC
Spring Web MVC 是基于 Servlet 构建的原始 Web 框架, 包含在 Spring 框架中.
Spring Web MVC 来自其源模块的名称(Spring-webmvc), 但通常称作 Spring MVC
即
- Spring MVC 构建在 Servlet 之上
- Spring MVC 是一个 Web 框架
- Spring MVC 基于 Spring-webmvc 模块
MVC
MVC(Model View Controller)—模型视图控制器
- Model(模型), 应用程序中用于处理应用程序数据逻辑的部分. 通常模型对象负责在数据库中存取数据
- View(视图), 应用程序中用于处理数据显示的部分. 通常视图是依据模型数据创建的
- Controller(控制器), 应用程序中用于处理用户交互的部分. 通常控制器负责从视图读取数据, 控制用户输入, 并向模型发送数据
对比 MVC 与 Spring MVC
MVC 与 Spring MVC 之间的关系类似于 IOC(思想) 与 DI(思想的具体实现) 之间的关系
MVC 是一种思想
Spring MVC 是对 MVC 思想的具体实现
🔎Spring MVC—连接
利用 Spring MVC 输出 hello world🍭
在 demo 包下创建一个 controller 包
在 controller 包下创建一个 TestController 类
demo(package) → controller(package) → TestController(.class)
-
@Controller
, 存储 TestController 至 Spring 容器 -
@ResponseBody
, 返回数据而非页面 -
@RequestMapping()
, 设置请求路径
注意🍂
-
@Controller
可与@ResponseBody
合并为@RestController
-
@RequestMapping()
既可以修饰类也可以修饰方法
完整代码🍂
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
// @Controller
// @ResponseBody
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/hello")
public String sayHello() {
return "hello world";
}
}
运行结果🍂
@RequestMapping 默认情况下支持的请求类型
@RequestMapping 默认情况下支持多种 HTTP 请求
包括 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…
可通过 Postman 工具进行查看
@RequestMapping 指定请求类型
通过 method 属性指定请求的类型
可指定的请求类型
举个栗子🌰
指定 GET 请求method = RequestMethod.GET
完整代码
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String sayHello() {
return "hello world";
}
}
另一种指定 GET 请求的方式
(其他类型同理)
@GetMapping("/hello")
效果与@RequestMapping(value = "/hello", method = RequestMethod.GET)
相同
此时通过其他请求进行访问就会报错
405(Method Not Allowed)—方法不被允许
🔎Spring MVC—获取参数
获取单个参数
@RestController
@RequestMapping("/test")
public class TestController {
// 获取单个参数
@GetMapping("/hello")
public String sayHello(String name) {
return "hello " + name;
}
}
注意🍭
URL 中的 key 必须与所传参数一致
错误示范🍭
获取两个参数
@RestController
@RequestMapping("/test")
public class TestController {
// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, Integer age) {
return "hello name: " + name + " | age: " + age;
}
}
注意🍭
建议传参的类型为包装类型, 而非基础类型
错误示范🍭
当传参的类型为基础类型时
// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, int age) {
return "hello name: " + name + " | age: " + age;
}
当传参的类型为包装类型时
// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, Integer age) {
return "hello name: " + name + " | age: " + age;
}
参数重命名
利用注解@RequestParam
为参数重命名
举个栗子🌰
有两个参数 String t1(起始时间), String t2(结束时间)
滑稽老哥觉得 t1, t2 这两个名字不太好, 想要改成 startTime, endTime
于是利用注解@RequestParam
为参数重命名
将 t1 重命名为 startTime
将 t2 重命名为 endTime
@GetMapping("time")
public String showTime(
@RequestParam(value = "t1", required = false) String startTime,
@RequestParam(value = "t2", required = false) String endTime) {
return "开始时间: " + startTime + " | 结束时间: " + endTime;
}
对于 required 的解释🍭
分析@RequestParam()
源码发现, required
默认为 true
即忘记填写对应的 key 时就会报错
设置required
为 false
传递对象
当所需获取的参数较多时, 可通过传递对象的方式进行传参
设置对象属性🍂
@Data
public class User {
private int id;
private String name;
private int age;
}
传递对象🍂
@RestController
@RequestMapping("/test")
public class TestController {
// 传递对象
@GetMapping("/user")
public String showUser(User user) {
return user.toString();
}
}
注意🍭
URL 中的 key 必须与所传对象的属性一致
错误示范🍭
传递 JSON 对象
利用注解@RequestBody
传递 JSON 对象
@RestController
@RequestMapping("/test")
public class TestController {
// 传递 JSON 对象
@PostMapping("/json-user") // 推荐使用 @PostMapping
public String showJsonUser(@RequestBody(required = false) User user) {
return user.toString();
}
}
注意🍭
此处不建议使用@GetMapping
传递 JSON 对象 , @GetMapping
默认使用 URL 传递参数
获取 URL 中的参数
http://127.0.0.1:8080/test/login?username=bibubibu
http://127.0.0.1:8080/test/login/bibubibu
此处所指获取 URL 中的参数是后者的形式
即/
后面就是参数, 而不是?username=bibubibu
利用注解@PathVariable
获取 URL 中的参数
举个栗子🌰
需要传递的参数用 { } 包裹
{username}
{password}
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/login/{username}/{password}")
public String login(
@PathVariable(value = "username", required = false) String username,
@PathVariable(value = "password", required = false) String password) {
return "username: " + username + " | password: " + password;
}
}
上传文件
利用注解@RequestPart
上传文件
@RestController
@RequestMapping("/test")
public class TestController {
// 上传文件
@RequestMapping("/upfile")
public String upFile(@RequestPart("files") MultipartFile file) throws IOException {
// 1. 根目录
String path = "D:\Java\documents\png_file\";
// 2. 根目录 + 唯一文件名
path += UUID.randomUUID().toString().replace("-", "");
// 3. 根目录 + 唯一文件名 + 文件后缀
path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
// 4. 保存文件
file.transferTo(new File(path));
return path;
}
}
获取 Cookie / header / Session
Spring MVC 内置了 HttpServletRequest, HttpServletResponse
传统方式获取 Cookie
传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
@RequestMapping("/getCookies")
public String getCookies(HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
for(Cookie item : cookies) {
log.error(item.getName() + " | " + item.getValue());
}
return "getCookies~~";
}
}
校验🍭
添加 Cookie
运行查看结果
利用注解获取 Cookie
利用注解获取 Cookie—通过@CookieValue
获取(获取指定 Cookie)
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
@RequestMapping("/getCookie")
public String getCookie(@CookieValue("Homo") String val) {
log.error("Homo | " + val);
return "getCookie~~";
}
}
运行查看结果
传统方式获取 header
传统方式获取 header—通过 Servlet 获取
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/getUser-Agent")
public String getHeader(HttpServletRequest req) {
String userAgent = req.getHeader("User-Agent");
return "tradition | UserAgent : " + userAgent;
}
}
运行查看结果
利用注解获取 header
利用注解获取 header—通过@RequestHeader
获取
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/getUser-Agent")
public String getUA(@RequestHeader("User-Agent") String userAgent) {
return "Annotation | UserAgent : " + userAgent;
}
}
运行查看结果
Session 的存储与获取
存储 Session
利用 Servlet 存储 Session
对于getSession()
, getSession(true)
, getSession(false)
的解释
-
getSession(true)
, 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 Session -
getSession(false)
, 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 返回 Null -
getSession()
, 等同于getSession(true)
@RestController
@RequestMapping("/test")
public class TestController {
// 通过 Servlet 存储 Session
@RequestMapping("/setSession")
public String setSession(HttpServletRequest req) {
// 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 Session
HttpSession session = req.getSession(true);
// 设置 key, value
session.setAttribute("userInfo", "userInfo");
return "Set Session Success";
}
}
获取 Session
获取 Session 有 2 种方式
- 通过 Servlet 获取
- 通过
@SessionAttribute
获取
通过 Servlet 获取
@RestController
@RequestMapping("/test")
public class TestController {
// 通过 Servlet 获取 Session
@RequestMapping("/getSession")
public String getSession(HttpServletRequest req) {
HttpSession session = req.getSession(false);
if(session != null && session.getAttribute("userInfo") != null) {
return (String) session.getAttribute("userInfo");
} else {
return "session 信息不存在";
}
}
}
通过 @SessionAttribute 获取
@RestController
@RequestMapping("/test")
public class TestController {
// 通过 @SessionAttribute 获取 Session
@RequestMapping("/getSession")
public String getSession(
@SessionAttribute(value = "userInfo", required = false) String userInfo) {
return userInfo;
}
}
🔎Spring MVC—返回数据
@ResponseBody
- 未添加
@ResponseBody
, 返回页面 - 添加
@ResponseBody
, 返回数据
返回页面🍭
(未添加@ResponseBody
)
@RequestMapping("/resp")
@Controller
public class RespController {
@RequestMapping("/page")
public String retPage() {
return "/hello.html";
}
}
返回数据🍭
(添加@ResponseBody
)
@RequestMapping("/resp")
@Controller
@ResponseBody
public class RespController {
@RequestMapping("/page")
public String retPage() {
return "/hello.html";
}
}
返回 JSON 对象
返回 对象(Object) / HashMap 都是 JSON 格式
JSON 格式是键值对结构, 对象(Object) / HashMap 也是键值对结构
以 HashMap 为例🌰
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/response")
public HashMapString, String> respJson() {
HashMapString, String> map = new HashMap>();
map.put("Tom", "Tom_Val");
map.put("Homo", "Homo_Val");
map.put("Jack", "Jack_Val");
return map;
}
}
抓包查看结果
请求转发与请求重定向
- 请求转发 → forward
- 请求重定向 → redirect
请求转发
// 请求转发
@RequestMapping("/bibubibu-forward")
public String reqForward() {
return "forward:/hello.html";
}
请求重定向
// 请求重定向
@RequestMapping("/bibubibu-redirect")
public String reqRedirect() {
return "redirect:/hello.html";
}
理解 forward(请求转发) 与 redirect(请求重定向)
举个栗子🌰
滑稽老哥对他女朋友说想吃羊肉串
女朋友帮他买羊肉串(请求转发)
滑稽老哥自己去买羊肉串(请求重定向)
具体区别🍭
- 请求转发 → 由服务器端负责转发, 请求重定向 → 将请求重定位到资源
- 请求转发 → 地址不会发生改变, 请求重定向 → 地址会发生改变
- 请求转发 → 服务器端负责转发, 地址不发生改变(可能造成原外部资源不能访问)
请求重定向 → 地址发生改变, 等同于直接访问新地址(原外部资源能够访问)
类似于滑稽老哥自己去买羊肉串他就能买到口感最好的羊肉串(自己平时光顾较多的烧烤店) → 原外部资源能够访问
而委托女朋友去买虽然告诉了具体的地址仍然有可能买错 → 原外部资源不能访问
🔎总结
- Spring MVC—连接🍂
-
@RestController
→@Controller
+@ResponseBody
-
@RequestMapping
默认支持多种 HTTP 请求(GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…) -
@RequestMapping
指定请求类型 →@RequestMapping(value = "", method = RequestMethod.指定请求的类型)
-
@RequestMapping
指定请求类型 == 指定请求类型Mapping
(例如@RequestMapping(value = "", method = RequestMethod.GET)
==@GETMapping(value = "")
)
-
- Spring MVC—获取参数🍂
- 获取参数时 URL 中的 key 必须与所传参数一致
- 建议传参的类型为包装类型, 而非基础类型
- 参数重命名 →
@RequestParam
- 传递对象 → 当所需获取的参数较多时, 可通过传递对象的方式进行传参(URL 中的 key 必须与所传对象的属性一致)
- 传递 JSON 对象 →
@RequestBody
- 获取 URL 中的参数 →
@PathVariable
- 上传文件 →
@RequestPart
- 获取 Cookie
- 传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)
- 利用注解获取 Cookie—通过
@CookieValue
获取(获取指定 Cookie)
- 获取 header
- 传统方式获取 header—通过 Servlet 获取
- 利用注解获取 Cookie—通过
@RequestHeader
获取
- Session 的存储与获取
- 存储 Session—通过 Servlet 存储 Session
- 获取 Session—通过 Servlet 获取 Session
- 获取 Session—通过
@SessionAttribute
获取
- Spring MVC—返回数据
-
@ResponseBody
→ 未添加@ResponseBody
, 返回页面 / 添加@ResponseBody
, 返回数据 - 请求转发(地址不会发生改变) → forward / 请求重定向(地址会发生改变) → redirect
-
🌸🌸🌸完结撒花🌸🌸🌸