什么是Spring Web MVC
Spring Web MVC是⼀个Web框架.下⾯咱们简称之为:Spring MVC
MVC的定义
MVC是Model View Controller的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分
View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
Controller(控制器) 可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型
Spring MVC是⼀个实现了MVC模式的Web框架
其实,Spring MVC我们在前⾯已经⽤过了,在创建Spring Boot项⽬时,我们勾选的Spring Web框架其实就是Spring MVC框架。不过Spring在实现MVC时, 也结合⾃⾝项⽬的特点, 做了⼀些改变, 相对⽽⾔, 下⾯这个图或许更加合适⼀些

学习Spring MVC
建立连接,请求,响应。只要掌握了这三个功能,就等于掌握了Spring MVC。
在 Spring MVC中使⽤ @RequestMapping 来实现URL路由映射,也就是浏览器连接程序的作⽤
java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@RestController
public class UserController {
// 路由器规则注册
@RequestMapping("/sayHi")
public String sayHi(){
return "hello,Spring MVC";
}
}
@RequestMapping 是Spring Web MVC应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的路由映射的。例如http://127.0.0.1:8080/sayHi后面的"/sayHi"就是映射,会调用这个接口下面的代码。
@RestController作用:⼀个项⽬中,会有很多类,每个类可能有很多的⽅法,Spring程序怎么知道要执⾏哪个⽅法呢? Spring会对所有的类进⾏扫描,如果类加了注解@RestController,Spring才会去看这个类⾥⾯的⽅法有没有加@RequestMapping 这个注解,当然他的作⽤不⽌这⼀点,咱们先⽤,后⾯再详细讲
@RequestMapping的URL路径最前⾯加不加 / (斜杠)都可以,Spring程序启动时,会进⾏判断,如果前⾯没有加 / ,Spring会拼接上⼀个 /。但建议规范还是加上比较好
@RequestMapping 既⽀持Get请求,⼜⽀持Post请求.同理,也⽀持其他的请求⽅式
java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@RestController
public class UserController {
@RequestMapping(value = "/getRequest",method= RequestMethod.POST)
public String sayHi(){
return "get request...";
}
}
代码中指定了POST请求方式,当只传一个参数,不用写前面形参。
Postman
用于对后端代码进行测试
请求
访问不同的路径,就是发送不同的请求.在发送请求时,可能会带⼀些参数,所以学习Spring的请求,主要是学习如何传递参数到后端以及后端如何接收。我们一般用浏览器和Postman来进行测试
传递单个参数
java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/m1")
public String method1(String name){
return "接收到参数name:"+ name;
}
}
使⽤基本类型来接收参数时,参数必须传(除boolean类型),否则会报500错误。若传参类型不相符回报400错误。
传递多个参数
java
@RequestMapping("/m2")
public Object method2(String name, String password) {
return "接收到参数name:" + name + ", password:" + password;
}
传递对象
java
@RequestMapping("/m3")
public Object method3(Person p){
return p.toString();
}
对象中的类型可以为基本类型,而直接传参最好不要使用基本类型。因为对象中的基本类型会被赋初值。
后端参数重命名(后端参数映射)
一般情况,后端的参数要与前端保持一致。但可以通过重命名来进行修改
java
@RequestMapping("/m4")
public Object method_4(@RequestParam("time") String createtime) {
return "接收到参数createtime:" + createtime;
}
这样前端的参数time就改为了后端的createtime。但这时,参数就变成了必传参数将required改为false就可以不传参数。
传递数组
java
@RequestMapping("/m5")
public String method5(String[] arrayParam) {
return Arrays.toString(arrayParam);
}

传递集合
集合参数:和数组类似,同⼀个请求参数名有为多个,且需要使⽤ @RequestParam 绑定参数关系
⽅式⼀:http://127.0.0.1:8080/param/m6listParam=zhangsan\&listParam=lisi\&listParam=wangwu
⽅式⼆:http://127.0.0.1:8080/param/m6?listParam=zhangsan%2Clisi%2Cwangwu
java
@RequestMapping("/m6")
public String method6(@RequestParam List<String> listParam){
return "size:"+listParam.size() + ",listParam:"+listParam;
}
传递JSON数据
JSON语法
java
{
"squadName": "Super hero squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [{
"name": "Molecule Man",
"age": 29,
"secretIdentity": "Dan Jukes",
"powers": ["Radiation resistance", "Turning tiny", "Radiation blast"
}, {
"name": "Madame Uppercut",
"age": 39,
"secretIdentity": "Jane Wilson",
"powers": ["Million tonne punch", "Damage resistance", "Superhuman r
}, {
"name": "Eternal Flame",
"age": 1000000,
"secretIdentity": "Unknown",
"powers": ["Immortality", "Heat Immunity", "Inferno", "Teleportation
}]
}

后端接受JSON对象
java
@RequestMapping(value = "/m7")
public Object method7(@RequestBody Person person) {
return person.toString();
}
加上@RequestBody来接受JSON对象
获取URL中参数@PathVariable
java
@RequestMapping("/m8/{id}/{name}")
public String method8(@PathVariable Integer id, @PathVariable("name") String use
return "解析参数id:"+id+",name:"+userName;
}

上传⽂件@RequestPart
java
@RequestMapping("/m9")
public String getfile(@RequestPart("file") MultipartFile file) throws IOExceptio
//获取⽂件名称
String fileName = file.getOriginalFilename();
//⽂件上传到指定路径
file.transferTo(new File("D:/temp/" + file.getOriginalFilename()));
return "接收到⽂件名称为: "+fileName;
}
获取Cookie/Session
简单来讲Cookie属于客户端,Session属于服务端
其中令牌一般就存在Cookie中
Session

Session的本质就是⼀个"哈希表",存储了⼀些键值对结构.Key就是SessionID,Value就是用户信息(用户信息可以根据需求灵活设计)
Cookie和Session之间主要是通过SessionId关联起来的,SessionId是Cookie和Session之间的桥梁
获取Cookie
java
@RequestMapping("/m10")
public String method10(HttpServletRequest request,HttpServletResponse response){
// 获取所有 cookie 信息
Cookie[] cookies = request.getCookies();
//打印Cookie信息
StringBuilder builder = new StringBuilder();
if (cookies!=null){
for (Cookie ck:cookies) {
builder.append(ck.getName()+":"+ck.getValue());
}
}
return "Cookie信息:"+builder;
}
@RequestMapping("/getCookie")
public String cookie(@CookieValue("bite") String bite) {
return "bite:" + bite;
}
获取Session
Session是服务器端的机制,我们需要先存储,才能再获取
Session存储
java
@RequestMapping("/setSess")
public String setsess(HttpServletRequest request) {
// 获取Session对象
HttpSession session = request.getSession();
if (session != null) {
session.setAttribute("username", "java");
}
return "session 存储成功";
}
Session读取
java
@RequestMapping("/getSess")
public String sess(HttpServletRequest request) {
// 如果 session 不存在, 不会⾃动创建
HttpSession session = request.getSession(false);
String username = null;
if (session != null && session.getAttribute("username") != null) {
username = (String) session.getAttribute("username");
}
return "username:" + username;
}
@RequestMapping("/getSess3")
public String sess3(HttpSession session) {
String username = (String)session.getAttribute("username");
return "username:"+username;
}
获取Header
java
@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
String userAgent = request.getHeader("User-Agent");
return name + ":"+userAgent;
}
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
return "userAgent:"+userAgent;
}
响应
@RestController = @Controller + @ResponseBody
@Controller :定义⼀个控制器,Spring框架启动时加载,把这个对象交给Spring管理.
@ResponseBody :定义返回的数据格式为⾮视图,返回⼀个text/html信息
如果要想返回视图,去掉@ResponseBody即返回@Controller即可
java
@Controller
public class IndexController {
@RequestMapping("/index")
public Object index(){
return "/index.html";
}
@RequestMapping("/returnData")
public String returnData(){
return "该⽅法返回数据";
}
}
这里下面代码没有加@ResponseBody,会默认返回视图,就会报错
后端返回数据时,如果数据中有HTML代码,也会被浏览器解析