MVC是Model View Controller的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分

Spring Web MVC是基于Servlet API构建的原始 Web 框架 ,从⼀开始就包含在Spring框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-web mvc),但它通常被称为"Spring MVC"。
MVC是⼀种架构设计模式,也是⼀种思想, ⽽SpringMVC是对MVC思想的具体实现.除此之外,Spring MVC还是⼀个Web框架.也就是说:Spring MVC是⼀个实现了MVC模式的Web框架.
那么上篇博客写的SpringBoot和这个Spring Web MVC之间由什么关系吗? 我们知道SpringBoot是一个便捷的开发框架,在创建SpringBoot项目时,选择的Spring Web就是Spring MVC。

总结: Spring Boot 只是实现SpringMVC的其中⼀种⽅式⽽已。Spring Boot 可以添加很多依赖,借助这些依赖实现不同的功能.SpringBoot通过添加Spring Web MVC框架,来实现web功能

既然是Web框架,那么只要在浏览器中输入url后,Spring MVC项目就能感知到请求,并响应。所以Web就可以调用Servlet来与浏览器交互。

上图是Servlet的官方解释,我们通俗理解 Servlet 是客户端和服务端交互的工具,是⼀种实现动态⻚⾯的技术。准确来讲Servlet是一套Java Web开发的规范,实现这个规范的产品包括:Tomcat、Weblogic、Jetty、Jboss、WebSphere等,抽象认为是"Servlet 容器"。
目的就是使用如何通过浏览器和⽤⼾程序进⾏交互。
因为Spring Boot 只是实现Spring MVC的其中⼀种⽅式,所以目前Spring MVC项⽬创建和SpringBoot创建项⽬相同,在创建的时候选择SpringWeb就相当于创建了Spring MVC的项⽬.

在Spring MVC中使用 @RequestMapping 注解来实现URL路由映射,连接浏览器和程序
路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射
import org.springframework.web.bind.annotation.*;
@RequestMapping("/hello")//类路径
@RestController
public class HelloController {
//既支持get又支持post
@RequestMapping("/hello")//方法路径
public String hello(){
return "hello spring boot";
}@RequestMapping 是Spring Web MVC最常用的注解之一,用来注册接口的路由映射的。 @RestController Spring会对所有的类进⾏扫描,如果类加了注解@RestController,Spring才会去看这个类⾥⾯的⽅法有没有加@RequestMapping 。相当于程序的入口。
运行程序后,通过浏览器访问就可以看到数据了。

在之前网络知识学习中,fiddler抓包抓到的数据,报头有GET也有POST,表示了此次请求的类型是GET请求还是POST请求。 首先,@RequestMapping 既⽀持Get请求,⼜⽀持Post请求,那么我们能否指定GET或者POST类型呢?
import org.springframework.web.bind.annotation.*;
@RequestMapping("/hello")
@RestController
public class HelloController {
//既支持get又支持post
@RequestMapping("/hello")
public String hello(){
return "hello spring boot";
}
@RequestMapping(value="/hello2",method = RequestMethod.GET)
public String hello2(){
return "hello spring boot2";
}
@RequestMapping(value="/hello3",method = RequestMethod.POST)
public String hello3(){
return "hello spring boot3";
}
@GetMapping("/hello4")
public String hello4(){
return "hello spring boot4";
}
@PostMapping("/hello5")
public String hello5(){
return "hello spring boot5";
}
}一般直接使用@GetMapping 或者 @PostMapping注解即可。 那么我们测试后端方法时,是不是只能通过浏览器去测试呢?又如何测试Post呢? 我使用专业的接口测试工具—Postman,具体的使用方法就需要大家去自己接触了,我这里不阐述了。
访问不同的路径,就是发送不同的请求.在发送请求时,可能会带⼀些参数,所以学习Spring的请求,主要是学习如何传递参数到后端以及后端如何接收.
import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r1")
public String r1(String keyword){
return "接受参数"+keyword;
}
}
如果参数不一致,是获取不到参数的。
和接收单个参数⼀样,直接使⽤⽅法的参数接收即可.使⽤多个形参
import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r2")
public String r1(String userName,String password){
return "接受参数:"+userName+",password:"+password;
}
}
当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果
如果方法需要很多参数,并且后续每增加一个参数都需要修改方法声明,我们可以把这些参数封装成一个对象。
//UserInfo对象
public class UserInfo {
private String name;
private Integer gender;
private Integer age;
public UserInfo(){
}
public UserInfo(String name, Integer gender, Integer age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "UserInfo{" +
"name='" + name + '\'' +
", gender=" + gender +
", age=" + age +
'}';
}
}import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/m1")
public Object method(UserInfo userInfo){
return userInfo.toString();
}
}
特殊情况下,前端传递的参数和后端接收的参数不一致,这种情况可以使用@RequestParam 注解来重命名前后端的参数。
import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r4")
public String r4(@RequestParam("q")String keyword){
return "接收参数:keyword"+keyword;
}
}
去查看@RequestParam 的实现可以发现required的默认值是true,表示该注解修饰的参数默认为必传参数,那么我们就可以通过设置@RequestParam 中required=false来避免必传参数。

import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r5")
public String r5(String[] arr){
return "接收参数:"+ Arrays.toString(arr);
}
}
import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r6")
public String r6(@RequestParam List<Integer> list){//参数绑定
return "接收参数:list="+ list;
}
}
JSON:JavaScript Object Notation 【JavaScript 对象表⽰法】 简单来说:JSON就是⼀种数据格式, 有⾃⼰的格式和语法,使⽤⽂本表⽰⼀个对象或数组的信息,因此JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换
JSON的语法: 1. 数据在键值对(Key/Value)中 2. 数据由逗号分隔 3. 对象用 {} 表示 4. 数组用 [] 表示 5. 值可以为对象,也可以为数组,数组中可以包含多个对象
优点:
JSON在Web应⽤程序中被⼴泛使⽤,如前后端数据交互、API接⼝数据传输等
JSON字符串与Java对象互转:
public class JSONUtils {
private static ObjectMapper objectMapper = new ObjectMapper();
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setId(5);
person.setName("zhangsan");
person.setPassword("123456");
//对象转为JSON字符串
String jsonStr = objectMapper.writeValueAsString(person);
System.out.println("JSON字符串为:"+jsonStr);
//JSON字符串转为对象
Person p = objectMapper.readValue(jsonStr,Person.class);
System.out.println("转换的对象id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword());
}
}writeValueAsString: 把对象转为JSON字符串 readValue: 把字符串转为对象
import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r7")
public String r7(@RequestBody UserInfo userInfo){
return userInfo.toString();
}
}@RequestBody 请求正文,这个注解作⽤在请求正⽂的数据绑定,请求参数必须在写在请求正⽂中

抓包看到,请求参数类型为json

import org.springframework.web.bind.annotation.*;
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/article/{articleId}")
public String r8(@PathVariable("articleId") Integer article){
return "获取文章ID:"+article;
}
}如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时,需要@PathVariable的属性value赋值

@RequestMapping("/m9")
public String getfile(@RequestPart("file") MultipartFile file) throws IOException {
//获取⽂件名称
String fileName = file.getOriginalFilename();
//⽂件上传到指定路径
file.transferTo(new File("D:/temp/" + file.getOriginalFilename()));
return " 接收到⽂件名称: "+fileName;
}
}这里需要我们对网络由一定了解,具体可以去看看我的博客:【Java EE初阶 — 网络原理】应用层—HTTP(HTTPS)协议
Session(会话):计算机领域中,会话是⼀个客⼾与服务器之间的不中断的请求响应。 服务器同⼀时刻收到的请求是很多的.服务器需要清楚的区分每个请求是属于哪个⽤⼾,也就是属于哪个会话,就需要在服务器这边记录每个会话以及与⽤⼾的信息的对应关系. Session是服务器为了保存⽤⼾信息⽽创建的⼀个特殊的对象 整个过程:
Cookie和Session的区别: • Cookie是客⼾端保存⽤⼾信息的⼀种机制.Session是服务器端保存⽤⼾信息的⼀种机制. • Cookie和Session之间主要是通过SessionId关联起来的,SessionId是Cookie和Session之间的桥梁 • Cookie和Session经常会在⼀起配合使⽤.但是不是必须配合**
@RequestMapping("/request")
@RestController
public class RequestController {
@RequestMapping("/r10")
public String r10(HttpServletRequest request, HttpServletResponse response){
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies){
System.out.println(cookie.getName()+":"+cookie.getValue());
}
}
return "返回cookie成功";
}
}Spring MVC是基于ServletAPI构建的原始Web框架,也是在Servlet的基础上实现的,所以HttpServletRequest , HttpServletResponse 两个类是Servlet提供的,是Spring MVC⽅法的内置对象.需要时直接在⽅法中添加声明即可

Session存储
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request){
//从cookie中获取sessionId,根据sessionId获取session对象
HttpSession session=request.getSession(true);
//默认存在内存
session.setAttribute("userName","zhangsan");
session.setAttribute("age",10);
return "设置session成功";
}Session读取
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request){
//从cookie中获取sessionId, 根据sessionId 获取Session对象
HttpSession session = request.getSession(false);
//如果用户登录, session 有值, 未登录, session为null
if (session==null){
return "用户未登录";
}else {
//从session中获取登录用户的信息
String userName = (String)session.getAttribute("userName");
return "登录用户为: " + userName;
}
}@RequestMapping("/getSession2")
public String getSession2(HttpSession session){
//从session中获取登录用户的信息
String userName = (String)session.getAttribute("userName");
return "登录用户为: " + userName;
}@RequestMapping("/getSession3")
public String getSession3(@SessionAttribute("userName") String userName){
return "登录用户为:"+userName;
}三种获取方法皆可。
//使用Selvert获取Header
@RequestMapping("/getHeader")
public String getHeader(HttpServletRequest request){
String userAgent=request.getHeader("User-Agent");
return "从header中获取userAgent"+userAgent;
}//使用RequestHeader注解获取Header
@RequestMapping("/getHeader2")
public String getHeader2(@RequestHeader ("user-Agent")String userAgent){
return "从header中获取userAgent"+userAgent;
}