一、什么是Spring MVC
1.Spring Web MVC 是基于 Servlet API构建
2.Spring MVC是一个 Web框架。
1.1 MVC定义
MVC 是Model View Controller 的缩写,是软件工程中的一种软件架构模式,它把软件分为 模型,视图,控制器三个部分
Model(模型):
是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
View(视图):
是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的
Controller(控制器):
是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据,控制⽤户输⼊,并向模型发送数据
MVC执行流程:
1.用户的请求首先给到Controller
2.Controller将请求转发给Model
3.Model处理业务并将结构给到Controller
4.Controller再将数据传给view
5.View转化数据生成最终的页面给用户
1.2 MVC 和 Spring MVC 的关系
MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。总结来说,Spring MVC 是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web框架,当用户在浏览器中输入了Url后,Spring MVC 项目可以感知到用户请求。
1.3 Spring MVC 重要性
大部分Java项目是基于Spring 的,Spring 的核心就是 Spring MVC ,Spring MVC是Spring 框架的核心模块,Spring Boot是Spring的脚手架。
创建Spring Boot项目时,勾选的Spring Web框架就是Spring MVC框架。
Spring MVC 是⼀切Spring 项⽬的基础,我们以后创建的所有Spring、Spring Boot 项⽬基本都是基于 Spring MVC 的。
二、 Spring MVC的功能与操作
1. 连接的功能:将⽤户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring 程序。
2. 获取参数的功能:⽤户访问的时候会带⼀些参数,在程序中要想办法获取到参数。
3. 输出数据的功能:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤户。
对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC
2.1 Spring MVC的创建与连接
Spring MVC的创建:在创建Spring Boot项目的时候,选择 Spring Web框架相当于创建了Spring MVC项目,这里我们就不多说。
Spring MVC的连接:
创建⼀个 UserController 类,实现⽤户到 Spring 程序的互联互通,具体实现代码如下:
@Controller//让spring框架启动时,加载
@ResponseBody//返回非页面数据
@RequestMapping("/user")//路由器规则注册
public class UserController {
//路由器规则注册
@RequestMapping("/hi")
public String sayHi(){
return "<h1>Hi,Spring MVC.</h1>";
}
}
在 Spring MVC 中使⽤ @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作⽤。
接下来浏览器访问地址:http://localhost:8080/user/hi,能打印“hello,spring mvc”信息。
2.2 @RequestMapping 注解介绍
@RequestMapping 是 Spring Web 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的路由映射的。
路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射。
@RequestMapping 基础使⽤:
@RequestMapping 即可修饰类,也可以修饰⽅法,用于将URL请求映射到相应的处理程序方法上。
当@RequestMapping 注解同时修饰类与方法的时候:
它们的URL映射会合并一起形成最终的URL,访问的地址变成 类+方法 localhost:8080/p/index
如果只修饰方法:访问地址 URL 就是 直接方法了。 例如localhost:8080/index
@Controller
@RequestMapping("/p")
//修饰了PersonController类,将该类中所有的方法映射到/p路径下
public class PersonController {
@RequestMapping("/index")
// 注解修饰了 index() 方法,表示该方法映射到/p/index 路径下
public Object index(Person person){
//获取参数
System.out.println(person.getName()+":"+person.getPassword());
//执行业务
return "/index.html";
}
}
2.3 @RequestMapping 的POST 与GET
@RequestMapping 注解默认处理 GET 请求。也就是说,如果你不指定请求方法(method)的话,默认情况下,该注解会处理 HTTP GET 请求。
如果要指定 其他HTTP的请求方法:可以用method 属性指定:
@RequestMapping(value = "/hello", method = RequestMethod.POST)
//表示该方法可以处理 HTTP POST 请求,并且映射到 /hello 路径下。
public String helloPost() {
return "Hello, World!";
}
@RequestMapping 注解外,Spring 还提供了其他的注解来指定不同的 HTTP 请求方法,例如:
- @GetMapping:处理 HTTP GET 请求
- @PostMapping:处理 HTTP POST 请求
- @PutMapping:处理 HTTP PUT 请求
- @DeleteMapping:处理 HTTP DELETE 请求
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
@PostMapping("/hello")
public String helloPost() {
return "Hello, World!";
}
三、获取参数
3.1传递参数
Spring MVC可以直接用方法中的参数来实现传参:
@RequestMapping("/m1")
public Object method(String name){
System.out.println("参数name"+ name);
return "/index.html";
}
表单传递多个参数:
@RequestMapping("/m2")
public Object method_3(String name, String pwd) {
System.out.println("name 参数:" + name);
System.out.println("pwd 参数:" + pwd);
return "/index.html";
}
注:当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果
3.2传递对象
Spring MVC 可以⾃动实现参数对象的赋值,⽐如 Person 对象:
import lombok.Data;
@Data
public class Person{
private int id;
private String name;
private String password;
}
传递对象代码实现:
@RequestMapping("/m3")
public Object method(Person p){
System.out.println("对象中的 name:"+p.getName());
System.out.println("对象中的 password:"+p.getPassword());
return "/index.html";
}
3.3 后端参数重命名(后端参数映射)
假如前端与后端接收的key可以不一致,比如前端传递一个time给后端,后端又有一个createtime 字段来接收,当参数接收不到的时候,可以用@RequestParam 来重命名前后端的参数值。
后端实现代码:
@RequestMapping("/m4")
public Object method(@RequestParam("time") String createtime){
System.out.println("时间"+createtime);
return "/index.html";
}
如果我们前端的参数不是非必传的参数,可以设置@RequestParam 中的 required=false 来避免不传递时报错,具体实现:
@RequestMapping("/m4")
public Object method(@RequestParam(value="time",required=false) String createtime){
System.out.println("时间"+createtime);
return "/index.html";
}
3.4 @RequestBody 接收JSON对象
@RequestMapping(value = "/m5", method = RequestMethod.POST)
public Object method_5(@RequestBody Person person) {
System.out.println("Person:" + person);
return "redirect:/index.html";
}
@RequestMapping 注解指定了请求的 URL 路径为 "/m5",并且请求方法为 POST。这意味着当发送一个 POST 请求到 "/m5" 路径时,该方法会被调用。
@RequestBody 将一个JSON对象 转化为 Java对象,并将其作为方法的参数进行处理。
JSON 是一种轻量级的数据交换格式,以文本形式表示结构化的数据,使用简单的键值对方式组织数据,支持多种数据类型,包括字符串,数字,布尔值,数组与对象,数据为两大结构组成。
1.对象:
{
"name": "John",
"age": 30,
"isStudent": false
}//对由键(key)和值(value)组成
2.数组:
[
"apple",
"banana",
"orange"
]
优点:简洁性,可读性好,支持多种数据结构,易于解析与生成。
3.5 获取URL中参数@PathVariable
后端代码:
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
public String getUserById(@PathVariable("id") int userId) {
// 处理 userId
// ...
return "user";
}
@PathVariable("id") 注解被应用于 userId 参数上,意味着方法 getUserById 期望从请求的 URL 中获取名为 "id" 的路径参数,并将其转换为 int 类型的 userId 参数。
当亲切感求到达,Spring MVC框架解析URL中的路径参数,将其传递相应的方法。userid参数包含URL的id值,可以在方法中进一步处理与使用。
使用 @PathVariable 注解,我们可以方便地从 URL 中提取路径参数,并在控制器方法中使用它们。这样,我们可以根据不同的路径参数值执行不同的逻辑操作。
3.6 上传⽂件@RequestPart
@RequestMapping("/m9")//指定URL路径
public String param9(String name,
@RequestPart("myfile") MultipartFile file) throws IOException {
//上面是方法签名:name为普通字符串参数,接受请求名为name的参数值,
//file 参数使用@RequestPart注解,用于接受请求名为myfile的文件部分。
// 获取上传文件的原始文件名,并提取文件后缀名。
String fileName = file.getOriginalFilename().substring(
file.getOriginalFilename().lastIndexOf("."));
//例如 cat.png 截取到 .png
// 构建⽂件保存路径地址,温江将保存在应用程序的static目录下,
//使用随机生成的UUID作为文件名
String filePath = ClassUtils.getDefaultClassLoader().getResource(
"static").getPath() +"/" + UUID.randomUUID() + fileName;
// 将上传的文件保存到指定的文件路径。
file.transferTo(new File(filePath));
return filePath + " 上传成功.";
//返回上传文件的保存路径,以及一个上传成功的提示信息。
}
简化一点的案例:
@PostMapping("/upload")
public String uploadFile(@RequestPart("file") MultipartFile file) {
// 检查文件是否为空
if (file.isEmpty()) {
return "请选择要上传的文件";
}
try {
// 获取文件名
String fileName = file.getOriginalFilename();
// 获取文件的字节数组
byte[] fileBytes = file.getBytes();
// 在这里可以进行文件处理操作,比如保存到本地、上传到云存储等
return "文件上传成功";
} catch (IOException e) {
e.printStackTrace();
return "文件上传失败";
}
}
获得项目目录的方法:
ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
new ClassPathResource("").getFile().getAbsolutePath();
ClassUtils.getDefaultClassLoader().getResource("").getPath();
ResourceUtils.getFile("classpath:static/").getPath();
//以上的四种方法都可获得项目目录
3.7 获取Cokie/Session/header
获取Request和Respouse 对象
@RequestMapping("/param")
public String param(HttpServletResponse response,HttpServletRequest request){
String name = request.getParameter("name");
// 获取所有 cookie 信息
Cookie[] cookies = request.getCookies();
return name + " 你好.";
}
传统获取 header/cookie
@RequestMapping("/param1")
@ResponseBody
public String param(HttpServletResponse response,HttpServlet request){
String name=request.getParameter("name");
//获取所有的cookie信息
Cookie[] cookies=request.getCookies();
String userAgent=request.getHeader("User-Agent");
return name+":"+userAgent;
}
简洁的获取 Cookie—@CookieValue
@RequestMapping("/cookie")
@ResponseBody
public String cookie(@CookieValue("bite")String bite){
return "cookie"+bite;
}
简洁获取 Header—@RequestHeader
@RequestMapping("/header")
@ResponseBody
public String header(@RequestHeader("User-Agent")String userAgent){
return "userAgent"+userAgent;
}
3.8 Session存储与获取
Session存储和Servlet类似,使用HttpServletRequest 获取
@RequestMapping("/setsess")
@ResponseBody
public String setsess(HttpServletRequest request){
//获取HttpSession对象,参数设置为true,表示如果没有session对象就创建一个session
HttpSession session=request.getSession(true);
if(session!=null){
session.setAttribute("username","java")
}
return "session 存储成功";
}
读取 Session 可以使⽤ HttpServletRequest,如下代码所示:
@RequestMapping("/sess")
@ResponseBody
public String sess(HttpServletRequest request){
//如果session不存在,不会自动创建
HttpSession session=request.getSession(false);
String username="暂无";
if(session!=null&&session.getAttribute("username")!=null){
username=(String)session.getAttribute("username");
}
return "username"+username;
}
获取 Session 更简洁的⽅式
@RequestMapping("/sess2")
@ResponseBody
public String sess2(@SessionAttribute(value="username",required=false)
String username){
return "username:"+username;
}
3.9 获取Header:
@RequestMapping("/header")
@ResponseBody
public String header(@RequestHeader("User-Agent")String userAgent){
return "userAgent"+userAgent;
}