SpringMVC注解全攻略之从请求到响应的过程详解
作者:稻草猫.
咱们学习Spring MVC,就是学习Spring MVC的各种注解。使用重点也就是学习如何通过浏览器和用户程序进行交互. 主要分以下三个方面:
1. 建立连接:将用户(浏览器)和Java程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring程序。
2. 请求:用户请求的时候会带⼀些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数 的功能。
3. 响应:执行了业务逻辑之后,要把程序执行的结果返回给用户,也就是响应.
Spring MVC注解
一. 建立连接
1.1 @RequestMapping
@RequestMapping:URL路由映射
路径映射(Path Mapping) 就是把浏览器访问的 URL 地址,和后端代码里处理请求的方法(Controller 方法)对应起来的规则。
资源路径:类路径+方法路径(如果一个方法路径它有类路径就必须加上)

注意:@RequestMapping括号中的 / 可加可不加
@RequestMapping既是类注解(对应类路径)也是方法注解(对应方法路径)(既可以加在类上也可以加在方法上)
@Request Mapping对于请求方法来说,默认既支持GET也支持POST方法(通过浏览器发起的请求都是默认GET请求,并且请求方式是由客户端决定,服务端进行支持的
如何让它只支持某一种请求:
@RequestMapping(value = "/hello",method = RequestMethod.GET)
当只支持这一种请求方法时,用另一种请求就会请求失败

也可以加更多的请求方式:
如:
@RequestMapping(value = "/hello",method = {RequestMethod.GET,RequestMethod.POST,RequestMethod.DELETE})还可以用其它的注解来指定请求方式(这里只写一部分,其它的类似):
- @GetMapping():仅支持GET请求
- @PostMapping():仅支持POST请求
- @DeleteMapping():仅支持DELETE请求

注意:
- @GetMapping(“/hello”)=@RequestMapping(value = "/hello",method = RequestMethod.GET)
- 如果类注解有method规定请求方法,而方法注解没有--则“继承类”的。如果方法注解有加,则支持方法自己的
其余类似
1.2 @RestController
@RestController是类注解
在上面这个代码中@RestController的主要作用:告诉Spring,这个类中有处理HTTP请求的能力(有处理HTTP请求的接口类),请求来了就到我这里来查-----相当于Spring的查找范围(没有就不会查)

二. 请求
访问不同的路径,就是发送不同的请求.在发送请求时,可能会带⼀些参数,所以学习Spring的请求,主要 是学习如何传递参数到后端以及后端如何接收. 传递参数,咱们主要是使⽤浏览器和Postman来模拟.
2.1 传递单个参数


当参数为Boolean类型时,可以传1/0也可以传true/false(SpringMVC会帮我们转换),其余的数字不可以
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(Boolean flag) {
return "接收到参数:"+flag;
}
}
参数重命名:使用@RequestParam注解(使用了@RequestParam注解的参数默认为必传参数-------如何修改--@RequestParam(value="number",required=false)即可)

实际上:我们服务器在Spring框架下接收到的数据都是String类型,它会根据你服务器方法实际要的数据类型进行转换(String类型转换成实际需要接收的参数类型,且转化成Java基础数据类型是转换成功后直接赋值,而转化为对象时Spring还会帮我们new对象)
注意:有的时候Spring在进行转换时也会转换失败,如:

2.2 传递多个参数
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(String name,Integer num) {
return "接收到参数:"+name+" "+num;
}
}
在传递时顺序可以不保持一致,但是参数名要保持一致
在传递参数时:
多传参数---不会报错,多的会被忽略
少传参数---可能会报错---原因:未传的参数Spring就会设为null,如果方法参数为基本数据类型(如 int,double,boolean等)就不能接收,就会报错。如果是其它的参数就不会报错(可以被赋值为null)

2.3 传递对象
package com.example.demo;
import org.springframework.web.bind.annotation.*;
class person{
String name;
int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
return "person{" +
"name='" + name + '\'' +
", num=" + num +
'}';
}
}
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(person person) {
return person.toString();
}
}在Spring代码中定义的类必须要有一个无参的构造方法和Setter/getter,不然会报错
为什么必须要 setter?
Spring 底层是这么干的:// 1. 调用无参构造
User user = new User();// 2. 赋值!必须靠 set 方法!
user.setName("张三");
user.setAge(20);
没有 setXxx(),Spring 根本没法给对象赋值!

注意:
- 对于对象来说,不传参数给Java基础类型的变量,不会报错---因为类中的变量都有对应的初始值(如int的初始值就是0)
- 在没加其它注解的情况下,对象的传参只能在URL上(有一种注解可以使对象在body在进行传参,下面会讲到)
2.4 传递数组
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(String[] arr) {
return Arrays.toString(arr);
}
}传递数组有两种方法:


2.5 传递集合
传递集合必须要使用注解 @RequestParam
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public List<String> r1(@RequestParam List<String> list) {
return list;
}
}
注意:注意:参数为数组/集合类时,对于客户端来说,传递参数时的格式都是一样的;但对于服务端来说,如果不加 @RequestParam,Spring 只能直接接收数组,集合必须加上这个注解才能正常接收。
2.6 传递JSON数据
JSON概念:
JSON(JavaScript Object Notation)
是一种轻量级、纯文本、跨语言的数据交换格式。
- 本质:字符串格式的结构化数据
- 作用:前后端、不同语言之间传递数据
- 特点:简单、易读、体积小、几乎所有语言都支持,且空行与换行无效JSON 语法:
1. 对象用 { } ,键值对结构(其中key对应于一个对象中的一个属性,value则对应属性的值)
2. 键必须用双引号 "key" (不能单引号、不能省略)
3. 键值之间用 冒号 :
4. 多组用 逗号 , 分隔
5. 数组/集合用 [ ]
6. 值支持:
- 字符串(双引号)
- 数字
- 布尔 true / false
- null
- 对象 {}
- 数组/集合 []
7. 最后一个成员后面不能加逗号
下面就是一个json格式的数据:
{
"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
reflexes"]
}, {
"name": "Eternal Flame",
"age": 1000000,
"secretIdentity": "Unknown",
"powers": ["Immortality", "Heat Immunity", "Inferno",
"Teleportation", "Interdimensional travel"]
}]
}JSON有两种格式:
- 对象格式:最外层用 { } 包裹键值对
- 数组格式:最外层用 [ ] 包裹对象/字符串/数字.....
可以使⽤在线JSON格式化⼯具来进行校验和书写:在线JSON校验格式化⼯具(https://www.bejson.com/)

JSON和Java对象可以相互转换---转换工具:常见有三种:
1. Gson 2.fastjson 3.jackson(由于jackson是Spring框架本身引入的,下面就以jackson演示)
使用到ObjectMapper这个类
@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() throws JsonProcessingException {
//对象转json
ObjectMapper objectMapper = new ObjectMapper();
person person=new person();
person.setName("zhangsan");
person.setNum(21);
String json=objectMapper.writeValueAsString(person);
System.out.println(json);
//json转对象
person p=objectMapper.readValue(json, com.example.demo.person.class);
System.out.println(p);
}
}注意:JSON 实际上就是一个具有特定格式的字符串,用来表示结构化数据。
我们在接收JSON对象时。有两种方式:
- 使用String来接收
- 使用自定义类来接收
这两种方式都要用到注解 @RequestBody,由于我们把json数据都是放在body中的,@RequestBody就是在告诉Spring,参数在body中,如果不加@RequestBody,Spring只会在URL中查找参数。
使用自定义类来接收:@RequestBody还会自动将JSON数据转化为Person对象
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(@RequestBody person person) {
return person.toString();
}
}
使用String来接收:@RequestBody不会将JSON数据转化为Person对象(如果想要这个Sting数据转化为对象可以借助ObjectMapper这个类来实现)
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(@RequestBody String json) throws JsonProcessingException {
//将拿到的JSON原始数据转化为对象
ObjectMapper objectMapper=new ObjectMapper();
person person=objectMapper.readValue(json, com.example.demo.person.class);
return person.toString();
}
}
2.7 获取URL中的参数
使用@PathVariable注解:Spring MVC 中用于从 URL 路径中提取变量值的注解,它将 URL 中的占位符参数绑定到控制器方法的形参上。
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1/{articleID}/{username}")
public String r1(@PathVariable Integer articleID,@PathVariable("username") String name){
return "接收到参数"+" "+articleID+" "+name;
}
}
注意:虽然 @PathVariable 本身不要求参数顺序,但路径变量的类型和位置必须严格对应。
2.8 上传文件
使用注解 @RequestPart
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(@RequestPart MultipartFile file) throws IOException {
file.transferTo(new File("D:\\新建文件夹\\"+file.getOriginalFilename()));//将文件拷贝到改路径下
return file.getOriginalFilename();//返回文件名
}
}

2.9 获取Cookie
获取Cookie有两种方法:
传统servl方式:
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/r1")
public String r1(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();//获取一个Cookie数组
if(cookies!=null){
for (Cookie cookie : cookies) {
if (cookie != null) {
System.out.println(cookie.getName() + "=" + cookie.getValue());//循环遍历打印每一个Cookie键值对
}
}
}
return "获取Cookie成功";
}
}如果我们的请求没有Cookie,我们可以手动设置Cookie(Cookie是可以伪造的)


注意:当一个 HTTP 请求到达时,Spring 会自动创建一个 HttpServletRequest 对象,封装了本次请求的所有信息(如 URL、请求头、参数、Cookie 等)。
用注解获取Cookie:(这个方法只能逐个获取单个Cookie键值对,不能一下子获取所有Cookie)
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/getCookie")
public String getCookie(@CookieValue("name") String name) {
return "获取Cookie成功,name:"+name;
}
}
注意:获取Cookie的前提是要有Cookie
2.10 获取Session
在获取Session之前要先获取Session1对象然后再设置Session才能获取得到
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request) {
HttpSession session=request.getSession();//拿到Session对象后,我们才能往Session中存数据
session.setAttribute("name","zhangsan");
session.setAttribute("age","22");
return "设置Session成功";//我们设置的Session数据只是保存在服务器中,不会外传
}
}当客户端向服务器发送请求并且代码主动要Session服务器才会第一次创建Session对象
每创建一个 session 对象,服务器都会通过响应发送一个 SessionID 给客户端。
request.getSession() : 如果客户端发送的请求中带有一个有效的SessionID,服务器就会依据这个SessionID找到对应的Session对象并返回。如果没有SessionID/没有找到SessionID对应的Session对象,服务器就会创建出一个新的Session对象,并且返回客户端一个SessionID。


总之:每一个客户端对应的Session对象是不同的,通过Session对象对应的SessionID来识别
注意:
- Session默认存储在内存中,服务器重启后Session会丢失
- 服务器可以存放并生成多个Session对象
- 如果我们将自己的携带的SessionID改为其它的SessionID(Cookie是可以伪造的)---身份改变
获取Session有三种方式(如果没有Session,都要先设置Session信息*):
法一:
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/setSession")//设置Session
public String setSession(HttpServletRequest request,String name) {
HttpSession session=request.getSession();
session.setAttribute("name",name);
return "设置Session成功";
}
@RequestMapping("/getSession1")//获取Session
public String getSession(HttpServletRequest request) {
HttpSession session=request.getSession();//先获取Session对象再获取其参数
return "获取Session成功"+"name: "+session.getAttribute("name");
}
}


法二:(Spring获取Session的方式):通过@SessionAttribute注解
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/setSession")//设置Session
public String setSession(HttpServletRequest request,String name) {
HttpSession session=request.getSession();
session.setAttribute("name",name);
return "设置Session成功";
}
@RequestMapping("/getSession2")//获取Session
public String getSession(@SessionAttribute("name") String name) {
return "获取Session成功"+"name: "+name;
}
}

法三:
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request,String name) {
HttpSession session=request.getSession();
session.setAttribute("name",name);
return "设置Session成功";
}
@RequestMapping("/getSession3")
public String getSession(HttpSession session) {
return "获取Session成功"+"name: "+session.getAttribute("name");
}
}2.11 获取Header
获取Header有两种方式
法一:
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/getHeader")
public String getSession(HttpServletRequest request) {
String User_Agent=request.getHeader("User-Agent");
return "获取Header成功:User-Agent= "+User_Agent;
}
}
通过查看Fiddler判断获取到的数据是否正确

法二:使用 @RequestHeader 注解
@RestController
@RequestMapping("/r")
public class Test {
@RequestMapping("/getHeader")
public String getSession(@RequestHeader("User-Agent") String User_Agent) {
return "获取Header成功:User-Agent= "+User_Agent;
}
}三. 响应
3.1 返回静态页面
使用 @Controller 注解(标明我们返回的是一个视图)
- @RestController :类级别注解,所有方法默认返回数据,不返回视图。
(@RestController =@Controller+@ResponseBody)
- @Controller :类级别注解,方法默认返回视图,如需返回数据需添加 @ResponseBody 。
- @ResponseBody :方法级别注解,使单个方法直接返回数据,不返回视图。
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping("/html")
public String getSession() {
return "/AAA.html"; //注意前面要加 /
}
}
注意我们要把要返回的静态页面放在静态资源下面的文件中

3.2 返回HTML代码片段
后端返回数据(不是视图)时,如果数据中有HTML代码,也会被浏览器解析。
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping("/html")
@ResponseBody
public String getSession() {
return "<h1> HTML</h1>";
}
}![]()

3.3 返回JSON
当我们返回的数据是对象/map/list等,Spring会自动将响应头中的content-type设置为application/json,并返回json数据
返回对象:
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping("/returnjson")
@ResponseBody
public Person returnjson() {
Person person=new Person();
person.setNum(21);
person.setName("zhangsan");
return person;
}
}

返回map:
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping("/returnjson")
@ResponseBody
public Map<String,String> returnjson() {
Map<String,String> map=new HashMap<>();
map.put("old","29");
map.put("name","zhangsan");
return map;
}
}
3.4 设置状态码
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping("/setstatus")
@ResponseBody
public String setstatus(HttpServletResponse response) {
response.setStatus(400);
return "设置状态码成功";
}
}
3.5 设置 Header
Http响应报头也会向客⼾端传递⼀些附加信息,⽐如服务程序的名称,请求的资源已移动到新地址等,如: Content-Type,Local等. 这些信息通过 @RequestMapping 注解的属性来实现 先来看 @RequestMapping 的源码:

1.value:指定映射的URL
2. method:指定请求的method类型,如GET,POST等
3. consumes:指定处理请求(request)的提交内容类型(Content-Type),例如application/json, text/html;
4. produces:指定返回的内容类型,还可以同时设置返回值的字符编码
5. Params:指定request中必须包含某些参数值时,才让该⽅法处理
6. headers:指定request中必须包含某些指定的header值,才能让该⽅法处理请求
设置 Content-Type:
设置Content-Type:通过@RequestMapping的produces属性设置
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping(value = "/setContentType",produces = "application/json")
@ResponseBody
public String setstatus(HttpServletResponse response) {
return "{\"name\":\"zhangsan \"}";
}
}
如果不手动设置Content-Type,Spring会根据方法的返回参数自动设置,返回类型为Spring---设置为text/plain(返回类型是对象/map等---设置为application/json)
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping(value = "/setContentType")
@ResponseBody
public String setstatus(HttpServletResponse response) {
return "{\"name\":\"zhangsan \"}";
}
}
设置其它Header
@Controller
@RequestMapping("/r")
public class Test {
@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","header");
return "设置header成功";
}
}
到此这篇关于SpringMVC注解全攻略:从请求到响应的文章就介绍到这了,更多相关SpringMVC注解从请求到响应内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
