SpringMVC
文章目录
- SpringMVC
一. SpringMVC的介绍
1.1 说明
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等等
SpringMVC框架主要功能: 实现前后端的交互.
交互:
- 前端通过http请求可以携带参数访问后端服务器. 请求
- 后端服务器可以将结果通过响应交还给前端. 响应
- 底层DispatcherServlet
1.2 入门案例
1.2.1 编辑UserController
package com.jt.controller;
import com.jt.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
@Controller //将类交给SpringMVC管理,SpringMVC交给Spring管理
@ResponseBody //将数据转化为"特殊的字符"串返回
public class UserController {
/*
* URL地址:http://localhost:8080/hello get请求
* 参数 : 无
* 返回值: 你好,SpringMVC的字符串
* */
@RequestMapping("/hello")
public String hello(){
return "你好,SpringMVC";
}
}
二. SpringMVC调用原理
三. SpringMVC用法
3.1 简单参数传递
需求: 查询后端数据 参数2个数据 name=tomcat,age=18岁
URL: http://localhost:8080/findUserByNA?name=tomcat&age=18
/*
* 需求:接收参数 name=xxx age=xxx
* URL地址:http://localhost:8080/findUserNA?name=tomact&age=18 get请求
* 返回值: "数据正确:name:age"
* 知识点:
* 1.通过URL中的key获取数据
* 2.如果参数众多,可以使用对象的方式接收,要求必须得有set方法
* */
@RequestMapping("/findUserNA")
public String findUserNA(String name,int age){
return "数据正确"+name+":"+age;
}
3.2 对象方式传参
编辑User的POJO
说明:
- 属性类型 必须为包装类型
- POJO 必须添加get/set方法
- POJO类型必须实现序列号接口
package com.jt.pojo;
import java.io.Serializable;
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private String sex;
/*必须添加set/get方法/toString*/
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
编辑UserController
/*
* 需求:接收参数 name=xxx age=xxx
* URL地址:http://localhost:8080/findUserNA?name=tomact&age=18&sex=男&id=1 get请求
* 参数 : User user
* 返回值: user.toString字符串
* */
@RequestMapping("/findUserNA2")
public String findUserNA2(User user){
return user.toString();
}
响应结果
3.3 同名提交问题
3.3.1 案例说明
说明: 如果遇到同名提交问题,数据一般采用,号的方式连接. 如图所示:
编辑UserController
/*
* URL地址:http://localhost:8080/hobby?hobby=睡觉,敲代码,玩游戏,熬夜 get请求
* 参数 : hobby=睡觉,敲代码,玩游戏,熬夜
* 返回值: 获取参数返回即可
* 知识点:如果遇到同名提交问题,则SpringMVC可采用数组接收,内部自动给完成
* 补充:http://localhost:8080/hobby?age=18,19&hobby=睡觉,敲代码,玩游戏,熬夜 age属性直接被抹除了
* 底层实现:hobby.split(",");
* */
@RequestMapping("/hobby")
// public String hobby(String hobby){
// String[] array = hobby.split(",");
// return Arrays.toString(array);
// }
public String hobby(String[] hobby){
//参数名称和网页提交的key值必须相同,否则取不到对应的值,hobby获取对应的hobby值,
return Arrays.toString(hobby);
}
响应结果
3.4 restFul风格
3.4.1 传统get方式提交
url1: http://localhost:8080/findUser?name=tomcat&age=18
url2: http://localhost:8080/findUser?name=tomcat&age=18&sex=男
需求: 上述的参数传递是否可以简化!
简化写法:
url3: http://localhost:8080/findUser/tomcat/18/男
3.4.2 restFul风格说明
案例: url3: http://localhost:8080/findUser/tomcat/18/男 (发送)
要求:
- restFul的风格数据的位置一旦确定,不能修改.
- 参数与参数之间使用"/"的方式分割.
- restFul的风格适用于 get/post/put/delete 请求类型
请求类型种类: get/post/put/delete
特定写法,独立于这四种请求之外,axios.xxx(参数只能放url)…,后端方法参数如果用包装类变量接,则参数括号内需要配合@PathVariable注解使用,如果使用对象接,则不需要加任何注解辅助
关于请求路径,只要是restFul风格请求路径,后端都需要在队在路径对应的位置上加{}取值符号,否则访问不到
3.4.3 编辑后端Controller
/**
* URL地址:
* http://localhost:8080/findUser/tomcat/18/男 get类型
* 参数: name/age/sex
* 返回值: 返回值获取的数据
* restFul语法:
* 1. 参数与参数之间使用/分割
* 2. 需要接收的参数使用{}包裹
* 3. 参数接收时采用@PathVariable取值
*/
@RequestMapping("/findUser/{name}/{age}/{sex}")
public String findUser(@PathVariable String name,
@PathVariable int age,
@PathVariable String sex){
return name+":"+age+":"+sex;
}
3.4.4 测试效果
四. JSON
4.1 JSON介绍
==JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。==它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。它是基于 JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999 的一个子集。 JSON采用完全独立于程序语言的文本格式,但是也使用了类C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
4.2 JSON格式-对象格式
对象(object) 是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。`
{"id": "100","name": "tomcat", "age": "18"}
4.3 JSON格式-数组格式
数组(array) 是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
[100,"张三",true]
4.4 JSON格式-嵌套格式
值(value) 可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
[100,true,["a","b",{"name":"张三","hobbys": ["吃饭","睡觉"]}]]
五. SpringMVC前后端交互
5.1 业务说明
问题说明1: 前端访问后端服务器,一般采用Ajax方式进行数据传递. 后端服务器返回给前端页面 通常采用JSON格式数据
问题说明2: 后端服务器怎么接收前端的参数的. servlet机制
问题: 后端服务器如何返回JSON串
5.2 @ResponseBody
5.2.1 案例测试
需求: 根据name/age 查询用户,要求返回User对象的JSON串
URL: http://localhost:8080/findJSON?name=tomcat&age=18
/*
*URL地址:http://localhost:8080/findJSON?name=tomcat&age=18
* 参数: name,age
* 返回值 :返回User对象的json
* 知识点:
* 1.@ResponseBody 将我们的返回值转化为JSON串
* 2.如果返回值为String类型,则@ResponseBody将字符串本身返回给前端
* 注意点: 1.springMVC中的请求路径不能重复
* 2.可以在类上添加@RequestMapping("/业务名称")自定义前缀
* */
@RequestMapping("/findJSON")
@ResponseBody //将我们的返回值转化为JSON串
public User findJSON(User user){
//在业务层扩展数据
user.setId(101);
user.setSex("男");
/* user对象转化为JSON*/
return user;
}
5.2.2 测试结果
5.3 @RestController注解
5.3.1 编辑RestUserController
package com.jt.controller;
import com.jt.pojo.User;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
//@Controller //将类交给SpringMVC管理
//@ResponseBody //当前类中的所有方法 都返回JSON串
@RestController // = @Controller + @ResponseBody
@RequestMapping("/rest")
public class RestUserController {
/**
* 注意事项:
* 1.springMVC中的请求路径不能重复!!!!
* 2.可以@RequestMapping("/业务名称")自定义前缀
* @return
*/
@RequestMapping("/findJSON")
public User findUser(User user){
user.setId(105);
user.setSex("男");
return user;
}
}
5.3.2 测试效果
知识小结
-
restFul风格
特点:
1.参数写到url中使用/分割
2.接收时采用{xxxx} 使用@PathVariable注解获取
3.支持请求类型 post/put/get/delete -
JSON串
格式: 1.对象格式 2.数组格式
嵌套格式: value可以嵌套
易错项: json格式必须添加""号 -
注解:
1.@ResponseBody 将返回值转化为JSON
2.@RestController 将当前类的所有返回值都转化为JSON
六. Axios前后端业务交互
6.1 项目环境搭建
6.2 Axios 讲解
6.2.1 Ajax介绍
Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。 [3] 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。 [3]
功能和作用: Ajax主要实现前后端交互.提高用户页面与服务器之间交互效率.
特点: 局部刷新,异步访问
axios只支持四种请求方式,get,delete,post,put
6.2.2 Ajax异步原理说明
组成部分:
- 用户
- Ajax引擎–代理
- 服务器
异步的特点:
- 由Ajax引擎直接访问后端服务器。
- 在回调函数没有执行之前,用户可以执行自己的任务。 异步
6.2.3 Axios入门案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Axios测试</title>
<script src="../js/axios.js"></script>
</head>
<body>
<h1>Axios测试案例-1</h1>
<script>
/*
1.可以编辑Axios 发送ajax请求
2.不同的服务器之间发送ajax请求时会有"跨域"问题
3.解决跨域问题 通过注解搞定. @CrossOrigin
axios.get("url地址","传递的数据").then(function(result){
console.log(result)
})
*/
var url = "http://localhost:8080/hello"
axios.get(url)
.then(function(result){ //回调函数!!!
console.log(result)
})
axios.get(url).then(result =>{//回调函数
console.log(result);
})
</script>
</body>
</html>
6.2.4 后端
@RestController //@RestController = @Controller + @ResponseBody
@CrossOrigin //允许跨域
public class UserController {
/*
* URL地址:http://localhost:8080/hello get请求
* 参数 : 无
* 返回值: 你好,SpringMVC的字符串
* */
@RequestMapping("/hello")
public String hello(){
return "你好,SpringMVC";
}
}
6.2.5 页面效果展现
6.3 前后端交互案例(get)
Axios-Get-对象参数写法
Axios-Get-restFul结构
前端:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Axios测试</title>
<script src="../js/axios.js" type="text/javascript">
</script>
</head>
<body>
<h1>Axios测试案例-1</h1>
<script type="text/javascript">
// var 关键字没有作用域的概念
// let 关键字 相当于var ,但是有作用域,更加安全
// const 定义常量的
// 关于axios数据返回值对象的说明:axios为了接收后端的数据,利用promise对象封装参数
let url="http://localhost:8080/axios/getUserById?id=100";
axios.get(url).then(function(promise){//回调函数
console.log(promise.data);
})
//1.get请求 对象传参
//2.语法说明:
// 关键字: params : 对象信息
// 底层实现还是相当于在url后面进行?key1=value1&key2=value2....拼接
let user2 = {name:"aaa",age:100}
let url2="http://localhost:8080/axios/getUserByNA";
axios.get(url2,{params:user2}).then(function(promise){//回调函数
if(promise.status==200){//status 状态码
console.log("业务执行成功");
console.log(promise);
console.log(promise.data);
}else{
console.log("业务请求失败");
}
})
/**
*需求 :利用restFul的风格实现前后端交互
*url:http://localhost:8080/axios/findUserByNS/tomcat/男
* 难点:
* 1.tomcat/男直接写死在url地址种,后期扩展不方便
* 模板字符串写法:ES6引入的新功能
* 语法:
* 1.使用反引号 ``
* 2.作用: 1.可以保证字符串的格式(字符串涉及到换行的时候,格式就失效了)
* 2.可以动态获取变量值
*/
let user3={name:"tomcat",sex:"男"};
let url3=`http://localhost:8080/axios/findUserByNS/${user3.name}/${user3.sex}`
axios.get(url3).then(function(promise){
if(promise.status==200){
console.log("业务执行成功");
console.log(promise.data)
}else{
console.log("业务请求失败");
}
})
</script>
</body>
</html>
后端
@RestController
@CrossOrigin //主要解决跨域问题
@RequestMapping("/axios")
public class AxiosController {
/*
* 业务需求: 根据ID查询用户信息
* url地址: http://localhost:8080/axios/getUserById?id=100
* 参数:id=100
* 返回值:User对象的JSON字符串 伪造一个User对象
*
* */
@RequestMapping("/getUserById")
public User getUserById(Integer id){
User user = new User();
user.setId(id);
user.setName("张三");
user.setAge(20);
user.setSex("男");
return user;
}
/*
* 业务需求: 根据ID查询用户信息
* url地址: http://localhost:8080/axios/getUserByNA?id=xxx&name=xxxx
* 参数:id=xxx name=xxxx
* 返回值:list<User>
*
* */
@RequestMapping("/getUserByNA")
public List<User> getUserByNA(User user){
ArrayList<User> list = new ArrayList<>();
list.add(user);
list.add(user);
return list;
}
/*
* 业务需求: 查询name=tomcat sex="男"的用户, 要求请求采用restFul的风格实现数据获取
* url地址: http://localhost:8080/axios/findUserByNS/tomcat/男
* 参数:name/sex
* 返回值:list<User> 规格:返回值为一个就是对象接,多个用集合接
*
* */
@RequestMapping("/findUserByNS/{name}/{sex}")//存在同名属性,调用set方法为属性赋值
public List<User> findUserByNS(User user){
ArrayList<User> list = new ArrayList<>();
list.add(user);
list.add(user);
return list;
}
}
6.4 前后端交互案例(post)
6.4.1 常见的post请求种类
- form表单提交 method=“post” 同步(要素:页面是否刷新)
- axios.post() 异步操作.
6.4 2 axios post入门案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Axios测试</title>
<script src="../js/axios.js"></script>
</head>
<body>
<h1>Axios测试案例-2</h1>
<script>
/*
语法:
1.参数 axios.post(URL地址,数据对象)
2.注意事项: 与axios.get(url,{params:对象})请求写法不一样.
*/
let url1 = "http://localhost:8080/axios/saveUser"
let user1 = {id:100, name:"猫", age:2, sex: "母"}
axios.post(url1,user1)
.then(function(promise){
console.log(promise.data)
})
</script>
</body>
</html>
6.4.3 前端页面解析
说明: axios.post请求中 如果传递了js对象.则发送到后端服务器的数据是 JSON串.
6.4.4 编辑AxiosController
@RestController
@CrossOrigin //主要解决跨域问题
@RequestMapping("/axios")
public class AxiosController {
/*
* url1:"http://localhost:8080/axios/saveUser"
* 参数:{"id":100,"name":"猫","age":2,"sex":"母"} json串
* 返回值 "新增用户成功"
* 难点:
* 1.get请求 数据是通过?key=value&key2=value2的方式获取
* post请求 数据是json串,数据结构不同,不能使用user对象接收
* 2.JSON串 想办法转化为user对象
* user转化为json串 用的是@ResponseBody注解
* json转化成user串 用的是@RequestBody注解,只能在post和put请求中使用,不能用在get和delete请求中
* 3.json串中的属性与对象中的属性一致,并且调用对象的set方法
* (其实一不一样无所谓,user会把同名的属性写进去,不同命的就过滤掉了,程序本身不会报错)
* 4.@RequestMapping可以支持任意类型的请求,但是这样的写法不安全
* 要求只接收post类型的请求
* 改进: @GetMapping
* @PostMapping("/saveUser")
* @DeleteMapping
* @PutMapping
* */
// @RequestMapping(value = "/saveUser",method = RequestMethod.POST)
@PostMapping("/saveUser")
public String saveUser(@RequestBody User user){//只能在post请求中使用,不能用在get请求中
System.out.println(user);
return "新增用户成功";
}
}
6.4.5 页面效果测试
6.4.6 关于请求常见异常
- 405 异常 ajax的请求类型与后端接收的请求类型不匹配.
- 400异常 参数类型不匹配
- 404异常 请求路径找不到
6.5 请求类型和业务关系
6.5.1 常见请求类型:
-
GET 查询操作
-
DELETE 删除操作 (get和delete请求的用法完全相同)
-
POST 1.表单数据提交 2.新增操作
-
PUT 修改操作(post和put请求的用法完全相同)
6.5.2 用户修改操作
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios案例测试2</title>
<script src="../js/axios.js"></script>
</head>
<body>
<h1>axios案例测试2</h1>
<script>
/*
* 业务需求:
* 完成用户的修改操作,将ID=100的数据,name改为张三,age改为18,sex改为女
* url:http://localhost:8080/axios/updateUser
* 返回值:修改成功 数据要求后端打印
*
* */
let url2="http://localhost:8080/axios/updateUser";
let user2={id:100,name:"张三",age:18,sex:"女"};
axios.put(url2,user2).then(function (promise) {
console.log(promise.data)
});
axios.put(url2,user2).then(function (promise) {
console.log(promise.data)
});
</script>
</body>
</html>
后端
@RestController
@CrossOrigin //主要解决跨域问题
@RequestMapping("/axios")
public class AxiosController {
/*
* url:http://localhost:8080/axios/updateUser
* 参数:json串
* 返回值:String
*
* */
// @PutMapping("/updateUser/{id}/{name}/{age}/{sex}")
@PutMapping("/updateUser")
public String updateUser(@RequestBody User user){
System.out.println(user);
return "修改成功";
}
}
6.5.3 用户删除操作
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios案例测试2</title>
<script src="../js/axios.js"></script>
</head>
<body>
<h1>axios案例测试2</h1>
<script>
/*
* 业务需求:根据id删除用户
* url3:http://localhost:8080/axios/deleteUserById?id=1
* url3:http://localhost:8080/axios/deleteUserById/1
* url3:http://localhost:8080/axios/deleteUserById
* 返回值:删除成功 数据要求后端打印
* */
let user3={id:1};
// let url3="http://localhost:8080/axios/deleteUserById?id=1"
// let url3="http://localhost:8080/axios/deleteUserById/1"
// let url3=`http://localhost:8080/axios/deleteUserById/${user3.id}`
let url3=`http://localhost:8080/axios/deleteUserById`
axios.delete(url3,{params:user3}).then(function (promise) {
console.log(promise.data)
})
</script>
</body>
</html>
后端
@RestController
@CrossOrigin //主要解决跨域问题
@RequestMapping("/axios")
public class AxiosController {
@DeleteMapping("/deleteUserById")
@DeleteMapping("/deleteUserById/{id}")
public String deleteUserById(User user){
System.out.println(user);
return "删除成功";
}
}
6.6 Axios的简化写法
6.6.1 编辑WebController
@RestController
@CrossOrigin //标识跨域的
@RequestMapping("/web")
public class WebController {
/**
* URL: http://localhost:8080/web/hello
* 类型: get
* 返回值: String
*/
@GetMapping("/hello")
public String hello(){
return "好好学习,天天向上";
}
}
6.6.2 编辑页面HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试案例</title>
<script src="../js/axios.js"></script>
</head>
<body>
<h1>axios简化测试</h1>
<script type="text/javascript">
/*简化方式1:抽取后端服务器地址:*/
/*简化方式2:使用箭头函数:,参数只有一个时候,(promise)=>的括号也可以省略*/
/*简化方式3:async await简化调用 重点
* 问题描述:如果ajax嵌套的层级较多,则可能会引发"回调地狱"问题
* 解决问题:能否将axios中的then进行简化
* 语法:
* 1.使用async关键字标识函数
* 2.通过await标识ajax的请求
* 3.必须同时出现
* */
axios.defaults.baseURL="http://localhost:8080"
// let url1="/web/hello";
// axios.get("/web/hello").then(promise => {
// console.log(promise.data)
// })
async function getHello() {
// let promise = await axios.get("/web/hello");
// console.log(promise.data);
//个人理解:类似于后端使用user对象接收到json串,调用set方法将同名属性赋值
let {data:result,status:code} = await axios.get("/web/hello");
console.log(result);
console.log(code);
}
getHello();//调用函数
</script>
</body>
</html>
6.7 跨域问题
6.7.1 同源策略
要素:
- 浏览器URL中的地址 例子:http://localhost:8848/webDemo/demo/3-axios.html
- Ajax请求的URL地址 例子: http://localhost:8080/web/hello
要求:上述要素必须满足 协议/域名/端口号都相同时.表示满足同源策略.
说明:
如果满足同源策略,则称之为 “同域访问” 反之称之为 “跨域访问” 跨域访问浏览器一般都会报错
6.7.2 关于跨域案例讲解(axios不支持跨域,所以要配置跨域注解)
案例1:
浏览器地址: http://localhost:8080/xx/xxx
Ajax地址: https://localhost:8080/yy/yyyy 跨域请求:协议不同
案例2:
前提: 域名与IP地址对应
浏览器地址: http://www.jt.com:8080/xx/xxx
Ajax地址: http://10.4.5.2:8080/yy/yyyy 跨域请求:域名不同
案例3:
浏览器地址: http://www.jt.com/xx/xxx
Ajax地址: http://www.jt.com:80/yy/yyyy 同域请求:http端口号默认80(可写可不写)
案例4:
浏览器地址: https://www.jt.com:443/xx/xxx
Ajax地址: https://www.jt.com:443/yy/yyyy 同域请求: https协议默认443端口(可写可不写)
案例5:
迷惑: IP表示同一个网段
浏览器地址: http://192.168.10.2:80/xx/xxx
Ajax地址: http://192.168.11.2:80/yy/yy 跨域请求: 域名不匹配
6.7.3 跨域解决方案
-
jsonp 方式跨域 淘汰了.
-
CORS 跨域资源共享
跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。
总结: CORS要求在服务器端标识哪个网址可以跨域
@RestController
@CrossOrigin //标识跨域,允许跨域访问,没有限定
//@CrossOrigin(value = "http://baidu.com") //指定域名访问
@RequestMapping("/web")
public class webController {}
七. SpringMVC调用原理
7.1 Servlet的作用
说明:servlet是浏览器煜服务器(tomcat)进行交互的一种机制
核心对象:
-
Request包含了用户的所有的请求相关信息(参数…协议…地址)
-
Response包含了服务器的相关信息(服务器的地址,返回得到数据)
7.2 重要组件
1). 前端控制器 DispatcherServlet(内部核心机制) 接收用户所有请求
2). 处理器映射器 HandlerMapping 查找用户的请求与业务处理的映射
3). 处理器适配器HandlerAdapter 在众多处理器中挑选合适的处理器去执行业务.
4). 视图解析器ViewResolver 实现页面的路径的拼接.
7.3 SpringMVC调用流程图
7.4 SpringMVC调用步骤
1.当用户发起请求时,被SpringMVC框架中的前端控制器拦截.
2.由于前端控制器,并不清楚哪个方法与请求对应,所以查询处理器映射器.
3.当tomcat服务器启动,则处理器映射器会加载所有的@RequestMapping注解,将其中的路径与方法进行绑定. Map</请求路径,包名.类名.方法名(参数)>,将查找到的方法信息回传给前端控制器 进行后续调用.
4.秉承着松耦合的思想,前端控制器将查询得到的方法, 请求处理器适配器(mvc针对不同的配置文件有专门的处理器(运行程序的机制))挑选合适的处理器去执行(程序内置的规则 无需人为干预)
5.当挑选合适的处理器之后,程序开始真正的执行业务方法. Controller-Service-Mapper(Dao),执行业务. 当业务执行成功之后.返回统一的ModelAndView对象.
其中包含2部分数据 1-Model(服务器数据) 2.View(页面逻辑名称)
6.当前端控制器获取ModelAndView对象之后,交给视图解析器 解析View对象的逻辑名称. 动态的拼接前缀 + 页面逻辑名称 + 后缀. 最终形成了用户展现页面的全路径.
7.将Model数据填充到页面中的过程,叫做视图渲染. 渲染之后,将数据交给前端控制器处理.
8.将得到的完整页面 响应给用户进行展现.