文章目录
1.什么是 Spring MVC?
官⽅对于 Spring MVC 的描述:
Spring Web MVC is the original web framework built on the Servlet APl and has been included in the Spring Framework from the very beginning. The formal name,“Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonly known as“Spring MVC”.
官⽅对于 Spring MVC 的描述
翻译为中⽂:
Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中。它的正式名称“Spring Web MVC”来自其源模块的名称(Spring-webmvc),但它通常被称为“SpringMVC”。
从上述定义我们可以得出两个关键信息:
1. Spring MVC 是⼀个 Web 框架(HTTP)。
2. Spring MVC 是基于 Servlet API 构建的。
3. 来自于Spring web MVC 模块
2.什么是MVC?
MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。
- Model(模型) 是应⽤程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库在存取数据。
- View(视图) 是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
- Controller(控制器) 是应⽤程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输⼊,并向模型发送数据。
3.MVC和Spring MVC的关系
MVC是一种思想,而Spring MVC是对MVC思想的具体实现。
总结来说,Spring MVC是一个实现了MVC模式,并继承了Servlet APIl的 Web 框架。既然是Web框架,那么当用户在浏览器中输入了url 之后,我们的Spring MVC 项目就可以感知到用户的请求。
4.Spring核心模块
现在绝⼤部分的 Java 项目都是基于 Spring(或 Spring Boot)的,而 Spring 的核心就是 Spring MVC。也就是说 Spring MVC 是 Spring 框架的核心模块,而 Spring Boot 是 Spring 的脚手架。
在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架,如下图所示:
5.三大重要功能
- 连接的功能:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调用到我们的Spring 程序。
- 获取参数的功能:用户访问的时候会带⼀些参数,在程序中要想办法获取到参数。
- 输出数据的功能:执行了业务逻辑之后,要把程序执行的结果返回给⽤户。
5.1Spring MVC 创建和连接
5.1.1 Spring MVC创建方式
1.使用Maven方式传统创建Spring MVC(已过时)
2.使用Spring Boot添加Spring Web模块=>Spring MVC
Spring MVC 可以基于 Spring Boot 创建,也就是创建⼀个 Spring Boot 项⽬,勾选上 Spring Web模块即可。
5.1.2 Spring MVC连接
创建⼀个 TestController 类,实现⽤户到 Spring 程序的互联互通,具体实现代码如下:
这里使用@Controller注解 (@Service @Component注解也能达到效果 但不建议这么写)
@RestController = @ResponseBody + @Controller
这样实现后,访问地址: http://localhost:8080/test/hi 就可以显示 hi,spring mvc~
5.1.3@RequestMapping 注解介绍
@RequestMapping 是 Spring Web 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的路由映射的。
路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射。
-
@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + ⽅法。
-
@RequestMapping 也可以直接修饰⽅法
-
5.1.4@RequestMapping 是 post 还是 get 请求?
我们使⽤ PostMan 测试⼀下,默认情况下使⽤注解 @RequestMapping 是否可以接收 GET 或 POST 请求。
- 既支持GET方式的请求又支持POST方式的请求
5.1.5指定 GET/POST 方法类型
我们可以显示的指定 @RequestMapping 来接收 POST 的情况
此时非POST请求不能正常访问
更简单的写法:
GET请求同理~
5.2获取参数
5.2.1传递单个参数
在 Spring MVC 中可以直接⽤⽅法中的参数来实现传参
使用postman测试
- 不传参数,默认为null
- 传递参数name=wzt(key一定要和设置的参数名一样)
注意: 在Spring Boot(Spring MVC)中传参一定要传包装类型,而非基础类型当需要一个基础类型,但又忘记传递参数的时候,使用基础类型会报错(500),而包装类型不会报错,只是值为null
5.2.2传递对象
Spring MVC 可以⾃动实现参数对象的赋值
这里我们创建一个User对象:
传递代码实现:
前端访问:
对象中的属性就是key
5.2.3表单参数传递/传递多个参数(非对象)
前端访问:
说明: 当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置 是不影响后端获取参数的结果。
5.2.4 后端参数重命名(后端参数映射)
某些特殊的情况下 (前后端分离) ,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个time 给后端,⽽后端⼜是有 createtime 字段来接收的,这样就会出现参数接收不到的情况。
如果出现这种情况,我们就可以使⽤ @RequestParam来重命名前后端的参数值。
具体示例
后端实现代码:
前端访问:
5.2.5 设置参数必传@RequestParam
上⾯的列⼦,如果我们是前端传递⼀个⾮ t 或者 t2 的参数,就会出现程序报错的情况,如下图所示:
这是因为后端已经声明了前端必须传递⼀个 t 或者 t2 的参数,但是前端没有给后端传递!!!
我们查看@RequestParam 注解的实现细节就可以发现原因,注解实现如下:
⾮必传参数设置
如果我们的实际业务前端的参数是⼀个⾮必传的参数,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错,具体实现如下:
5.2.6@RequestBody 接收JSON对象
后端接收代码:
前端访问:
5.2.7 获取URL(BaseURL)中直接获取参数@PathVariable
后端实现:
前端访问:
注意事项:@PostMapping(“/login/{username}/{password}”) 中的 {password} 参数不能省略。
5.2.8 上传文件@RequestPart
简单的img.png文件上传
后端实现
前端访问
最终版
5.2.9 获取Cookie/Session/header
获取全部Cookie – 采用日志打印
获取单个Cookie
获取 Cookie—@CookieValue
获取 Header—@RequestHeader
Session 存储和获取
Session 存储和 Servlet 类似,是使⽤ HttpServletRequest 中获取的
读取 Session 可以使⽤ HttpServletRequest
获取 Session 更简洁的⽅式:
5.3返回数据
通过上⾯的学习我们知道,默认请求下⽆论是 Spring MVC 或者是 Spring Boot 返回的是视图(xxx.html),⽽现在都是前后端分离的,后端只需要返给给前端数据即可,这个时候我们就不需要使⽤@ResponseBody 注解了。
3.3.1返回静态页面
创建前端⻚⾯ index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello,spring mvc</title>
</head>
<body>
<h1>Hello,Spring MVC.</h1>
</body>
</html>
后端返回html / text
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/resp")
public class RespController {
@RequestMapping("/hi")
public String sayHi(){
return "/index.html";
}
}
练习:实现计算器功能
可使⽤ postman 传递参数,或使⽤ form 表单的⽅式提交参数。
前端⻚⾯:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.
0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>计算器示例</title>
</head>
<body>
<form action="http://localhost:8080/calc">
<div style="margin-top: 100px;text-align: center">
<h1>计算器</h1>
<div>数字1:<input name="num1" type="text"></div>
<div>数字2:<input name="num2" type="text"></div>
<div><input type="submit" value=" 点击相加 "></div>
</div>
</form>
</body>
</html>
controller 代码:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@ResponseBody
public class CalcController {
@RequestMapping("/calc")
public String calc(Integer num1,Integer num2){
if (num1==null||num2==null)
return "参数错误";
return "sum = " + (num1 + num2);
}
}
5.3.2 返回 JSON 对象
key - value 选择 HashMap
@RequestMapping("/respJson")
@ResponseBody
public HashMap<String, String> respJson() {
HashMap<String, String> map = new HashMap<>();
map.put("Java", "Java Value");
map.put("MySQL", "MySQL Value");
map.put("Redis", "Redis Value");
return map;
}
使用Fiddler抓包查看:
5.3.3 请求转发或请求重定向
forward VS redirect return 不但可以返回⼀个视图,还可以实现跳转,跳转的⽅式有两种:
forward 是请求转发;
redirect:请求重定向。
举例说明 forward 和 redirect
forward(请求转发)和redirect(请求重定向)的区别,举例来说,例如,你告诉你妈妈,你想吃辣条,如果你妈妈,说好,我帮你去买,这就是 forward请求转发;如果你妈妈让你⾃⼰去买,那么就是请求 redirect 重定向。
“转发”和“重定向”理解:在中国官⽅发布的内容越少事也越⼤,“转发”和“重定向”也是⼀样:字越少,责任越⼤。转发是服务器帮转的,⽽重定向是让浏览器重新请求另⼀个地址。
请求转发和重定向的使⽤对⽐:
// 请求重定向
@RequestMapping("/index")
public String index(){
return "redirect:/index.html";
}
// 请求转发
@RequestMapping("/index2")
public String index2(){
return "forward:/index.html";
}
forward 和 redirect 具体区别如下:
- 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
- 请求重定向地址发⽣变化,请求转发地址不发⽣变化。
- 请求重定向与直接访问新地址效果一致,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。
小细节
@ResponseBody 说明
@ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成application/json 返回给前端。
@ResponseBody 可以⽤来修饰⽅法或者是修饰类,修饰类表示类中的所有⽅法都会返回 html 或者json,⽽不是视图。
组合注解:@RestController
@RestController = @Controller + @ResponseBody
查看更多注解
官⽅ API:
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping