Spring MVC

🔎什么是 Spring MVC


Spring Web MVC 是基于 Servlet 构建的原始 Web 框架, 包含在 Spring 框架中.
Spring Web MVC 来自其源模块的名称(Spring-webmvc), 但通常称作 Spring MVC

  • Spring MVC 构建在 Servlet 之上
  • Spring MVC 是一个 Web 框架
  • Spring MVC 基于 Spring-webmvc 模块

MVC


MVC(Model View Controller)—模型视图控制器

  • Model(模型), 应用程序中用于处理应用程序数据逻辑的部分. 通常模型对象负责在数据库中存取数据
  • View(视图), 应用程序中用于处理数据显示的部分. 通常视图是依据模型数据创建的
  • Controller(控制器), 应用程序中用于处理用户交互的部分. 通常控制器负责从视图读取数据, 控制用户输入, 并向模型发送数据

在这里插入图片描述

对比 MVC 与 Spring MVC


MVC 与 Spring MVC 之间的关系类似于 IOC(思想) 与 DI(思想的具体实现) 之间的关系

MVC 是一种思想
Spring MVC 是对 MVC 思想的具体实现

🔎Spring MVC—连接


利用 Spring MVC 输出 hello world🍭

在 demo 包下创建一个 controller 包
在 controller 包下创建一个 TestController 类

demo(package) → controller(package) → TestController(.class)

在这里插入图片描述

  • @Controller, 存储 TestController 至 Spring 容器
  • @ResponseBody, 返回数据而非页面
  • @RequestMapping(), 设置请求路径

注意🍂

  1. @Controller可与@ResponseBody合并为@RestController
  2. @RequestMapping()既可以修饰类也可以修饰方法

完整代码🍂

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

// @Controller
// @ResponseBody
@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/hello")
    public String sayHello() {
        return "hello world";
    }

}

运行结果🍂

在这里插入图片描述

@RequestMapping 默认情况下支持的请求类型


@RequestMapping 默认情况下支持多种 HTTP 请求
包括 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…

可通过 Postman 工具进行查看

在这里插入图片描述

@RequestMapping 指定请求类型


通过 method 属性指定请求的类型

在这里插入图片描述

可指定的请求类型

在这里插入图片描述

举个栗子🌰

指定 GET 请求method = RequestMethod.GET

完整代码

@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String sayHello() {
        return "hello world";
    }

}

另一种指定 GET 请求的方式
(其他类型同理)

@GetMapping("/hello")

效果与@RequestMapping(value = "/hello", method = RequestMethod.GET)相同

此时通过其他请求进行访问就会报错

405(Method Not Allowed)—方法不被允许

在这里插入图片描述

🔎Spring MVC—获取参数


获取单个参数


@RestController
@RequestMapping("/test")
public class TestController {

    // 获取单个参数
    @GetMapping("/hello")
    public String sayHello(String name) {
        return "hello " + name;
    }
    
}

注意🍭

URL 中的 key 必须与所传参数一致

在这里插入图片描述

错误示范🍭

在这里插入图片描述

获取两个参数


@RestController
@RequestMapping("/test")
public class TestController {

    // 获取两个参数
    @GetMapping("/hello")
    public String sayHello(String name, Integer age) {
        return "hello name: " + name + " | age: " + age;
    }
    
}

注意🍭

建议传参的类型为包装类型, 而非基础类型

在这里插入图片描述

错误示范🍭

当传参的类型为基础类型时

// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, int age) {

    return "hello name: " + name + " | age: " + age;
    
}

在这里插入图片描述

当传参的类型为包装类型时

// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, Integer age) {

    return "hello name: " + name + " | age: " + age;
    
}

在这里插入图片描述

参数重命名


利用注解@RequestParam为参数重命名

举个栗子🌰

有两个参数 String t1(起始时间), String t2(结束时间)

滑稽老哥觉得 t1, t2 这两个名字不太好, 想要改成 startTime, endTime

于是利用注解@RequestParam为参数重命名

将 t1 重命名为 startTime
将 t2 重命名为 endTime

@GetMapping("time")
public String showTime(
		@RequestParam(value = "t1", required = false) String startTime, 
		@RequestParam(value = "t2", required = false) String endTime) {

    return "开始时间: " + startTime + " | 结束时间: " + endTime;
    
}

对于 required 的解释🍭

分析@RequestParam()源码发现, required默认为 true

即忘记填写对应的 key 时就会报错

在这里插入图片描述

在这里插入图片描述

设置required为 false

在这里插入图片描述

传递对象


当所需获取的参数较多时, 可通过传递对象的方式进行传参

设置对象属性🍂

@Data
public class User {
    private int id;
    private String name;
    private int age;
}

传递对象🍂

@RestController
@RequestMapping("/test")
public class TestController {

	// 传递对象
    @GetMapping("/user")
    public String showUser(User user) {
        return user.toString();
    }	

}

注意🍭

URL 中的 key 必须与所传对象的属性一致

在这里插入图片描述

错误示范🍭

在这里插入图片描述

传递 JSON 对象


利用注解@RequestBody传递 JSON 对象

@RestController
@RequestMapping("/test")
public class TestController {

	// 传递 JSON 对象
	@PostMapping("/json-user") // 推荐使用 @PostMapping
	public String showJsonUser(@RequestBody(required = false) User user) {
    	return user.toString();
	}

}

在这里插入图片描述

注意🍭

此处不建议使用@GetMapping传递 JSON 对象 , @GetMapping默认使用 URL 传递参数

获取 URL 中的参数


http://127.0.0.1:8080/test/login?username=bibubibu

http://127.0.0.1:8080/test/login/bibubibu

此处所指获取 URL 中的参数是后者的形式

/后面就是参数, 而不是?username=bibubibu

利用注解@PathVariable获取 URL 中的参数

举个栗子🌰

需要传递的参数用 { } 包裹

{username}
{password}

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/login/{username}/{password}")
    public String login(
            @PathVariable(value = "username", required = false) String username,
            @PathVariable(value = "password", required = false) String password) {

        return "username: " + username + " | password: " + password;
    }
    
}

在这里插入图片描述

上传文件


利用注解@RequestPart上传文件

@RestController
@RequestMapping("/test")
public class TestController {

	// 上传文件
    @RequestMapping("/upfile")
    public String upFile(@RequestPart("files") MultipartFile file) throws IOException {
        // 1. 根目录
        String path = "D:\\Java\\documents\\png_file\\";
        // 2. 根目录 + 唯一文件名
        path += UUID.randomUUID().toString().replace("-", "");
        // 3. 根目录 + 唯一文件名 + 文件后缀
        path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 4. 保存文件
        file.transferTo(new File(path));
        
        return path;
    }	
    
}

在这里插入图片描述

在这里插入图片描述

获取 Cookie / header / Session


Spring MVC 内置了 HttpServletRequest, HttpServletResponse

传统方式获取 Cookie


传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

	@RequestMapping("/getCookies")
    public String getCookies(HttpServletRequest req) {
        Cookie[] cookies = req.getCookies();

        for(Cookie item : cookies) {
            log.error(item.getName() + " | " + item.getValue());
        }

        return "getCookies~~";
    }
    
}    

校验🍭

添加 Cookie

在这里插入图片描述

运行查看结果

在这里插入图片描述

在这里插入图片描述

利用注解获取 Cookie


利用注解获取 Cookie—通过@CookieValue获取(获取指定 Cookie)

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

	@RequestMapping("/getCookie")
    public String getCookie(@CookieValue("Homo") String val) {

        log.error("Homo | " + val);
        return "getCookie~~";

    }
    
}    

运行查看结果

在这里插入图片描述

在这里插入图片描述

传统方式获取 header


传统方式获取 header—通过 Servlet 获取

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/getUser-Agent")
	public String getHeader(HttpServletRequest req) {
    	String userAgent = req.getHeader("User-Agent");
    	return "tradition | UserAgent : " + userAgent;
	}
    
} 

运行查看结果

在这里插入图片描述

利用注解获取 header


利用注解获取 header—通过@RequestHeader获取

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/getUser-Agent")
    public String getUA(@RequestHeader("User-Agent") String userAgent) {
        return "Annotation | UserAgent : " + userAgent;
    }
    
} 

运行查看结果

在这里插入图片描述

Session 的存储与获取


存储 Session

利用 Servlet 存储 Session

对于getSession(), getSession(true), getSession(false)的解释

  • getSession(true), 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 Session
  • getSession(false), 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 返回 Null
  • getSession(), 等同于getSession(true)
@RestController
@RequestMapping("/test")
public class TestController {

	// 通过 Servlet 存储 Session
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest req) {
        // 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 Session
        HttpSession session = req.getSession(true);
        // 设置 key, value
        session.setAttribute("userInfo", "userInfo");
        return "Set Session Success";
    }
    
}
获取 Session

获取 Session 有 2 种方式

  1. 通过 Servlet 获取
  2. 通过 @SessionAttribute 获取
通过 Servlet 获取

@RestController
@RequestMapping("/test")
public class TestController {

	// 通过 Servlet 获取 Session
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest req) {
        HttpSession session = req.getSession(false);
        
        if(session != null && session.getAttribute("userInfo") != null) {
            return (String) session.getAttribute("userInfo");
        } else {
            return "session 信息不存在";
        }
    }
    
}
通过 @SessionAttribute 获取

@RestController
@RequestMapping("/test")
public class TestController {

	// 通过 @SessionAttribute 获取 Session
    @RequestMapping("/getSession")
    public String getSession(
            @SessionAttribute(value = "userInfo", required = false) String userInfo) {

        return userInfo;

    }	
    
}

🔎Spring MVC—返回数据


@ResponseBody


  • 未添加@ResponseBody, 返回页面
  • 添加@ResponseBody, 返回数据

返回页面🍭

(未添加@ResponseBody)

@RequestMapping("/resp")
@Controller
public class RespController {

    @RequestMapping("/page")
    public String retPage() {
        return "/hello.html";
    }

}

在这里插入图片描述
在这里插入图片描述

返回数据🍭

(添加@ResponseBody)

@RequestMapping("/resp")
@Controller
@ResponseBody
public class RespController {

    @RequestMapping("/page")
    public String retPage() {
        return "/hello.html";
    }

}

在这里插入图片描述

返回 JSON 对象


返回 对象(Object) / HashMap 都是 JSON 格式

JSON 格式是键值对结构, 对象(Object) / HashMap 也是键值对结构

以 HashMap 为例🌰

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/response")
    public HashMap<String, String> respJson() {
        HashMap<String, String> map = new HashMap<>();
        map.put("Tom", "Tom_Val");
        map.put("Homo", "Homo_Val");
        map.put("Jack", "Jack_Val");
        return map;
    }
    
}    

抓包查看结果

在这里插入图片描述

请求转发与请求重定向


  • 请求转发 → forward
  • 请求重定向 → redirect

请求转发

// 请求转发
@RequestMapping("/bibubibu-forward")
public String reqForward() {
    return "forward:/hello.html";
}

请求重定向

// 请求重定向
@RequestMapping("/bibubibu-redirect")
public String reqRedirect() {
    return "redirect:/hello.html";
}

在这里插入图片描述

理解 forward(请求转发) 与 redirect(请求重定向)


举个栗子🌰

滑稽老哥对他女朋友说想吃羊肉串

女朋友帮他买羊肉串(请求转发)
滑稽老哥自己去买羊肉串(请求重定向)

具体区别🍭

  1. 请求转发 → 由服务器端负责转发, 请求重定向 → 将请求重定位到资源
  2. 请求转发 → 地址不会发生改变, 请求重定向 → 地址会发生改变
  3. 请求转发 → 服务器端负责转发, 地址不发生改变(可能造成原外部资源不能访问)
    请求重定向 → 地址发生改变, 等同于直接访问新地址(原外部资源能够访问)

类似于滑稽老哥自己去买羊肉串他就能买到口感最好的羊肉串(自己平时光顾较多的烧烤店) → 原外部资源能够访问
而委托女朋友去买虽然告诉了具体的地址仍然有可能买错 → 原外部资源不能访问

🔎总结


  • Spring MVC—连接🍂
    • @RestController@Controller + @ResponseBody
    • @RequestMapping默认支持多种 HTTP 请求(GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…)
    • @RequestMapping指定请求类型 → @RequestMapping(value = "", method = RequestMethod.指定请求的类型)
    • @RequestMapping指定请求类型 == 指定请求类型Mapping
      (例如@RequestMapping(value = "", method = RequestMethod.GET) == @GETMapping(value = ""))
  • Spring MVC—获取参数🍂
    • 获取参数时 URL 中的 key 必须与所传参数一致
    • 建议传参的类型为包装类型, 而非基础类型
    • 参数重命名 → @RequestParam
    • 传递对象 → 当所需获取的参数较多时, 可通过传递对象的方式进行传参(URL 中的 key 必须与所传对象的属性一致)
    • 传递 JSON 对象 → @RequestBody
    • 获取 URL 中的参数 → @PathVariable
    • 上传文件 → @RequestPart
    • 获取 Cookie
      • 传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)
      • 利用注解获取 Cookie—通过@CookieValue获取(获取指定 Cookie)
    • 获取 header
      • 传统方式获取 header—通过 Servlet 获取
      • 利用注解获取 Cookie—通过@RequestHeader获取
    • Session 的存储与获取
      • 存储 Session—通过 Servlet 存储 Session
      • 获取 Session—通过 Servlet 获取 Session
      • 获取 Session—通过 @SessionAttribute 获取
  • Spring MVC—返回数据
    • @ResponseBody → 未添加@ResponseBody, 返回页面 / 添加@ResponseBody, 返回数据
    • 请求转发(地址不会发生改变) → forward / 请求重定向(地址会发生改变) → redirect

在这里插入图片描述

🌸🌸🌸完结撒花🌸🌸🌸

  • 40
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 38
    评论
评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值