1. SpringMVC的请求
1.1 请求参数的理解
Http协议的请求头,是服务器在正式接收数据之前对接收数据格式类型等的一些预处理信息。
Http协议的响应头,是浏览器在正式处理数据之前对响应数据格式、类型、编码等等的预处理信息。
-
字符串格式的数据。大多数数据使用该格式
-
二进制格式的数据。通常是文件使用该格式
1.1.2 请求的方式
比较完整的请求方式可以在HttpServlet类源代码的请求方式定义中查看。
public abstract class HttpServlet extends GenericServlet { private static final String METHOD_DELETE = "DELETE"; private static final String METHOD_HEAD = "HEAD"; private static final String METHOD_GET = "GET"; private static final String METHOD_OPTIONS = "OPTIONS"; private static final String METHOD_POST = "POST"; private static final String METHOD_PUT = "PUT"; private static final String METHOD_TRACE = "TRACE"; ... }
- GET请求
- POST请求
- PUT请求
- DELETE请求
- OPTION请求
1.2 基本数据类型的请求
1.2.1 GET请求的地址
- 地址栏直接输入
http://localhost:8080/int?id=1
- 表单的get请求
<form action="int" method="get" enctype="application/x-www-form-urlencoded">
<input name="id">
<button>提交</button>
</form>
- 超链接
<a href="/int?id=1">链接</a>
- ajax的get请求
$.ajax({
url: 'int',
type: 'get',
data: {
id: 10
}
});
请求的数据分析
1.2.2 POST请求
- 表单的POST请求
<form action="int" method="post" enctype="application/x-www-form-urlencoded">
<input name="id">
<button>提交</button>
</form>
- ajax的POST请求
$.ajax({
url: 'int',
type: 'post',
data: {
id: 10
}
});
1.2.3 后端处理
@RequestMapping("/int")
public void getInt(int id){
System.out.println(id);
}
1.3 对象类型的请求
1.3.1 请求的方式
- GET请求
http://localhost:8080/login?account=admin&password=123456
- POST请求
<form action="/login" method="post" enctype="application/x-www-form-urlencoded">
<input name="account">
<input name="password" type="password">
<button>登陆</button>
</form>
1.3.2 后端处理
@RequestMapping("/login")
public void login(LoginQuery query){
System.out.println(query);
}
1.4 数组类型的请求
1.4.1 请求的方式
- GET/POST请求
- ajax请求数组
$.ajax({
url: 'dohobby',
type: 'get',
// 让数组的数据名称去掉[]
traditional: true,
data: {
hobby: ['阅读','运动','上网']
}
});
let data = {
hobby:['阅读','运动','上网']
};
let paramString = $.param(data,true);
$.ajax({
url: 'dohobby',
type: 'get',
data: paramString
});
1.4.2 后端处理
@RequestMapping("/dohobby")
public void doHobby(String[] hobby) {
System.out.println(hobby);
for (String h : hobby) {
System.out.println(h);
}
}
1.5 集合类型的请求
1.5.1 传统方式:表单名称必须和属性名一致(键值对)
1.5.1.1 请求的格式
<form action="/dolist">
<input name="goods[0].id" value="1">
<input name="goods[0].name" value="方便面"> <br>
<input name="goods[1].id" value="2">
<input name="goods[1].name" value="牙刷"> <br>
<input name="goods[2].id" value="3">
<input name="goods[2].name" value="毛巾"> <br>
<button>批量添加商品</button>
</form>
1.5.1.2 后端响应
@Data
public class Goods {
private Integer id;
private String name;
}
@Data
public class GoodsDTO {
private List<Goods> goods;
}
@RequestMapping("/dolist")
public void doList(GoodsDTO goodsDTO){
System.out.println(goodsDTO);
System.out.println(goodsDTO.getGoods());
}
1.5.2 使用 JSON
格式提交
如果需要spring对json格式数据进行支持需要导入jackson包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.2</version> </dependency>
15.2.1 请求的格式
let list = [{
id: 1,
name: '方便面'
},{
id: 2,
name: '牙刷'
},{
id: 3,
name: '毛巾'
}];
$.ajax({
url: 'dolistjson',
type: 'post',
contentType: 'application/json;charset=utf-8',
data: JSON.stringify(list)
});
1.5.2.2 后端的响应 - 使用@RequestBody获取
@RequestMapping("/dolistjson")
public void doList(@RequestBody List<Goods> goods){
System.out.println(goods);
}
1.5.2.3 注意事项
使用 JSON
格式发送请求时,前端请求的对象必须和后端接收的的对象的属性一一对应。
1.6 文件类型的请求
1.6.1 请求的格式
<form action="dofile" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button>提交文件</button>
</form>
1.6.2 后端的响应
1.6.2.1 common-fileupload 方式
添加依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
在SpringMVC的配置文件中添加解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
书写后端代码
@RequestMapping("/dofile")
public void dofile(MultipartFile file) throws IOException {
// 获取文件的相关信息
System.out.println(file); // 对象信息
System.out.println(file.getName()); // 表单名称 name属性名称
System.out.println(file.getBytes()); // 文件的二进制数据
System.out.println(file.getContentType()); // 上下文类型
System.out.println(file.getOriginalFilename()); // 文件名称
System.out.println(file.getSize()); // 文件大小
System.out.println(file.isEmpty()); // 是否为空
// 保存
if (!file.isEmpty()) {
file.transferTo(new File("D://" + file.getOriginalFilename()));
}
}
1.6.2.2 servlet 3.0 方式
- web.xml 中为servlet添加配置
<load-on-startup>1</load-on-startup>
容器加载时加载Servlet<multipart-config/>
Servlet接收文件上传
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:webApplicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config/>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
-
Spring Web MVC 中的文件上传配置
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
-
Controller代码
@RequestMapping("/dofile") public void dofile(MultipartFile file) throws IOException { // 获取文件的相关信息 System.out.println(file); // 对象信息 System.out.println(file.getName()); // 表单名称 name属性名称 System.out.println(file.getBytes()); // 文件的二进制数据 System.out.println(file.getContentType()); // 上下文类型 System.out.println(file.getOriginalFilename()); // 文件名称 System.out.println(file.getSize()); // 文件大小 System.out.println(file.isEmpty()); // 是否为空 // 保存 if (!file.isEmpty()) { // 从输入流中获取出来,复制到文件中 Files.copy(file.getInputStream(),new File("D:/"+ file.getOriginalFilename()).toPath()); } }
1.6.3 注意事项
请求的格式
-
请求方式必须是:methd=“post”
-
请求的编码类型必须是:enctype=“multipart/form-data”
1.7 RESTFul风格的请求
前后端通信的一种人为定制的规范。使用语义化的URL地址来描述请求的操作。
格式:url地址 + 请求的方式
- 请求的方式
- GET 请求:对应的查询功能
- POST请求:对应新增的功能
- PUT请求:对应修改的功能
- DELETE请求:对应删除的功能
传统的URL和RESTFul风格的请求
- 查询/ 删除/ 新增/ 修改 某个版块
传统的URL | RESTFul风格 |
---|---|
http://域名地址/sections?id=1 | http://域名地址/sections/1.html : GET |
http://域名地址/delsections?id=1 | http://域名地址/sections/1.html : DELETE |
http://域名地址/addsection?id=1 | http://域名地址/sections : POST |
http://域名地址/updatesection?id=1 | http://域名地址/sections/1.html : PUT |
RESTFul风格的URL地址:认为同一个资源的操作URL地址应该一样,使用URL地址代表资源,使用请求方式代表具体的操作。
1.7.1 后端操作
注解 | 描述 |
---|---|
@RequestMapping | 匹配所有请求方式 |
@GetMapping | 匹配GET请求,REFTFul风格表示查询 |
@DeleteMapping | 匹配DELETE请求,REFTFul风格表示删除 |
@PutMapping | 匹配PUT请求,REFTFul风格表示修改 |
@PostMapping | 匹配POST请求,REFTFul风格表示新增 |
// @RequestMapping(path = "/sections/{id}.html",method = RequestMethod.GET)
@GetMapping("/sections/{id}.html")
public void querySection(@PathVariable("id") int id){
System.out.println("查询 - " + id);
}
// @RequestMapping(path = "/sections/{id}.html",method = RequestMethod.DELETE)
@DeleteMapping("/sections/{id}.html")
public void deleteSection(@PathVariable("id")int id){
System.out.println("删除 - " + id);
}
// @RequestMapping(path = "/sections/{id}.html",method = RequestMethod.PUT)
@PutMapping("/sections/{id}.html")
public void updateSection(@PathVariable int id, Section section){
System.out.println("修改 - " + id);
System.out.println(section);
}
// @RequestMapping(path = "/sections",method = RequestMethod.POST)
@PostMapping("/sections")
public void addSection(Section section){
System.out.println("新增 - " + section);
}
1.8 获取Servlet的相关API对象
直接在方法中添加对应需要的参数即可。
@GetMapping("/servlet-api.html")
public void getServletAPI(HttpServletResponse response, HttpSession session, HttpServletRequest request) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
}
保存数据到request的作用域中,使用参数
@GetMapping("/servlet-api.html")
public String getServletAPI(Model model){
// 把数据保存到request的作用域中 - request.setAttribute
model.addAttribute("test","测试数据1");
System.out.println(model.getClass());
return "servlet";
}
@GetMapping("/servlet-api.html")
public String getServletAPI(ModelMap modelMap){
// 把数据保存到request的作用域中 - request.setAttribute
modelMap.put("test","测试数据2");
return "servlet";
}
@GetMapping("/servlet-api.html")
public String getServletAPI(Map map){
// 把数据保存到request的作用域中 - request.setAttribute
map.put("test","测试数据3");
return "servlet";
}
数据展示
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${test}"></h1>
</body>
</html>
保存数据到session中
@SessionAttributes(names = {“test”}) 在执行时,会从request当中获取一个名称为test的属性,并保存到session中。
@Controller
@SessionAttributes(names = {"test"})
public class TypeController {
@GetMapping("/servlet-api.html")
public String getServletAPI(Map map ){
// 把数据保存到request的作用域中 - request.setAttribute
map.put("test","测试数据3");
return "servlet";
}
}
数据呈现代码
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${test}"></h1>
<h2 th:text="${session.test}"></h2>
</body>
</html>
1.9 特殊对象的参数获取
1.9.1 获取请求头中的内容
@RequestHeader("名称")
服务端代码
/**
* 获取请求头中的数据
* @return
*/
@GetMapping("/get-token")
public String getToken(@RequestHeader("token")String token){
System.out.println(token);
return "index";
}
请求需要发送token
1.9.2 获取Cookie作用域中的内容
@CookieValue( cookie的键名 )
/**
* 获取cookie中的内容
* @param id
*/
@GetMapping("/get/cookie")
public void getCookie(@CookieValue("JSESSIONID") String id){
System.out.println(id);
}
1.9.3 获取session作用域中的内容(了解)
/**
* 获取session中的内容
* @param test
*/
@GetMapping("/get/session")
public void getSession(@SessionAttribute( name = "test",required = false) String test){
System.out.println(test);
}
1.9.4 获取request作用域中的内容(了解)
/**
* 转发,转发前将数据存储到request中
*/
@GetMapping("/dispatch")
public void dispatchRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("test","转发的内容");
request.getRequestDispatcher( "get/request").forward(request,response);
}
/**
* 获取request作用域中的内容 , 在被跳转中的请求中获取上一个请求存储的test
* @param test
*/
@GetMapping("/get/request")
public void getRequest(@RequestAttribute( name = "test",required = false) String test){
System.out.println(test);
}
1.10 请求的静态资源
静态资源:HTML/CSS/JS/图片/字体 等等
特点:不用经过Java代码的处理,直接返回给客户端
1.10.1 直接使用默认的Servlet处理
<mvc:default-servlet-handler/>
1.10.2 手动配置不需要拦截的地址
location:指放行的文件路径 , 服务器上的路径
mapping:放行的url地址 , 浏览器地址栏填写的数据
<mvc:resources mapping="/static/**" location="/static/"/>
1.11 请求的编码处理
使用过滤器完成
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.12 请求的自定义类型转换
自定义类型
public class DateConvert implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
return format.parse(source);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.xuetang9.spring.demo.convert.DateConvert"></bean>
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
注解日期转换
@RequestMapping("/dotime")
public void dotime(@DateTimeFormat(pattern = "yyyy-MM-dd") Date time){
System.out.println(time);
}
1.13 请求数据的后端验证
添加验证需要的jar包
<!--添加一个hibernate提供的后端验证的jar包-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
在需要验证的对象的类中属性书写验证规则和提示信息
@Data
public class LoginQuery {
@NotEmpty(message = "账号必填")
private String account;
@NotEmpty(message = "密码必填")
private String password;
}
在控制器中的方法 添加验证的注解和错误信息的参数
BindingResult bindingResult 参数必须紧跟在验证的参数对象的后面。
@RequestMapping("/dologin")
public void doValid(@Validated LoginQuery query, BindingResult bindingResult){
if(bindingResult.hasErrors()){
System.out.println("验证失败!");
}else{
System.out.println("验证成功!");
}
System.out.println(query);
}
注解 | 描述 |
---|---|
@NotEmpty(message = “账号必填”) | 非空 |
@Length(min = 6, max = 12, message = “”) | 字符串长度 |
@Range(min = 20,max = 100,message = “”) | 数值范围 |
@Pattern(regexp="1{6,12}$",message = “”) | 正则表达式 |
2. SpringMVC的响应
2.1 SpringMVC的页面跳转
2.1.1 页面转发
- 返回值为String
- 默认会把返回值的内容 拼接上视图解析器的内容转发查找页面
- 返回完整的ModelAndView
无返回值
2.1.2 重定向请求
redirect: + URL地址
@RequestMapping("/mylogin.html")
public String login(){
// 重定向到首页
return "redirect:/index.html";
}
2.1.3 转发请求
forward: + URL地址
@RequestMapping("/forward-login.html")
public String login(){
// 转发到首页
return "forward:/index.html";
}
2.2 SpringMVC的JSON数据
使用 @ResponseBody
表明返回的内容作为数据发送给客户端。
默认集成 jackson的jar包。
@RequestMapping("/getjson")
@ResponseBody
public Object returnJson(){
return "index";
}
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
2.3 SpringMVC中的异常处理
使用 @ExceptionHandler 拦截当前控制器中异常
@RequestMapping("/create/ex")
@ResponseBody
public Object createException(){
return Arrays.asList(1,2,3).get(5);
}
@ExceptionHandler
@ResponseBody
public String doException(Exception e){
System.out.println("处理异常" + e.getMessage());
return e.getMessage();
}
@RequestMapping("/forward-login.html")
public String login(){
// 转发到首页
return "forward:/index.html";
}
## 2.2 SpringMVC的JSON数据
使用 `@ResponseBody` 表明返回的内容作为数据发送给客户端。
默认集成 jackson的jar包。
```java
@RequestMapping("/getjson")
@ResponseBody
public Object returnJson(){
return "index";
}
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
2.3 SpringMVC中的异常处理
使用 @ExceptionHandler 拦截当前控制器中异常
@RequestMapping("/create/ex")
@ResponseBody
public Object createException(){
return Arrays.asList(1,2,3).get(5);
}
@ExceptionHandler
@ResponseBody
public String doException(Exception e){
System.out.println("处理异常" + e.getMessage());
return e.getMessage();
}
\d ↩︎