什么是 Spring Web MVC
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称"Spring Web MVC"来⾃其源模块的名称(Spring-webmvc),但它通常被称为)Spring
MVC)
Spring Web MVC 是⼀个 Web 框架,简称为 Spring MVC
Spring MVC 定义
MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分
• View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源
• Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分
Controller(控制器)可以理解为⼀个分发器,用来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即用来连接视图和模型
什么是 Spring MVC
MVC 是⼀种架构设计模式, 也⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现. 除此之外, Spring MVC还是⼀个Web框架
总结来说,Spring MVC 是⼀个实现了 MVC 模式的 Web 框架
所以, Spring MVC主要关注有两个点:
- MVC
- Web框架
Spring MVC 全称是 Spring Web MVC
Spring在实现MVC时, 也结合⾃⾝项⽬的特点, 做了⼀些改变, 相对⽽⾔, 上面这个图或许更加合适
⼀些
学习 Spring MVC
既然是 Web 框架, 那么当⽤⼾在浏览器中输⼊了 url 之后,我们的 Spring MVC 项⽬就可以感知到⽤⼾的请求, 并给予响应
咱们学习Spring MVC, 重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互
主要分以下三个⽅⾯:
- 建⽴连接:将⽤⼾(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的
Spring 程序 - 请求: ⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数, 所以请求这块主要是 获取参数 的功能
- 响应: 执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤⼾, 也就是响应
项目创建
Spring MVC 项⽬创建和 Spring Boot 创建项⽬相同,在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项⽬
创建项⽬时, 勾选上 Spring Web 模块即可
建立连接
在 Spring MVC 中使⽤ @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作⽤
创建⼀个 UserController 类,实现⽤⼾通过浏览器和程序的交互:
package com.example.demo; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @RequestMapping("sayhi") public String sayHi(){ return "hi MVC"; } }
⽅法名和路径名称(@RequestMapping) ⽆需⼀致
@RequestMapping 介绍
@RequestMapping 是 Spring Web MVC 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的
路由映射的
表⽰服务收到请求时, 路径为 /sayhi 的请求就会调⽤ sayHi 这个⽅法的代码
路由映射: 当⽤⼾访问⼀个 URL 时, 将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射
Spring会对所有的类进⾏扫描, 如果类加了注解@RestController, Spring才会去看这个类⾥⾯的⽅法
@RequestMapping 使用
@RequestMapping 即可修饰类,也可以修饰⽅法 ,当修饰类和⽅法时,访问的地址是类路径 + ⽅法路径
@RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息
@RequestMapping标识⼀个⽅法:设置映射请求请求路径的具体信息
@RequestMapping("/user")@RestController public class UserController { @RequestMapping("sayhi") public String sayHi(){ return "hi MVC"; } }
注意:
@RequestMapping 的URL 路径最前⾯加不加 / (斜杠)都可以, Spring程序启动时, 会进⾏判断, 如果前⾯没有加 / , Spring会拼接上⼀个 /
通常情况下, 我们加上 /
@RequestMapping 的URL路径也可以是多层路径, 最终访问时, 依然是 类路径 + ⽅法路径
@RequestMapping 请求类型
GET请求:
浏览器发送的请求类型都是get, 通过以上案例, 可以看出来 @RequestMapping ⽀持get请求
POST 请求:
我们通过form表单来构造请求
@RequestMapping 既⽀持Get请求, ⼜⽀持Post请求. 同理, 也⽀持其他的请求⽅式
指定GET/POST⽅法类型
@RequestMapping(value = "sayhi",method = RequestMethod.GET) public String sayHi(){ return "hi MVC"; }
请求
postman
后端开发⼯程师测试⾃⼰的程序使⽤专业的接⼝测试⼯具
安装地址 Download Postman | Get Started for Free
创建请求
访问不同的路径, 就是发送不同的请求. 在发送请求时, 可能会带⼀些参数, 所以学习Spring的请求, 主要 是学习如何传递参数到后端以及后端如何接收
传递参数,此处用 Postman 模拟
传递单个参数
接收单个参数, 在 Spring MVC 中直接⽤⽅法中的参数就可以
@RequestMapping("/r1") public String r1(String name){ return "接受到字符串:"+name; }
Spring MVC 会根据⽅法的参数名, 找到对应的参数, 赋值给⽅法
如果参数不⼀致, 是获取不到参数的
@RequestMapping("/r2") public String r2(Integer age){ return "接受到字符串:"+age; }
@RequestMapping("/r3") public String r3(int age){ return "接受到字符串:"+age; }
age传值为 空值 age不传值
注意:
1)使⽤基本类型来接收参数时, 参数必须传(除boolean类型), 否则会报500错误
2)类型不匹配时, 会报400错误
3)对于包装类型, 如果不传对应参数,Spring 接收到的数据则为null
所以企业开发中,对于参数可能为空的数据,建议使⽤包装类型
传递多个参数
和接收单个参数⼀样, 直接使⽤⽅法的参数接收即可. 使⽤多个形参
@RequestMapping("/r4") public String r4(String name,Integer age){ return "接受到名字:"+name+",年龄:"+age; }
当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果
传递对象
如果参数⽐较多时, ⽅法声明就需要有很多形参. 并且后续每次新增⼀个参数, 也需要修改⽅法声明.
我们不妨把这些参数封装为⼀个对象
Spring MVC 也可以⾃动实现对象参数的赋值
import lombok.Data; @Data public class Student { private String name; private Integer id; private int age; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } }
此处使用使用注解 @Data (创建 getter and setter 方法)
@RequestMapping("/r5") public String r5(Student student){ return "接收到参数:student:"+student; }
Spring 会根据参数名称⾃动绑定到对象的各个属性上, 如果某个属性未传递, 则赋值为null(基本类型则赋值为默认初识值, ⽐如int类型的属性, 会被赋值为0)
后端参数重命名(后端参数映射)
某些特殊的情况下,前端传递的参数 key 和后端接收的 key 可以不⼀致
使用 @RequestParam 来重命名前后端的值
@RequestMapping("/r6") public String r6(@RequestParam("name") String useName){ return "接受到字符串:"+useName; }
Spring可以正确的把浏览器传递的参数name绑定到了后端参数useName参数上
此时浏览器使⽤useName进⾏参数传递
- 使⽤ @RequestParam 进⾏参数重命名时, 请求参数只能和 @RequestParam 声明的名称⼀致, 才能进⾏参数绑定和赋值.
- 使⽤ @RequestParam 进⾏参数重命名时, 参数就变成了必传参数
⾮必传参数设置
添加required=false之后, time前⾯也加了key, 变成了 value = "name"
注解属性赋值时, 没有指明key的话, 默认为value属性.
如果需要有多个属性进⾏赋值时, 需要写上key
@RequestMapping("/r7") public String r7(@RequestParam(value = "name",required = false) String useName){ return "接受到字符串:"+useName; }
传递数组
Spring MVC 可以⾃动绑定数组参数的赋值
@RequestMapping("/r8") public String r8(String[] array){ return "接受的字符串是:"+ Arrays.toString(array); }
key相同时,会组装成一个数组
数组参数:请求参数名与形参数组名称相同且请求参数为多个, 后端定义数组类型形参即可接收参数
传递集合
集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使⽤ @RequestParam 绑定参数关系
默认情况下,请求中参数名相同的多个值,是封装到数组. 如果要封装到集合,要使⽤@RequestParam 绑定参数关系
@RequestMapping("/r10") public String r10(@RequestParam(required = false) List<String> list){ return "接受的集合是:"+ list; }
⾮必传参数设置 required = false
传递JSON数据
JSON ------ JavaScript Object Notation 【JavaScript 对象表⽰法】
JSON就是⼀种数据格式, 有⾃⼰的格式和语法, 使⽤⽂本表⽰⼀个对象或数组的信息, 因此
JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换
JSON 是⼀个字符串,其格式⾮常类似于 JavaScript 对象字⾯量的格式
import lombok.Data; @Data public class Student { private String name; private Integer id; private int age; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } } @RequestMapping("/r11") public String r11(@RequestBody Student student){ return "接收到参数:student:"+student; }
接收JSON对象, 需要使⽤ @RequestBody 注解
RequestBody: 请求正⽂,意思是这个注解作⽤在请求正⽂的数据绑定,请求参数必须在写在请求正⽂中
@RequestMapping("/r5") public String r5(Student student){ return "接收到参数:student:"+student; } r5 是发送对象/普通参数 r11 是发送Json(一个对象)
JSON字符串和对象的转换,需要借助第三方工具
jackson
fastjson
fastjson2
Spring MVC框架也集成了JSON的转换⼯具,可以直接使⽤ public class Json { public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String jsonstr = "{\n" + " \"id\":12,\n" + " \"name\":\"ming\",\n" + " \"age\":17\n" + "}"; //JSON字符串转对象 Student student = objectMapper.readValue(jsonstr,Student.class); System.out.println(student); //对象转JSON字符串 String s = objectMapper.writeValueAsString(student); System.out.println(s); } }
获取URL中参数@PathVariable
path variable: 路径变量
和字⾯表达的意思⼀样, 这个注解主要作⽤在请求URL路径上的数据绑定
默认传递参数写在URL上,SpringMVC就可以获取到
@RequestMapping("/article/{articleId}/{name}") //顺序不能错或少 public String r13(@PathVariable("articleId") Integer articleId,@PathVariable("name") String name) { return "接收到参数:" + articleId + " ," + name; }
如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时, 可以简写, 不⽤给@PathVariable的属性赋值, 如上述例⼦中的id变量
如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时, 需要@PathVariable的属性value赋值,如上述例⼦中的userName变量
上传⽂件@RequestPart
@RequestMapping("/r14") public String r14(@RequestPart("file") MultipartFile imgfile){ //获取文件名 String originalFilename = imgfile.getOriginalFilename(); //文件上传指定路径 imgfile.transferTo(new File("D:" + imgfile.getOriginalFilename())); return "接收到文件名为:"+originalFilename; }
获取Cookie/Session
Cookie
HTTP 协议⾃⾝是属于 "⽆状态" 协议
"⽆状态" 的含义指的是:
默认情况下 HTTP 协议的客⼾端和服务器之间的这次通信, 和下次通信之间没有直接的联系
- 客户端 输入用户名和密码
- 服务器 进行校验,检验成功返回 token/令牌
- 客户端再次访问时带上token
- 服务器校验 token 是否合法 ------该过程也是无状态的
上述图中的 "令牌" 通常就存储在 Cookie 字段中
此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的⽤⼾信息, 这个就是 Session 机制所做的工作
Session
1)在计算机领域, 会话是⼀个客⼾与服务器之间的不中断的请求响应. 对客⼾的每个请求,服务器能够识别出请求来⾃于同⼀个客户. 当⼀个未知的客⼾向Web应⽤程序发送第⼀个请求时就开始了⼀个会话.当客⼾明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了
2)服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个用户, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与⽤⼾的信息的对应关系.
Session是服务器为了保存⽤⼾信息⽽创建的⼀个特殊的对象
3)Session的本质就是⼀个 "哈希表", 存储了⼀些键值对结构. Key 就是SessionID, Value 就是用户信息(用户信息可以根据需求灵活设计)
4)SessionId 是由服务器⽣成的⼀个 "唯一性字符串", 从 Session 机制的角度来看, 这个唯⼀性字符串称为 (SessionId). 但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 (token) 上述例子中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息, ⽐如时间, 签名等
- 当⽤⼾登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId 返回给客⼾端 (通过HTTP 响应中的 Set-Cookie 字段返回)
- 客⼾端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId. (通过 HTTP 请求中的Cookie 字段带上)
- 服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的⽤⼾信息, 再进⾏后续操作.找不到则重新创建Session, 并把SessionID返回
Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失
Cookie 和 Session 的区别
• Cookie 是客⼾端保存⽤⼾信息的⼀种机制. Session 是服务器端保存⽤⼾信息的⼀种机制
• Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁
• Cookie 和 Session 经常会在⼀起配合使⽤. 但是不是必须配合
• 完全可以⽤ Cookie 来保存⼀些数据在客⼾端. 这些数据不⼀定是⽤⼾⾝份信息, 也不⼀定是
SessionId
• Session 中的sessionId 也不需要⾮得通过 Cookie/Set-Cookie 传递, ⽐如通过URL传递
Cookie 和 Session 获取
Spring MVC是基于 Servlet API 构建的原始 Web 框架, 也是在Servlet的基础上实现的
HttpServletRequest , HttpServletResponse 是Servlet提供的两个类, 是Spring MVC⽅法的内置对象. 需要时直接在⽅法中添加声明即可
HttpServletRequest 对象代表客⼾端的请求, 当客⼾端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的⽅法,可以获得客⼾端请求的所有信息
HttpServletResponse 对象代表服务器的响应. HTTP响应的信息都在这个对象中, ⽐如向客⼾
端发送的数据, 响应头, 状态码等. 通过这个对象提供的⽅法, 可以获得服务器响应的所有内容
Spring MVC在这两个对象的基础上进⾏了封装, 给我们提供更加简单的使⽤⽅法
获取 Cookie
@RequestMapping("/getCookies") public String getCookie(HttpServletRequest request, HttpServletResponse response){ //获取参数 // String name = request.getParameter("name"); Cookie[] cookies = request.getCookies(); //获取所有Cookie if(cookies != null){ Arrays.stream(cookies).forEach(ck -> System.out.println(ck.getName()+":"+ck.getValue())); } return "获取Cookies"; }
在浏览器虚构一个 Cookie ,输入URL后刷新,在IEDA中会出现Cookie
@RequestMapping("/getCookie") //获取单个Cookie public String gerCookie2(@CookieValue("hello") String hello){ return "从Cookies中获取值:"+hello; }
设置 Session
@RequestMapping("/setSession") public String setSession(HttpServletRequest request, HttpServletResponse response){ //从Cookie中获取SessionId,根据SessionId获取Session对象,如果没获取到,会创建一个session对象 HttpSession session = request.getSession(); session.setAttribute("name","ming"); return "设置session成功"; }
获取 session
Session是服务器端的机制, 我们需要先存储, 才能再获取
Session 也是基于HttpServletRequest 来存储和获取的
@RequestMapping("/getSession") public String getSession(HttpServletRequest request, HttpServletResponse response){ //从Cookie中获取SessionId,根据SessionId获取Session对象 HttpSession session = request.getSession(); String name = (String) session.getAttribute("name"); return "从session中获取:"+name; }
通过Spring MVC内置对象HttpSession 来获取
@RequestMapping("/getSession2") public String getSession2(HttpSession session){ String name = (String) session.getAttribute("name"); return "从session中获取:"+name; }
方法二的简化操作
@RequestMapping("/getSession3") public String getSession3(@SessionAttribute("name") String name){ return "从session中获取:"+name; }
当前session存放在内存中,刷新后重新创建session
HttpSession getSession(boolean create) : 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null
HttpSession getSession(): 和getSession(true) 含义⼀样, 默认值为true
void setAttribute(String name, Object value): 使⽤指定的名称绑定⼀个对象到该 session 会话
Object getAttribute(String name): 返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null
HttpSession session = request.getSession(); Session 不存在的话, 会⾃动进⾏创建
获取Header
使⽤HttpServletRequest 提供的getHeader⽅法来获取, 参数对应HTTP请求报头的"Key"
@RequestMapping("/getHeader") public String getHeader(HttpServletRequest request){ String userAgent = request.getHeader("User-Agent"); return "从Header中获取信息:"+userAgent; }
@RequestMapping("/getHeader2") public String getHeader2(@RequestHeader("User-Agent") String userAgent){ return "从Header中获取信息:"+userAgent; }
@RequestHeader注解的参数值为HTTP请求报头中的"key"
响应
ttp响应结果可以是数据, 也可以是静态⻚⾯,也可以针对响应设置状态码, Header信息等
返回静态页面
创建一个静态页面
注意路径
@RequestMapping("/responses") @RestController public class Responses { @RequestMapping("/index") public String index(){ return "/index1.html"; } }
结果却发现, ⻚⾯未正确返回, http响应把 "/index.html" 当做了http响应正⽂的数据------>
把 @RestController 改为 @Controller
@RequestMapping("/responses") @Controller public class Responses { @RequestMapping("/index") public String index(){ return "/index1.html"; } }
随着Java前后端的分离, MVC的概念也逐渐发⽣了变化, View不再返回视图, ⽽是返回显⽰视图时需要的数据。所以前⾯使⽤的 @RestController 其实是返回的数据
@RestController = @Controller + @ResponseBody
@Controller : 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理.
@ResponseBody : 定义返回的数据格式为⾮视图, 返回⼀个 text/html 信息
如果想返回视图的话, 只需要把 @ResponseBody 去掉就可以了, 也就是 @Controller
返回数据@ResponseBody
@ResponseBody 表示返回数据
加上 @ResponseBody 注解, 该⽅法就会把 )/index.html) 当做⼀个数据返回给前端
@RequestMapping("/responses") @Controller public class Responses { @ResponseBody @RequestMapping("/index") public String index(){ return "/index1.html"; } }
@ResponseBody 既是类注解, ⼜是⽅法注解
如果作⽤在类上, 表⽰该类的所有⽅法, 返回的都是数据, 如果作⽤在⽅法上, 表⽰该⽅法返回的是数据
也就是说: 在类上添加 @ResponseBody 就相当于在所有的⽅法上添加了 @ResponseBody 注解
同样, 如果类上有 @RestController 注解时:表⽰所有的⽅法上添加了 @ResponseBody 注
解, 也就是当前类下所有的⽅法返回值做为响应数据
如果⼀个类的⽅法⾥, 既有返回数据的, ⼜有返回⻚⾯的, 就把 @ResponseBody 注解添加到对应的⽅法上即可
如果去掉 @ResponseBody 注解, 程序会报404错误程序会认为需要返回的是视图, 根据内容去查找⽂件, 但是查询不到, 路径不存在, 报404
@RequestMapping("/responses") @Controller public class Responses { @RequestMapping("data") public String data(){ return "该方法返回的是一段数据"; } }
返回HTML代码⽚段
后端返回数据时, 如果数据中有HTML代码, 也会被浏览器解析
@RequestMapping("/responses") @Controller public class Responses { @RequestMapping("/indexData") @ResponseBody public String indexData(){ return "<h1>HTML片段</h1>"; } }
响应中的 Content-Type 常⻅取值有以下⼏种:
• text/html : body 数据格式是 HTML
• text/css : body 数据格式是 CSS
• application/javascript : body 数据格式是 JavaScript
• application/json : body 数据格式是 JSON
如果请求的是js⽂件, Spring MVC会⾃动设置Content-Type为 application/javascript
如果请求的是css⽂件, Spring MVC会⾃动设置Content-Type为 text/css
返回JSON
Spring MVC 也可以返回JSON
后端⽅法返回结果为对象
@RequestMapping("/responses") @Controller public class Responses { @ResponseBody @RequestMapping(value = "/setContentType",produces = "application/json") public String setContentType(){ return "{\"OK\":1}"; } }
@RequestMapping("/responses") @Controller public class Responses { @ResponseBody @RequestMapping("/getMap") public HashMap<String, String> getMap() { HashMap<String, String> map = new HashMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); return map; } }
public class Json { public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String jsonstr = "{\n" + " \"id\":12,\n" + " \"name\":\"ming\",\n" + " \"age\":17\n" + "}"; //JSON字符串转对象 Student student = objectMapper.readValue(jsonstr,Student.class); System.out.println(student); //对象转JSON字符串 String s = objectMapper.writeValueAsString(student); System.out.println(s); } }
设置状态码
pring MVC会根据我们⽅法的返回结果⾃动设置响应状态码, 程序员也可以⼿动指定状态码
通过Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置
@RequestMapping("/responses") @Controller public class Responses { @ResponseBody @RequestMapping("/setStatus") public String setStatus(HttpServletResponse response){ response.setStatus(418); return "设置状态码"; } }
设置Header
Http响应报头也会向客⼾端传递⼀些附加信息, ⽐如服务程序的名称,请求的资源已移动到新地址等, 如: Content-Type, Local等
这些信息通过 @RequestMapping 注解的属性来实现
- value: 指定映射的URL
- method: 指定请求的method类型, 如GET, POST等
- consumes: 指定处理请求(request)的提交内容类型(Content-Type),例如application/json,
text/html- produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型 才返回
- Params: 指定request中必须包含某些参数值时,才让该⽅法处理
- headers: 指定request中必须包含某些指定的header值,才能让该⽅法处理请求
设置Content-Type
通过设置 produces属性的值, 设置响应的报头Content-Type
@RequestMapping("/responses") @Controller public class Responses { @RequestMapping(value = "/returnJson", produces = "application/json") @ResponseBody public String returnJson() { return "{\"success\":true}"; } }
如果不设置produces , ⽅法返回结果为String时, Spring MVC默认返回类型, 是text/html.
设置返回类型时, 也可以同步设置响应编码
设置其他Header
设置其他Header的话, 需要使⽤Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置
@RequestMapping("/responses") @Controller public class Responses { @RequestMapping(value = "/setHeader") @ResponseBody public String setHeader(HttpServletResponse response) { response.setHeader("MyHeader", "MyHeaderValue"); return "设置Header成功"; } }
void setHeader(String name, String value) 设置⼀个带有给定的名称和值的 header. 如果 name已经存在, 则覆盖旧的值