Spring MVC
🔎什么是 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()
既可以修饰类也可以修饰方法
完整代码🍂
packagecom.example.demo.controller;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.*;// @Controller// @ResponseBody@RestController@RequestMapping("/test")publicclassTestController{@RequestMapping("/hello")publicStringsayHello(){return"hello world";}}
运行结果🍂
@RequestMapping 默认情况下支持的请求类型
@RequestMapping 默认情况下支持多种 HTTP 请求
包括 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…
可通过 Postman 工具进行查看
@RequestMapping 指定请求类型
通过 method 属性指定请求的类型
可指定的请求类型
举个栗子🌰
指定 GET 请求
method = RequestMethod.GET
完整代码
@RestController@RequestMapping("/test")publicclassTestController{@RequestMapping(value ="/hello", method =RequestMethod.GET)publicStringsayHello(){return"hello world";}}
另一种指定 GET 请求的方式
(其他类型同理)
@GetMapping("/hello")
效果与
@RequestMapping(value = "/hello", method = RequestMethod.GET)
相同
此时通过其他请求进行访问就会报错
405(Method Not Allowed)—方法不被允许
🔎Spring MVC—获取参数
获取单个参数
@RestController@RequestMapping("/test")publicclassTestController{// 获取单个参数@GetMapping("/hello")publicStringsayHello(String name){return"hello "+ name;}}
注意🍭
URL 中的 key 必须与所传参数一致
错误示范🍭
获取两个参数
@RestController@RequestMapping("/test")publicclassTestController{// 获取两个参数@GetMapping("/hello")publicStringsayHello(String name,Integer age){return"hello name: "+ name +" | age: "+ age;}}
注意🍭
建议传参的类型为包装类型, 而非基础类型
错误示范🍭
当传参的类型为基础类型时
// 获取两个参数@GetMapping("/hello")publicStringsayHello(String name,int age){return"hello name: "+ name +" | age: "+ age;}
当传参的类型为包装类型时
// 获取两个参数@GetMapping("/hello")publicStringsayHello(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")publicStringshowTime(@RequestParam(value ="t1", required =false)String startTime,@RequestParam(value ="t2", required =false)String endTime){return"开始时间: "+ startTime +" | 结束时间: "+ endTime;}
对于 required 的解释🍭
分析
@RequestParam()
源码发现,
required
默认为 true
即忘记填写对应的 key 时就会报错
设置
required
为 false
传递对象
当所需获取的参数较多时, 可通过传递对象的方式进行传参
设置对象属性🍂
@DatapublicclassUser{privateint id;privateString name;privateint age;}
传递对象🍂
@RestController@RequestMapping("/test")publicclassTestController{// 传递对象@GetMapping("/user")publicStringshowUser(User user){return user.toString();}}
注意🍭
URL 中的 key 必须与所传对象的属性一致
错误示范🍭
传递 JSON 对象
利用注解
@RequestBody
传递 JSON 对象
@RestController@RequestMapping("/test")publicclassTestController{// 传递 JSON 对象@PostMapping("/json-user")// 推荐使用 @PostMappingpublicStringshowJsonUser(@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")publicclassTestController{@RequestMapping("/login/{username}/{password}")publicStringlogin(@PathVariable(value ="username", required =false)String username,@PathVariable(value ="password", required =false)String password){return"username: "+ username +" | password: "+ password;}}
上传文件
利用注解
@RequestPart
上传文件
@RestController@RequestMapping("/test")publicclassTestController{// 上传文件@RequestMapping("/upfile")publicStringupFile(@RequestPart("files")MultipartFile file)throwsIOException{// 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(newFile(path));return path;}}
获取 Cookie / header / Session
Spring MVC 内置了 HttpServletRequest, HttpServletResponse
传统方式获取 Cookie
传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)
@RestController@RequestMapping("/test")@Slf4jpublicclassTestController{@RequestMapping("/getCookies")publicStringgetCookies(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")@Slf4jpublicclassTestController{@RequestMapping("/getCookie")publicStringgetCookie(@CookieValue("Homo")String val){
log.error("Homo | "+ val);return"getCookie~~";}}
运行查看结果
传统方式获取 header
传统方式获取 header—通过 Servlet 获取
@RestController@RequestMapping("/test")publicclassTestController{@RequestMapping("/getUser-Agent")publicStringgetHeader(HttpServletRequest req){String userAgent = req.getHeader("User-Agent");return"tradition | UserAgent : "+ userAgent;}}
运行查看结果
利用注解获取 header
利用注解获取 header—通过
@RequestHeader
获取
@RestController@RequestMapping("/test")publicclassTestController{@RequestMapping("/getUser-Agent")publicStringgetUA(@RequestHeader("User-Agent")String userAgent){return"Annotation | UserAgent : "+ userAgent;}}
运行查看结果
Session 的存储与获取
存储 Session
利用 Servlet 存储 Session
对于
getSession()
,
getSession(true)
,
getSession(false)
的解释
getSession(true)
, 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 SessiongetSession(false)
, 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 返回 NullgetSession()
, 等同于getSession(true)
@RestController@RequestMapping("/test")publicclassTestController{// 通过 Servlet 存储 Session@RequestMapping("/setSession")publicStringsetSession(HttpServletRequest req){// 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 SessionHttpSession session = req.getSession(true);// 设置 key, value
session.setAttribute("userInfo","userInfo");return"Set Session Success";}}
获取 Session
获取 Session 有 2 种方式
- 通过 Servlet 获取
- 通过
@SessionAttribute
获取
通过 Servlet 获取
@RestController@RequestMapping("/test")publicclassTestController{// 通过 Servlet 获取 Session@RequestMapping("/getSession")publicStringgetSession(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")publicclassTestController{// 通过 @SessionAttribute 获取 Session@RequestMapping("/getSession")publicStringgetSession(@SessionAttribute(value ="userInfo", required =false)String userInfo){return userInfo;}}
🔎Spring MVC—返回数据
@ResponseBody
- 未添加
@ResponseBody
, 返回页面 - 添加
@ResponseBody
, 返回数据
返回页面🍭
(未添加
@ResponseBody
)
@RequestMapping("/resp")@ControllerpublicclassRespController{@RequestMapping("/page")publicStringretPage(){return"/hello.html";}}
返回数据🍭
(添加
@ResponseBody
)
@RequestMapping("/resp")@Controller@ResponseBodypublicclassRespController{@RequestMapping("/page")publicStringretPage(){return"/hello.html";}}
返回 JSON 对象
返回 对象(Object) / HashMap 都是 JSON 格式
JSON 格式是键值对结构, 对象(Object) / HashMap 也是键值对结构
以 HashMap 为例🌰
@RestController@RequestMapping("/test")publicclassTestController{@RequestMapping("/response")publicHashMap<String,String>respJson(){HashMap<String,String> map =newHashMap<>();
map.put("Tom","Tom_Val");
map.put("Homo","Homo_Val");
map.put("Jack","Jack_Val");return map;}}
抓包查看结果
请求转发与请求重定向
- 请求转发 → forward
- 请求重定向 → redirect
请求转发
// 请求转发@RequestMapping("/bibubibu-forward")publicStringreqForward(){return"forward:/hello.html";}
请求重定向
// 请求重定向@RequestMapping("/bibubibu-redirect")publicStringreqRedirect(){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
🌸🌸🌸完结撒花🌸🌸🌸
版权归原作者 哔卟哔卟_: ) 所有, 如有侵权,请联系我们删除。