【SpringMVC】SpringMVC基础教程(4)
前言:
本文内容:RestFul风格讲解、重定向和转发、接收请求参数及数据回显
推荐免费SpringMVC基础教程视频:【狂神说Java】SpringMVC最新教程IDEA版通俗易懂_哔哩哔哩_bilibili
RestFul风格讲解
概念
ResultFul是一个资源定位及资源操作的风格。不是标准也不是协议,而是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
功能
- 资源:互联网所有的内容都可以被抽象为资源
- 资源操作:使用Post,Delete,Put,Get等不同呢方法对资源进行操作
- 分别对应:增删改查
传统方式操作资源
通过不同的参数来实现不同的效果,方法单一(Post和Get)
- http://localhost/item/queryItem.action?id=1 查询 Get
- http://localhost/item/saveItem.action 新增 Post
- http://localhost/item/updateItem.action 修改 Post
使用RestFul风格操作资源
可以通过不同的请求方式来是实现不同的效果
- http://localhost/item/1 查询 Get
- http://localhost/item 新增 Post
- http://localhost/item 修改 Post
练习
-
新建
RestFulController.java
1
2
3
4
public class RestFulController{
} -
在Spring MVC中可以使用
@PathVariable
注解,让方法参数的值对应绑定到一个URI模板变量上1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package com.jokerdig.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Joker大雄
* @data 2022/6/3 - 16:00
**/
public class RestFulController {
// 原来的: http://localhost:8080/add?a=1&b=2
// RestFul:http://localhost:8080/add/a/b
public String test1(int a, int b, Model model){
int res = a+b;
model.addAttribute("msg","结果为"+res);
return "test";
}
}运行:http://localhost:8080/springmvc_05_controller_war_exploded/add/1/2
1
结果为3
-
也可以使用method实行指定请求类型
用于约束请求类型,指定请求的类型如:
GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE,TRACE
等1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.jokerdig.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Joker大雄
* @data 2022/6/3 - 16:00
**/
public class RestFulController {
// 原来的: http://localhost:8080/add?a=1&b=2
// RestFul:http://localhost:8080/add/a/b
// @RequestMapping(name="/add/{a}/{b}",method= RequestMethod.POST)
public String test1(int a, int b, Model model){
int res = a+b;
model.addAttribute("msg","结果为"+res);
return "test";
}
} -
所有地址栏请求默认都是HTTP GET类型的
方法级别的注解变体有如下几个:
1
2
3
4
5 -
请求的地址相同,但所执行的方法并不同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37package com.jokerdig.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
/**
* @author Joker大雄
* @data 2022/6/3 - 16:00
**/
public class RestFulController {
// 原来的: http://localhost:8080/add?a=1&b=2
// RestFul:http://localhost:8080/add/a/b
// @RequestMapping("/add/{a}/{b}")
// @RequestMapping(name="/add/{a}/{b}",method= RequestMethod.GET) name可能会报错
// @RequestMapping(value="/add/{a}/{b}",method= RequestMethod.GET)
// @RequestMapping(path="/add/{a}/{b}",method= RequestMethod.GET)
// @RequestMapping(name="/add/{a}/{b}",method= RequestMethod.POST)
public String test1(int a, int b, Model model){
int res = a+b;
model.addAttribute("msg","结果1为"+res);
return "test";
}
// 请求地址相同 但走的方法不同
public String test2(int a, int b, Model model){
int res = a+b;
model.addAttribute("msg","结果2为"+res);
return "test";
}
} -
运行测试
1
2
3
4
5
6运行:http://localhost:8080/springmvc_05_controller_war_exploded/add/1/10
浏览器显示
结果2为11
当使用表单提交后
会走Post请求的方法
地址不改变 -
小结
RestFul风格的优势:简洁、高效、安全。
重定向和转发
ModelAndView
设置ModelAndView对象,根据view的名称,和视图解析器跳到指定页面
页面:{视图解析器前缀}+viewName+{视图解析器后缀}
1 | <!-- 视图解析器--> |
对应的Controller
1 | package com.jokerdig.controller; |
ServletAPI
通过设置servletAPI,不需要视图解析器
- 通过HttpServletResponse进行输出
- 通过HttpServletResponse实现重定向
- 通过HttpServletResponse实现转发
新建ModelTest1.java
1 | package com.jokerdig.controller; |
运行测试
http://localhost:8080/springmvc_05_controller_war_exploded/mt1/t1
1 | 浏览器显示 |
SpringMVC
通过SpringMVC来实现转发和重定向(无需视图解析器)
测试前先将视图解析器注释掉
新建ModelTest2.java
进行测试
1 | package com.jokerdig.controller; |
浏览器显示
1 | ModelTest2 |
通过SpringMVC来实现转发和重定向(有视图解析器)
重定向不需要视图解析器,本质就是请求一个新的地方
新建ModelTest3.java
进行测试
1 | package com.jokerdig.controller; |
接收请求参数及数据回显
处理提交数据
-
提交的名称和处理方法的参数名一致
提交数据:http://localhost:8080/htest?name=zhangsan
处理方法
1
2
3
4
5
public String test(String name){
System.out.println(name);
return "test";
}后台输出
1
zhangsan
-
提交的名称和处理方法的参数名不一致
提交数据:http://localhost:8080/htest?uname=zhangsan
处理方法
1
2
3
4
5
public String test({ String name)
System.out.println(name);
return "test";
}后台输出
1
zhangsan
-
提交的是一个对象
要求提交的表单域和对象的属性名一致,参数使用对象即可
实体类(使用Lombok)
1
2
3
4
5<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.jokerdig.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Joker大雄
* @data 2022/6/3 - 17:49
**/
public class User {
private int id;
private String name;
private int age;
}新建
UserController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36package com.jokerdig.controller;
import com.jokerdig.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Joker大雄
* @data 2022/6/3 - 17:48
**/
public class UserController {
// localhost:8080/user/t1?name=xxx
public String test1(String name, Model model){
// 1. 接收前端参数
System.out.println("接收到前端的参数为:"+name);
// 2. 将返回的结果传递到前端
model.addAttribute("msg",name);
return "test";
}
// 前端接收的是一个对象 User(id name age)
/*
1. 接收前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
2. 假设传递的是一个对象,匹配对象中的字段名,名字一致则传递值,否则接收不到数据
*/
public String test2(User user){
System.out.println(user);
return "test";
}
}运行后输出
http://localhost:8080/springmvc_05_controller_war_exploded/user/t2?id=1&name=zhangsan&age=21
1
User(id=1, name=zhangsan, age=21)
数据显示到前端
-
通过ModelAndView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package com.jokerdig.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Joker大雄
* @data 2022/6/1 - 12:35
**/
// 只要实现Controller接口的类 就是一个控制器
public class ControllerTest implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView();
mav.addObject("msg","ControllerTest1");
mav.setViewName("test");
return mav;
}
} -
通过ModelMap
1
2
3
4
5
6// ModelMap
public String test3(ModelMap modelMap){
modelMap.addAttribute("msg","ModelMap");
return "test";
} -
通过Model
1
2
3
4
5
6
7
8
9// localhost:8080/user/t1?name=xxx
public String test1(String name, Model model){
// 1. 接收前端参数
System.out.println("接收到前端的参数为:"+name);
// 2. 将返回的结果传递到前端
model.addAttribute("msg",name);
return "test";
} -
拓展
Model 继承了 ModelMap 继承了 LinkedHashMap
-
小结
三种传递方式的区别
- Model:只有几个方法适用于储存数据,简化了使用和理解
- ModelMap:继承了
LinkedHashMap
,除了自身一些方法,同样继承LinkedHashMap
的方法和特性 - ModelAndView:可以在储存数据的同时,设置返回的逻辑视图,来控制展示层的跳转
-