文章目录
- 一、Spring Boot Web MVC 概念
- 二、状态码
- 三、其他注解
- 四、响应操作
一、Spring Boot Web MVC 概念
Spring Web MVC 是⼀个 Web 框架,一开始就包含在Spring 框架里。
1. MVC 定义
软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分
2. 什么是Spring MVC
MVC 是⼀种架构设计模式, 也⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现
Spring MVC 是⼀个实现了 MVC 模式的 Web 框架
Spring Boot 只是实现Spring MVC的其中⼀种方式而已
Spring Boot 实现了MVC思想后,就被称为Spring MVC,可以实现 web功能
Spring Boot 可以添加很多依赖, 借助这些依赖实现不同的功能. Spring Boot 通过添加Spring Web MVC框架, 来实现web功能
Spring Boot 结合自身特点的情况,如下图,不过核心依旧没变
3. Spring Boot 不同的传参介绍
- 普通传参, 也就是通过查询字符串来传参
- form-data
- x-www-form-urlencoded
- raw
- 可以上传任意格式的⽂本,可以上传text、json、xml、html等
4. Spring Boot 不同的传参方式
如果使用的是基本类型,必须要传值,不然会报错,因为基本类型无法被赋值null
(1)传递单个参数
限制方法
@RequestMapping(value = "demo1",method = RequestMethod.PUT)
public String demo1(String name){
return "接收到的name:" + name;
}
不限制方法
@RequestMapping("demo1")
public String demo1(String name){
return "接收到的name:" + name;
}
(2)传递多个参数
多个参数发送的时候,顺序是无所谓的
@RequestMapping("demo2")
public String demo2(String name, Integer age){
return "接受到的name:" + name + ",age:" + age;
}
(3)传递对象
@RequestMapping("demo3")
public String demo3(Person person){
return person.toString();
}
@RequestMapping("demo4")
public String demo4(@RequestParam("name") String username){
return "接收到的name:" + username;
}
如果进行了重命名,就必须要使用@RequestParam注解里的名字
想要把name变成非必传参数
计算机这边正规的还是name,但是程序员这边是用username代替了name
(4)传递数组/集合
@RequestMapping("demo5")
public String demo5(String[] str){
return "接收到的数组:" + str.toString() + ",长度是:" + str.length;
}
如果传的是一个列表,idea会把列表默认为数组,需要一个@RequestParam注解,才能让idea知道这个是列表
@RequestMapping("/demo6")
public String m7(@RequestParam(required = false,defaultValue = "zhangsan,lisi,wangwu,zhaoliu") List<String> listParam){
return "接收到的参数listParam:"+ listParam + ",长度:"+listParam.size();
}
(5)传递JSON数据
Json 只能接收正文的,而且只能接收JSON字符串格式
工作中,上面四种传参方式都不常用,比起传单个/多个数据,还是更倾向于传对象,但是上述方法太过繁琐,我们一般使用JSON传递数据
概念:本质上是一个字符串,有着自己的格式和语法,可以描述数据信息
语法:
(1)数据在 键值对(Key/Value) 中
(2)数据由逗号 , 分隔
(3)对象⽤ {} 表⽰
(4)数组⽤ [] 表⽰
(5)值可以为对象, 也可以为数组, 数组中可以包含多个对象
传递方法:
接收JSON对象, 需要使⽤ @RequestBody 注解
原理:赋值是要key=XXX的格式,但是JSON本质是一个字符串,是一整个数据,需要转换
二、状态码
- http状态码,不是后端定义的
- 5XX通常指服务端发生错误,4XX通常指客户端发生错误,3XX通常是重定向,2XX通常表示成功
- 业务状态码,后端定义的,无法作假
三、其他注解
1. 获取URL中参数@PathVariable
@PathVariable:用来获取url路径上的数据绑定
@RequestMapping("/demo8/{name}/{wendiage}")
public String demo8(@PathVariable String name, @PathVariable("wendiage") Integer age){
return "解析的name:" + name + ", age:" + age;
}
- 查找url的时候,要准确对应
2. 上传文件@RequestPart
@RequestMapping("/demo9")
public String demo9(@RequestPart MultipartFile file) throws IOException {
System.out.println(file.getOriginalFilename());
file.transferTo(new File("D:/else/" + file.getOriginalFilename()));
return "success";
}
3. 获取Cookie/Session
- 传统获取方式
- 简洁注解获取方式
这两个都是会话机制
(1) 概念理解
Cookie
Cookie 相当于学生证,注册完成之后,可以让保安知道是该学校的学生,并完成一系列操作
问题:是可以伪造的
Session
会话:⼀个客户与服务器之间的不中断的请求响应
本质上是个“哈希表”,用来存储用户的信息,确保服务器能够分辨出请求从属于哪个对话/用户
(1)Session是由服务器生成的唯一的标识符。Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失
(2)Session 是服务器端的,无法伪造,需要写代码手动添加。在内存中存储,服务器重启后,就会被清空
(3)问题:分布式情况下,会多创建Session
Cookie 和 Session 的区别
- Cookie 是客⼾端保存⽤⼾信息的⼀种机制,Session 是服务器端保存⽤⼾信息的⼀种机制
- Cookie 和 Session之间主要是通过 SessionId 关联起来的
- Cookie 和 Session 经常会在⼀起配合使⽤. 但是不是必须配合
(2) 获取Cookie 代码
Spring 是基于servlet创建的,所以servlet支持的,Spring 都支持
//拿到所有的Cookie
@RequestMapping("/demo10")
public String demo10(HttpServletRequest request, HttpServletResponse response){
//Spring内置对象
Cookie[] cookies = request.getCookies();
StringBuilder builder = new StringBuilder();
if (cookies != null){
for (Cookie ck : cookies){
builder.append(ck.getName() + ":" + ck.getValue());
}
}
return "Cookie信息:" + builder;
}
//使用注解的方式,一个一个去拿
@RequestMapping("/demo11")
public String cookie(@CookieValue("kunjuan") String bite) {
return "bite:" + bite;
}
Cookie 的值需要设置,浏览器 F12打开开发者工具,可以手动设置,但也因说明Cookie是可以伪造的, 也就是不安全的, 所以使⽤Cookie时, 后端需要进⾏Cookie校验
(3) Session 代码
解析:getSession 内部提取到请求中Cookie里的SessionId,然后根据SessionId获取到对应的Session 对象, Session 对象⽤HttpSession来描述
Session 存储:
@RequestMapping("/setSess")
public String setsess(HttpServletRequest request) {
// 获取Session对象
HttpSession session = request.getSession();
if (session != null) {
session.setAttribute("username", "java");
}
return "session 存储成功";
}
Session 读取:
@RequestMapping("/getSess1")
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("/getSession2")
public String getSession2(@SessionAttribute(required = false) String username){
//@SessionAttribute 默认是一个必传参数
return "username:"+username;
}
@RequestMapping("/getSession3")
public String getSession3(HttpSession session){
String username = (String)session.getAttribute("username");
return "登录用户:"+username;
}
//HttpSession session 等同于 HttpSession session = request.getSession(true)
(4) Cookie 和Session 的联系
(1)当一台电脑打开了多个浏览器,每一个浏览器对应的服务器都会创建一个会话,但是服务器之间是不知道这些浏览器都是由用户一个人打开的,服务器每一个会话都会记录一个SessionId,而每一个Id都会对应一个SessionValue,value 里面存了许多值。
(2)后台服务器会把SessionId告诉客户端,把SessionId存到Cookie里面,后面再访问的时候,就会带着SessionId去访问。服务器就可以根据SessionId 带你去拿到这个SessionId对象
3. 获取header
@RequestMapping("/getHeader")
public String getHeader(HttpServletRequest request){
String userAgent = request.getHeader("User-Agent");
return "userAgent:"+userAgent;
}
@RequestMapping("/getHeader2")
public String getHeader2(@RequestHeader("User-Agent") String userAgent){
return "userAgent:"+userAgent;
}
四、响应操作
- Http响应结果可以是数据, 也可以是静态页面,也可以针对响应设置状态码, Header信息等
- 多个注解时, 没有先后顺序, 先写哪个都可以
- 响应中的 Content-Type 常见取值有以下几种:
- text/html : body 数据格式是 HTML
- text/css : body 数据格式是 CSS
- application/javascript : body 数据格式是 JavaScript
- application/json : body 数据格式是 JSON
1. 返回静态页面
Content-Type 为 text/htm
@RestController
@RequestMapping("/return")
public class returnController {
@RequestMapping("/htmlTest")
public String htmlTest(){
return "/index.html";
}
}
@Controller
@RequestMapping("/return")
public class returnController {
@RequestMapping("/index")
public String htmlTest2(){
return "/index.html";
}
}
(1)解析
@RestController
@RestController 定义返回的数据格式为非视图, 返回⼀个 text/html 信息,即返回的是正文信息
@Controller
@Controller 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理
ResponseBody
@ResponseBody,定义返回的数据格式为⾮视图, 返回⼀个 text/html 信息
生命周期:活在代码里,编译后,就消失了
2. 返回数据
可以修饰类,也可以修饰方法。修饰类的时候,表示这个类下的所有方法,返回的均为数据,修饰方法时,表示该方法返回的是数据
@ResponseBody
@RequestMapping("/index2")
public String htmlTest3(){
return "/index.html";
}
Content-Type 为 text/htm
3. 返回HTML代码片段
@ResponseBody
@RequestMapping("/returnHtml")
public String returnHtml(){
return "<h1>返回HTML代码片段</h1>";
}
Content-Type 为 text/htm
4. 返回JSON
@ResponseBody
@RequestMapping("/returnJson")
public Person returnJson(){
Person person = new Person();
person.setId(1);
person.setName("zhangsan");
person.setAge(7);
return person;
}
当我们的接口返回的是对象时,Content-Type 为 application/json
5. 设置状态码
Spring MVC会根据我们⽅法的返回结果自动设置响应状态码, 程序员也可以⼿动指定状态码
@ResponseBody
@RequestMapping("/setStatus")
public String setStatus(HttpServletResponse response){
response.setStatus(401);//通常表示没有登录
return "设置状态码";
}
6. 设置header
@ResponseBody
@RequestMapping(value = "/r1",produces = "application/json;charset=utf-8")
public String r1(HttpServletResponse response){
//设置header
response.setHeader("myhead","myhead");
return "{'OK':1}";
}
- consumes:限制能够处理的请求,不是这个请求的处理不了
- produces:设置返回的内容类型