请求域对象
将数据存入请求域对象
@RequestMapping("/testAttrOriginalRequest")
public String testAttrOriginalRequest(HttpServletRequest request){
//目标:将数据存储到请求域对象,然后跳转到target页面
//方式一:使用原始的request来完成
request.setAttribute("username","aobama");
return "target";
}
①使用Model对象往请求域中存储值
②在形参位置声明ModelMap类型变量,用于存储模型数据
③在形参位置声明Map类型变量,用于存储模型数据
④创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
设置视图名称
modelAndView.setViewName(“target”);
SpringMVC 传入的 Model、ModelMap、Map类型的参数其实本质上都是 BindingAwareModelMap 类型的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3hYMF4nH-1640242779352)(./img/002.png)]
会话域对象
使用会话域最简单直接的办法就是使用原生的 HttpSession 对象
@RequestMapping("/attrSession")
public String attrSession(HttpSession httpSession){
//目标:往会话域中存储数据
httpSession.setAttribute("address","召唤师峡谷");
return "target";
}
应用域
应用域同样是使用IOC注入的方式来操作:
@Autowired
private ServletContext servletContext;
@RequestMapping("/attr/application")
public String attrApplication() {
servletContext.setAttribute("appScopeMsg", "i am hungry...");
return "target";
}
1、Spring和SpringMVC的环境
- 依赖
- web.xml中的配置:servlet、filter
- springmvc配置文件:
- 包扫描:为了解析组件注解(IOC和依赖注入的主键)
- 配置Thymeleaf的模板解析器:为了解析Thymeleaf模板
- 加载MVC注解驱动:为了能够找到Handler方法处理请求
- 处理静态资源
-
view-controller
:访问页面
- 注解:
- IOC和依赖注入的注解: Controller、Service、Repository、AutoWired
- SpringMVC的注解: RequestMapping(请求映射)、RequestParam(获取请求参数)
- 日志
2. 持久层环境
- 依赖
- springmvc配置文件中配置持久层:
- 数据源
- JdbcTemplate
- 持久层实现类的方法中执行各个SQL语句
3. 测试环境
- 依赖
- Spring整合Junit
- 测试:需要测试业务层和持久层的代码
功能总结
1. 单纯跳转页面的功能
例如:访问首页、访问add.html添加页面,使用view-controller
标签实现
2. 查询功能
例如:查询电影列表、更新前的数据回显。它们的具体步骤:
- 需不需要带参数:就要看有没有查询条件
- 获取参数:
- 调用业务层的方法进行查询,获取到查询的数据
- 将查询到的数据存储到请求域
- 返回逻辑视图
- 在Thymeleaf页面获取请求域的数据,并展示
3. 增删改功能
例如:添加电影、删除电影、更新电影。它们的具体步骤:
- 肯定需要带参数:Thymeleaf的路径携带参数、以及表单携带参数
- 参数乱码:配置过滤器解决
- 获取参数:单个参数、POJO封装参数
- 调用业务层的方法进行增删改
- 重新查询所有: 使用
redirect
指令重定向访问查询所有电影
的功能
RESTFul风格交互方式
概述
其就是表现层资源转移
http使用url更加简洁也更加隐晦,使用问号传参,容易被人利用和破坏。REST 风格携带数据不再需要明显的暴露数据的名称。
操作 | 传统风格 | REST 风格 |
---|---|---|
保存 | /CRUD/saveEmp | URL 地址:/CRUD/emp 请求方式:POST |
删除 | /CRUD/removeEmp?empId=2 | URL 地址:/CRUD/emp/2 请求方式:DELETE |
更新 | /CRUD/updateEmp | URL 地址:/CRUD/emp 请求方式:PUT |
查询(表单回显) | /CRUD/editEmp?empId=2 | URL 地址:/CRUD/emp/2 请求方式:GET |
四种请求方式的映射
html中可以使用get和post请求,但是远远不够,所以SpringMVC便提 HiddenHttpMethodFilter把post请求转换为DELETE和PUT请求
put请求
1、web的xml文件
<!--一定要配置在解决乱码的Filter之后-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
html
<form th:action="@{/rest/movie}" method="post">
<input type="hidden" name="_method" value="put"/>
<button>发送请求</button>
</form>
后端的handler方法
@PutMapping("/movie")
public String updateMovie(){
logger.debug("PUT请求....");
return "target";
}
DELETE请求
表单转移
<form id="myForm" method="post">
<input type="hidden" name="_method" value="delete"/>
</form>
vue
<!--引入vue-->
<script th:src="@{/static/javaScript/vue.js}"></script>
绑定单击响应函数
var vue = new Vue({
"el":"#app",
"methods":{
deleteMovie(){
console.log("aaaaaaa")
//真正发送删除请求:
//1. 阻止标签的默认行为
event.preventDefault()
//2. 创建一个空表单:先动态设置表单的action
var myForm = document.getElementById("myForm");
myForm.action = event.target.href
//并且使用js代码提交表单
myForm.submit()
}
}
});
后端handler
@DeleteMapping("/movie")
public String deleteMovieById(){
logger.debug("DELETE请求....");
return "target";
}
PathVariable注解获取路径参数
结合REST风格
单个路径传参
<a th:href="@{/rest/movie/2}">携带参数movieId</a>
后端handler方法
//注意:{Id是一个占位符},表示获取该位置的值,@PathVariable("Id")表示获取占位符为"Id"的值
@GetMapping("/movie/{Id}")
public String findMovieById(@PathVariable("Id") Integer Id){
logger.debug("GET请求...."+movieId);
return "target";
}
多个路径参数
<a th:href="@{/rest/movie/2/22/123}">携带多个参数</a>
后端handler方法
@GetMapping("/movie/{categoryId}/{groupId}/{movieId}")
public String findMovieById(@PathVariable("categoryId") Integer categoryId,@PathVariable("groupId")Integer groupId,@PathVariable("movieId") Integer movieId){
logger.debug("GET请求...."+categoryId+":"+groupId+":"+movieId);
return "target";
}
REST的小结
- 解决什么问题: 从根据功能设计url变成根据资源设计url
- 是什么:资源状态转移Representational State Transfer
- 特征:
- 一个url就代表一个资源,也就是说通过url我们可以知道当前请求操作的是什么资源
- 请求方式代表操作,也就是说通过请求方式我们知道当前请求对当前资源做的是何种操作
- 效果:
- url更加简洁
- url更加隐晦
- 操作的幂等性
- 怎么实现:
- 请求方式映射:HTML默认只能发送GET和POST请求,SpringMVC在某些时候需要将POST请求映射成PUT或者DELETE请求
- GetMapping、PostMapping、DeleteMapping、PutMapping要选择情况使用
- 合理设计url
- 使用Pathvariable注解获取REST风格的url上的路径参数
Ajax交互
获取请求参数
普通类型参数
前端代码
sendCommon(){
axios({
"method":"POST",
"url":"ajax/commonParameter",
//params表示携带普通类型的参数
"params":{
"userName":"tom",
"password":"123456"
}
}).then(response => {
})
}
后端代码
@RequestMapping("/commonParameter")
public String commonParameter(User user){
//获取异步请求携带的普通类型参数,和以前获取同步请求携带的参数是一样的
logger.debug(user.toString());
return "hello";
}
获取JSON请求体参数
前端代码
sendJsonBody(){
axios({
"method":"POST",
"url":"ajax/jsonBodyParameter",
//data表示携带json请求体类型的参数
"data":{
"userName":"tom",
"password":"123456"
}
}).then(response => {
})
}
后端代码
@RequestMapping("/jsonBodyParameter")
public String jsonBodyParameter(@RequestBody User user){
//1. 获取Json请求体类型的参数必须要封装到POJO对象或者是Map中
//2. POJO参数或者Map参数的前面一定要加入RequestBody注解
//3. 你的项目中一定要引入jackson的依赖(因为SpringMVC默认支持jackson)
//获取Json请求体类型的请求参数和获取普通类型的参数不一样
logger.debug(user.toString());
return "success";
}
RequestBody注解
我们遇到了json数据我们必须使用RequestBody进行josn数据解析,如果遇到500的错误就说明json没有转换,想要解析 JSON 数据需要两方面支持:mvc:annotation-driven 引入 Jackson 依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
RestController注解
RestController 注解就相当于给类中的每个方法都加了ResponseBody 注解。
源码解析如下::::::