SpringMVC底层处理请求的类型,分为3类
1、普通参数与基本注解
- 注解:
@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody
- Servlet API:
WebRequest、ServletRequest、MultipartRequest、HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId
- 复杂参数:
Map、Errors/BindingResult、Model、RedirectAttributes、ServletResponse、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder
- 自定义对象参数:
注解的方式处理页面请求
- CookieValue(获取Cookid值)、@PathVariable(路径变量)、@RequestHeader(获取请求头)、@RequestParam(获取请求参数)
Controller层
package com.xky.controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @since 2021-02-18 11:31
*/
@RestController
public class ParameterTestController {
/**
* @param id 入参
* @param name 入参
* @param pv
* @param userAgent 入参
* @param header 请求头
* @param age 入参
* @param inters 入参
* @param params 入参
* @param cook 单个cookie信息
* @param cookie 整个cookie对象
* @return
*/
//@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@CookieValue
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable("id") Integer id,
@PathVariable("username") String name,
@PathVariable Map<String,String> pv,
@RequestHeader("User-Agent") String userAgent,
@RequestHeader Map<String,String> header,
@RequestParam("age") Integer age,
@RequestParam("inters")List<String> inters,
@RequestParam Map<String,String> params,
@CookieValue("Idea-661643a5") String cook,
@CookieValue("Idea-661643a5")Cookie cookie){
Map<String, Object> map = new HashMap<>();
// map.put("id", id);
// map.put("name", name);
// map.put("pv", pv);
//获取请求头
// map.put("userAgent", userAgent);
// map.put("headers", header);
//获取数据
map.put("age", age);
map.put("inters", inters);
map.put("params", params);
map.put("_ga", cook);
//将cookie对象中的key和value值打印出来
System.out.println(cookie.getName() + "===>" + cookie.getValue());
System.out.println(cookie);
System.out.println(cook);
return map;
}
}
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>welCome!</h1>
<h2>测试基本注解:</h2>
<a href="/car/3/owner/lisi?age=18&inters=basketball&inters=game">/car/{id}/owner/{username}</a><br>
</body>
</html>
- @RequestBody(获取请求体[POST])
Controller层
package com.xky.controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @since 2021-02-18 11:31
*/
@RestController
public class ParameterTestController {
@PostMapping("/save")
public Map postMethod(@RequestBody String content){
Map<String, Object> map = new HashMap<>();
map.put("content", content);
return map;
}
}
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>welCome!</h1>
<h2>测试基本注解:</h2>
<form action="/save" method="post">
测试@RequestBody获取数据库<br/>
用户名: <input name="userName"/><br>
邮箱: <input name="email"/>
<input type="submit" value="提交">
</form>
</body>
</html>
- @RequestAttribute(获取request域属性)
Controller层
package com.xky.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @since 2021-02-18 14:23
*/
@Controller
public class RequestController {
@GetMapping("/goto")
public String goToPage(HttpServletRequest request){
request.setAttribute("msg", "成功了...");
request.setAttribute("code", 200);
return "forward:/success"; //转发到 /success请求
}
@ResponseBody
@GetMapping("/success")
public Map success(@RequestAttribute("msg") String msg,
@RequestAttribute("code") String code,
HttpServletRequest request){
Object msgOne = request.getAttribute("msg");
Map<String, Object> map = new HashMap<>();
map.put("reqMethod_msg", msgOne);
map.put("annotation_msg", msg);
return map;
}
}
之后直接访问localhost:8080/goto,调用goto方法即可:
- @MatrixVariable(矩阵变量)
矩阵变量应绑定在路径中,页面开发中cookie仅用了,session怎么使用?
session的jsessionid一般会存放在cookie中每次发请求时会携带,通过这个id找到session对象,如果禁用cookie没有办法使用jsessionid,我们可以通过url重写的方法将jsessionid放在url中,把cookid的值使用矩阵变量的方式进行传递
config配置类
package com.xky.config;
import org.springframework.context.annotation.*;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.util.UrlPathHelper;
/**
* web模块配置类
* @since 2021-02-18 10:07
*/
@Configuration(proxyBeanMethods = false)
public class WebConfig /*implements WebMvcConfigurer*/ {
/**
* 将_method这个名字换成自定义的
* @return
*/
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m"); //自定义名字
return methodFilter;
}
/**
* 开启矩阵变量
* 第一种写法:
* 继承 WebMvcConfigurer 接口重写下面的方法
*/
/*@Override
public void configurePathMatch(PathMatchConfigurer configurer){
UrlPathHelper urlPathHelper = new UrlPathHelper();
//设置为不移除; 后面的内容,矩阵变量才能生效
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}*/
/**
* 开启矩阵变量
* 第二种写法
*/
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
//不移除; 后面的内容,矩阵变量功能就可以生效
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
};
}
}
Controller
package com.xky.controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @since 2021-02-18 11:31
*/
@RestController
public class ParameterTestController {
//1、语法:/cars/sell;low=34;brand=byd,audi,yd
//2、SpringBoot默认仅用了矩阵变量的功能,要手动开启:
//原理:对于路径的处理,UrlPathHelper进行解析
// removeSemicolonContent(移除分号内容)用来支持矩阵变量,其意思是 是否移除矩阵变量
//3、矩阵变量必须有url路径变量才能被解析
@GetMapping("/cars/{path}")
public Map carsSell(@MatrixVariable("low") Integer low,
@MatrixVariable("brand") List<String> brand,
@PathVariable("path") String path){
Map<String, Object> map = new HashMap<>();
map.put("low", low);
map.put("brand", brand);
map.put("path", path);
return map;
}
//多个参数用同一个参数名的情况下可以使用pathVar路径区别开
@GetMapping("/boss/{bossId}/{empId}")
public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
@MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
Map<String, Object> map = new HashMap<>();
map.put("bossAge", bossAge);
map.put("empAge", empAge);
return map;
}
}
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>welCome!</h1>
<h2>测试REST风格:</h2>
<form action="/user" method="get">
<input value="REST-GET 提交" type="submit">
</form>
<form action="/user" method="post">
<input value="REST-POST 提交" type="submit">
</form>
<form action="/user" method="post">
<input type="hidden" name="_method" value="delete">
<input type="hidden" name="_m" value="delete">
<input value="REST-DELETE 提交" type="submit">
</form>
<form action="/user" method="post">
<input type="hidden" name="_method" value="put">
<input value="REST-PUT 提交" type="submit">
</form>
<hr />
<h2>测试基本注解:</h2>
<a href="/car/3/owner/lisi?age=18&inters=basketball&inters=game">/car/{id}/owner/{username}</a><br>
<a href="/car/1">@PathVariable</a><br>
<a href="/car/1">@RequestHeader</a><br>
<a href="/car?brand=byd">@RequestParam-GET</a>
<br>
<a href="/cars/sell;low=34;brand=byd,audi,yd">@RequestParam-GET(矩阵变量)</a><br>
<a href="/cars/sell;low=34;brand=byd,brand=audi;brand=yd">@MatrixVariable(矩阵变量)</a><br>
<a href="/boss/1;age=20/2;age=10">@MatrixVariable(矩阵变量)/boss/{bossId}/{empId}</a><br>
<form action="/save" method="post">
测试@RequestBody获取数据库<br/>
用户名: <input name="userName"/><br>
邮箱: <input name="email"/>
<input type="submit" value="提交">
</form>
<ol>
<li>矩阵变量需要在SpringBoot中手动开启</li>
<li>根据RFC3986的规范,矩阵变量应当绑定在路径变量中!</li>
<li>若是有多个矩阵变量,应当使用英文符号;进行分隔</li>
<li>若是一个矩阵变量有多个值,应当使用英文符号,进行分隔,或只命名多个重复的key即可</li>
<li>如:/cars/sell;low=34;brand=byd,audi,yd</li>
</ol>
</body>
</html>