@PathVariable、@RequestHeader、@RequestBody、@RequestParam、@MatrixVariable、@RequestAttribute、@CookieValue
目录
6.@RequestAttribute 获取request域属性
1.@PathVariable 路径变量
@PathVariable 映射 URL 绑定的占位符
- 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
- 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
- 主要是根据请求方法进行类的区别
例子:
<a href="/car/1/owner/a?age=17&cs=2&cs=3">"/car/1/owner/a?age=17&cs=2&cs=3"</a>
/*
* <p>If the method parameter is {java.util.Map Map<String, String>}
* then the map is populated with all path variable names and values.
*/
@RequestMapping(value = "/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable String id,
@PathVariable String username,
@PathVariable Map<String,String> pv){
Map<String,Object> map = new HashMap<>();
map.put("id",id);
map.put("username",username);
map.put("pv",pv);
return map;
}
结果:
{"pv":{"id":"1","username":"a"},"id":"1","username":"a"}
2.@RequestHeader 获取请求头
@RequestHeader 是获取请求头中的数据,通过指定参数 value 的值来获取请求头中指定的参数值。其他参数用法和 @RequestParam 完全一样
RequestHeader的值大致如下图所示:
下面举一个 基本使用 的例子:
@Controller
public class handleHeader {
@GetMapping("/getHeader")
public String getRequestHeader(@RequestHeader("User-Agent") String agent) {
System.out.println(agent);
return "success";
}
}
3.@RequestBody 获取请求体【POST】
- @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);
- GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
- 在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
例子:
前段表单:
<form action="/save" method="post">
测试@RequestBody获取数据
用戶名:<input name="username">
邮箱:<input name="email">
<input type="submit" value="提交">
</form>
后端代码:
@RequestMapping(value = "/save",method = RequestMethod.POST)
public Map<String,Object> getForm(@RequestBody String content) throws UnsupportedEncodingException {
Map<String,Object> map = new HashMap<>();
content= URLDecoder.decode(content,"utf-8");//解决java代码中邮箱被转义问题“@”被转义为”%40”
map.put("content",content);
System.out.println(content);
return map;
}
4.@RequestParam 获取请求参数
@RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
value:参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,
自动为false,如果没有传该参数,就使用默认值
例子:
<a href="/car/1/owner/a?age=17&cs=2&cs=3">"/car/1/owner/a?age=17&cs=2&cs=3"</a>
@RequestMapping(value = "/car/{id}/owner/{username}")
public Map<String,Object> getCar(@RequestParam("age") String age,
@RequestParam("cs") List<String> classes){
Map<String,Object> map = new HashMap<>();
map.put("age",age);
map.put("classes",classes);
return map;
}
结果:
{"classes":["2","3"],"age":"17"}
5.@MatrixVariable 矩阵变量
org.springframework.web.bind.annotation.MatrixVariable
注解拓展了URL
请求地址的功能。使用@Matrixvariable
注解时多个变量可以使用;(分号)分隔,该注解允许开发者进行多条件组合査询。
属性 | 类型 | 是否必要 | 说明 |
name | String | 否 | 指定请求参数绑定的名称,如果省略则绑定同名参数 |
value | String | 否 | name 属性的别名 |
pathVar | String | 否 | matrix variable 所在路径的url path 变量的名称 |
required | boolean | 否 | 指示参数是否必须绑定 |
defaultValue | String | 否 | 如果没有传递参数而使用的默认值 |
5.1启用@MatrixVariable
虽然从Spring 3.2就已经支持@MatrixVariable
特性,但直至现在其依然为默认禁用的状态。我们需要手工配置开启才能使用。
原理:
MVC自动配置类WebMvcAutoConfiguration中WebMvcAutoConfigurationAdapter.configurePathMatch
方法配置路径映射时UrlPathHelper (Url路径帮助器)中removeSemicolonContent属性(移除分号内容)
默认为true。
/**
* Set if ";" (semicolon) content should be stripped from the request URI.
* <p>Default is "true".
*/
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
checkReadOnly();
this.removeSemicolonContent = removeSemicolonContent;
}
可以看出removeSemicolonContent 为TRUE的话;后所有内容均被截取掉了。
所以要启用@MatrixVariable的话需要设置removeSemicolonContent属性为false。
注:所有路径处理都是通过UrlPathHelper 进行解析。removeSemicolonContent属性是用来支持矩阵变量的。
public void configurePathMatch(PathMatchConfigurer configurer) {
if (this.mvcProperties.getPathmatch().getMatchingStrategy() == MatchingStrategy.PATH_PATTERN_PARSER) {
configurer.setPatternParser(new PathPatternParser());
}
configurer.setUseSuffixPatternMatch(this.mvcProperties.getPathmatch().isUseSuffixPattern());
configurer.setUseRegisteredSuffixPatternMatch(this.mvcProperties.getPathmatch().isUseRegisteredSuffixPattern());
this.dispatcherServletPath.ifAvailable((dispatcherPath) -> {
String servletUrlMapping = dispatcherPath.getServletUrlMapping();
if (servletUrlMapping.equals("/") && this.singleDispatcherServlet()) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setAlwaysUseFullPath(true);
configurer.setUrlPathHelper(urlPathHelper);
}
});
}
方法如下:
If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration
class of type WebMvcConfigurer
but without @EnableWebMvc
.
不用@EnableWebMvc注解。使用 @Configuration
+ WebMvcConfigurer
自定义规则
/**
*方法1
*实现WebMvcConfigurer 接口
*/
@Configuration
public class SpringBootConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
/**
* 方法2:使用@Bean注入WebMvcConfigurer类型的组件,重写configurePathMatch方法
* @return
*/
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
WebMvcConfigurer.super.configurePathMatch(configurer);
UrlPathHelper urlPathHelper=new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);//关闭
configurer.setUrlPathHelper(urlPathHelper);
}
};
}
5.2使用@MatrixVariable
参数仅有一个值时:
/*
1. 获取单个路径片段中的参数
请求URI为 /Demo2/66;color=red;year=2020
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@PathVariable String id,
@MatrixVariable String color,
@MatrixVariable String year){}
/*
2. 获取单个路径片段中的参数
请求URI为 /Demo2/color=red;year=2020
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test2(@MatrixVariable String color,
@MatrixVariable String year){}
/*
3. 获取不同路径片段中的参数
请求URI为 /Demo2/66;color=red;year=2020/pets/77;color=blue;year=2019
*/
@RequestMapping(path="/Demo2/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test3(@PathVariable String id1,
@PathVariable String id2,
@MatrixVariable(name="color", pathVar="id1") String color1,
@MatrixVariable(name="year", pathVar="id1") String year1,
@MatrixVariable(name="color", pathVar="id2") String color2,
@MatrixVariable(name="year", pathVar="id2") String year2){}
/*
4. 获取不同路径片段中的参数
请求URI为 /Demo2/color=red;year=2020/pets/77;color=blue;year=2019
*/
@RequestMapping(path="/Demo2/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test4(@PathVariable String id2,
@MatrixVariable(name="color", pathVar="id1") String color1,
@MatrixVariable(name="year", pathVar="id1") String year1,
@MatrixVariable(name="color", pathVar="id2") String color2,
@MatrixVariable(name="year", pathVar="id2") String year2){}
/*
5. 通过Map获取所有或指定路径下的所有参数
*/
@RequestMapping(path="/Demo3/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test5(@MatrixVariable Map<String, Object> all,
@MatrixVariable(pathVar="id1") Map<String, Object> mapId1) {}
参数有多个值时:
若参数值不是单个,那么可以通过两种方式传递:
值之间通过逗号分隔,如dept=321,123
重名name-value对,如dept=321;dept=123
/*
请求为/Demo1/color=123,321
那么color值为123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Integer[] color){}
/*
请求为/Demo1/color=123;color=321
那么color值为123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Integer[] color){}
需要注意的坑:
1.String参数类型可以接受通过逗号和通过重名name-value传递的所有值,
而其它类型只能获取第一个值。
/*
请求为/Demo1/color=123,321
那么color值为123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable String color){}
/*
请求为/Demo1/color=123;color=321
那么color值为123,321
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable String color){}
/*
请求为/Demo1/color=123;color=321
那么color值为123
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Integer color){}
2.Map<String, Object[]>只能获取参数中的第一个值而已。
/*
请求为/Demo1/color=123,321
那么color值为123
*/
@RequestMapping(path="/Demo1/{id}", method=RequestMethod.GET)
public String test1(@MatrixVariable Map<String, Integer[]> color){}
3.不同路径片段中出现名称相同的参数,那么必须通过pathVar标识所有相同参数所属路径,否则Url匹配失败。
// 以下handler仅标识第二个参数的pathVar,而没有标识第一个,那么也是会匹配失败的。
@RequestMapping(path="/Demo2/{id1}/pets/{id2}", method=RequestMethod.GET)
public String test2(@MatrixVariable String color,
@MatrixVariable(name="color", pathVar="id2") String color2){}
6.@RequestAttribute 获取request域属性
@RequestAttribute用在方法入参上,作用:从request中取对应的值
例子:
@Controller
public class RequestController {
@GetMapping("/goto")
public String goToPage(HttpServletRequest request){
request.setAttribute("msg","成功");
return "forward:/success";//转发到 /success请求
}
@ResponseBody
@GetMapping("/success")
public Map success(@RequestAttribute("msg") String msg,
HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
Object msg1=request.getAttribute("msg");
map.put("reqMethod_msg",msg1);
map.put("annotation_msg",msg);
return map;
}
}
http://localhost:8080/goto
{"reqMethod_msg":"成功","annotation_msg":"成功"}
7.@CookieValue 获取Cookie值
使用 @CookieValue
注解主要是将请求的Cookie数据映射到功能处理方法的参数上。
属性说明表
属性 类型 是否必要 说明 value String 否 绑定参数的名称 required boolean 否 指示参数是否必须绑定,默认为true defaultValue String 否 如果没有传递参数而使用的默认值
例子:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<h4>测试@CookieValue注解</h4>
<a href="cookieValueTest">cookieValueTest</a>
<br>
</body>
</html>
@Controller
public class HelloWorldController {
@RequestMapping("/cookieValueTest")
public void cookieValueTest(@CookieValue(value="JSESSIONID")String sessionId) {
System.out.println("通过@CookieValue获得JSESSIONID:"+sessionId);
}
}