–什么是Spring Web MVC?
官网描述
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名“Spring Web MVC”来⾃其源模块的名称(Springwebmvc),通常被称为Spring MVC.
所以Spring Web MVC 是⼀个 Web 框架
MVC的定义
MVC分别是Model(模型) View(试图) Controller(控制器)的缩写 它是软件工程的一种软件架构设计模式
MVC 是⼀种架构设计模式, 也⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现. 除此之外,SpringMVC还是⼀个Web框架
SpringBoot 是实现了Spring MVC的其中⼀种⽅式Spring Boot 通过添加Spring WebMVC框架, 来实现web功能
随着时代的发展Spring在实现MVC时 后端人员不会编写前端的代码所以这里的view会变成视图所需要的数据
学习Spring MVC
spring 是web框架 当用户输入url后 项目就可以给予响应
主要分为三个方面
(1)建立连接(客户端和服务器)
这么建立连接?
我们通过@RequestMapping(路由映射)建立连接
什么是路由映射?
当⽤⼾访问⼀个 URL 时, 将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射
@RequestMapping它是⽤来注册接⼝的路由映射的表⽰服务收到请求时, 路径为 /sayHi 的请求就会调⽤ sayHi 这个⽅法的代码
@RequestMapping可以修饰方法也可以修饰类
访问地址为:类的路径加上方法路径
如果类没有@RequestMapping 类路径就是空的这时就直接访问方法的路径
package com.example.demo.demos.web.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@RequestMapping("/sayhi")public String sayHi(){return "hi,SpringBoot";}@RequestMapping("/sayhello")public String sayhello(){return "hello,SpringBoot";}
}
此时加上@RequestMapping修饰类
我们在访问时就要加上类的路径
@RequestMapping也支持 get和set方法
当我们使用postman发送方式各种请求时
各种请求方式都会支持 所以当我们使用@RequestMapping就不要专门些请求方法了
但是@RequestMapping也可以指定方法
例如让方法只支持get:
当我们发送post请求而不是get请求时就会被告知方法不允许 使用限制请求方式就使用method属性
我们查看@RequestMapping的源码可以发现当只有一个参数时 就是默认代表方法的路径 当有两个参数时我们就要加上属性名 value/path=" " method=" "
(2)请求
请求就是如何传参
普通传参, 也就是通过查询字符串来传参
其中查询字符串就是请求的参数
传递单个参数
package com.example.demo.demos.web.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/param")
@RestController
public class ParanController {@RequestMapping("/m1")public String m1(String name){return "接收到的参数name:"+name;}
}
我们在请求中
传递多个参数
package com.example.demo.demos.web.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/param")
@RestController
public class ParanController {@RequestMapping("/m1")public String m1(String name){return "接收到的参数name:"+name;}@RequestMapping("/m2")public String m2(String name ,int age){return "接收到的参数name:"+name+"接收到的参数age"+age;}
}
发送参数的数据也可以调换
注意:
如果使用基本类型必须要传值 不传就会报错
说的是基本类型不能转为null 还建议使用包装类型
所以开发时建议使用包装类
当我们传入空值时是允许的
传递对象
@RequestMapping("/m4")public String m4(Person person){return "接收到的参数person:"+person.toString();}public class Person {public String name;public Integer age;public Integer id;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", id=" + id +'}';}
}
传递对象直接去发 Spring会直接帮我们进行映射
开发中 接口的参数定义为对象
方法中的重命名
为了达到代码的高可用 我们前端的代码时"name"后端时确实username这时应该进行后端参数重命名
package com.example.demo.demos.web.controller;import com.example.demo.demos.web.Person;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/param")
@RestController
public class ParanController {@RequestMapping("/m1")public String m1(String name){return "接收到的参数name:"+name;}@RequestMapping("/m2")public String m2(String name ,int age){return "接收到的参数name:"+name+"接收到的参数age"+age;}@RequestMapping("/m3")public String m3(String name , Integer age){return "接收到的参数name:"+name+"接收到的参数age"+age;}@RequestMapping("/m4")public String m4(Person person){return "接收到的参数person:"+person.toString();}@RequestMapping("/m5")public String m5(@RequestParam("name") String username){return "接收到的参数name:"+ username;}
}
我们发送请求时可以直接写查询字符串name
但是当我们写入后端参数名username的时候却会报错
但是一般来说不会报错而是显示name为空
我们查看原因
这里说的是需要name的参数
也就是说使用了@RequestParam之后name变成了必传参数 此时我们只需要将代码改成
此时再使用username传入参数显示为null
所以此时说明不能使用后端参数传入
传递数组
当我们请求中同时一个参数有多个时 浏览器就会给我们封装成一个数组
public String m6(String[] arrayParam){return "接受到的参数arrayParam:" + arrayParam.toString()+"长度"+arrayParam.length;}
传递集合
集合参数:和数组类似同一个请求参数名有多个
@RequestMapping("/m7")public String m7(@RequestParam(required = false) List<String> listParam){return "收到的参数listParam"+ listParam + ",长度"+listParam.size();}
请求⽅式和数组类似:
传递JSON数据
@RequestBody 注解 能指定传递jasn的格式
//使用json格式发送请求@RequestMapping("/m8")public String m8(@RequestBody Person person){return "接受到的数据person:"+ person.toString();}
使⽤Postman来发送json请求参数
可以通过Fiddler查看请求参数
获取URL中的参数
注解@PathVariable 能获取URL的参数
注意这里的参数顺序不能相反
@RequestMapping("/m9/{userId}/{name}")public String m9(@PathVariable Integer userId,@PathVariable String name){return "userId"+userId+"name"+name;}
上传⽂件
我们上传一张图片
注解@RequestPart
使⽤Postman发送请求:
@RequestMapping("/10")public String m10(@RequestPart MultipartFile file){System.out.println(file.getOriginalFilename());return "success";}
可以看到传送成功了
我们将⽂件上传到指定路径再验证一下
@RequestMapping("/m10")public String m10(@RequestPart MultipartFile file) throws IOException {file.transferTo(new File("C:\\Users\\86188\\Desktop\\test\\" + file.getOriginalFilename()));return "接收到⽂件名称为:" + file.getOriginalFilename();}
获取Cookie和Session
HTTP协议自身是属于"无状态"协议
无状态是 默认情况下HTTP协议的客户端和服务器之间的通信和下次通信之间没有直接联系
但是在实际之中我们很多时候需要请求之间的关联
例如登录一个网站第二次访问服务器时就知道是否登录过
这里的令牌就储存在Cookie字段
此时在服务器需要记录"令牌"信息 对应令牌用户的用户信息就是Session机制所做的工作
Session会话
A和B交流产生一个会话
A和C交流产生一个会话
会话是一个客户与服务器之间不中断的请求响应 对客户每个请求 服务器能识别请求来自那一个客户 当一个未知客户向web 应用程序发送一个请求就开始一个会话当客户结束会话或服务器在一个时限内没有接受到客户的任何请求时会话就结束了
Session是服务器为了保存用户信息创建的一个特殊对象
获取Cookie
传统获取Cookie
@RequestMapping("/m11")public String getCookie(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;}
此时如果没有设置Cookie通过浏览器发起请求就得到Cookie为null
然后我们使用浏览器设置Cookie之后会有
更多工具->开发人员工具->应用程序
然后我们刷新就会看到
然后使用注解方式获取Cookie但只能一个个获取
@RequestMapping("/m12")public String getCookie2(@CookieValue String name){return "cookie存储的值name:" + name;}
使用浏览器获取请求
Session存储
@RequestMapping("/m16")public String setSession(HttpServletRequest request){HttpSession session = request.getSession();if(session!=null){session.setAttribute("username","张三");}return "succes";}
通过浏览器查看
通过Fiddler观察Http请求和响应情况
获取session的几种方法
@RequestMapping("/m13")public String getSession(HttpServletRequest request){//如果session不存在不会自动创建HttpSession session = request.getSession(false);if(session != null){String username = (String)session.getAttribute("username");return "登录用户:" + username;}return "session 为空";}@RequestMapping("/m14")public String getSession2(@SessionAttribute String username){return "username:" + username;}@RequestMapping("/m15")public String getSession3(HttpSession session){String username = (String)session.getAttribute("username");return "登录用户:" + username;}
获取header