详解Java之Spring MVC篇一

目录

[Spring MVC](#Spring MVC)

官方介绍

MVC

RequestMapping

传递参数

无参数

单个参数

针对String类型

针对Integer类型

针对int类型

针对自定义类型

多个参数

参数重命名

参数强制一致

参数不强制一致

传递数组

​编辑传递List

​编辑

传递JSON

​编辑

从路径中获取参数

获取单个参数

获取多个参数

​编辑

上传文件


Spring MVC

官方介绍

翻译:

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称"Spring Web MVC"来⾃其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC"。

MVC

MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分

为模型、视图和控制器三个基本部分。

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

MVC和Spring MVC的区别

MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。

总结来说,Spring MVC 是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web 框架,那么当⽤户在浏览器中输⼊了 url 之后,我们的 Spring MVC 项⽬就可以感知到⽤户的请求。

RequestMapping

@RequestMapping 是 Spring Web 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的路

由映射的。

路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射。
@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + ⽅法。

@RequestMapping是处理get请求还是处理post请求的?

java 复制代码
@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/hello")
    public String say(){
        return "hello, Spring mvc";
    }
}

使用get请求

使用post请求

我们发现, @RequestMapping既能处理get请求也能处理post请求。

传递参数
无参数
java 复制代码
@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/hello")
    public String say(){
        return "hello, Spring mvc";
    }
}

结果:

单个参数
针对String类型
java 复制代码
@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/r1")
    public String r1(String name){
        return "接收到参数,name:"+name;
    }
}

正确传参的结果:

不传递参数的结果(结果为null):

传递错误参数的结果(结果为null):

由此我们知道,传递单个参数时,参数名必须保持一致!!!

针对Integer类型
java 复制代码
@RequestMapping("/r2")
public String r2(Integer age){
   return "接收到参数,age:"+age;
}

正确传参的结果:

错误传参的结果(结果为null):

不传参的结果(结果为null):

由此我们知道,对于Integer类型的参数,当不传参数时,默认值为null,如果传参名字不一致,值也是默认值null。

针对int类型
java 复制代码
@RequestMapping("/r3")
public String r2(int age){
    return "接收到参数,age:"+age;
}

正确传参的结果:

错误传参的结果(错误码500) :

不传参的结果(错误码500):

由此我们知道,对于int类型的参数, 如果传参的参数名不一致时,会报错且错误码为500;如果不传参,也会报错且错误码为500,这一点与int的包装类型Integer不一样!!!

针对自定义类型
java 复制代码
@RequestMapping("/r5")
public String r5(Student student){
    return "接收到参数,student:"+student;
}

正确传参的结果:

部分传参的结果:

错误传参的结果:

由此我们知道,针对自定义类型,如果不传参也不会报错,包装类型参数的默认值为null,如果传参类型不匹配会报错!!!

多个参数
java 复制代码
@RequestMapping("/r4")
public String r4(String name,Integer age){
    return "接收到参数,name:"+name+",age:"+age;
}
参数重命名
参数强制一致
java 复制代码
@RequestMapping("/r6")
public String r6(@RequestParam("name") String userName){
    return "接收到参数,name:"+userName;
}

正确传参的结果:

不传参的结果(错误码400):

错误传参的结果(错误码400):

由此我们知道,当参数重命名之后,默认要求该参数必须传参,否则会报错!!!

参数不强制一致
java 复制代码
@RequestMapping("/r7")
public String r7(@RequestParam(value = "name",required = false) String userName){
    return "接收到参数,name:"+userName;
}

正确传参的结果:

错误传参的结果(结果为null):

不传参的结果(结果为null):

由此我们知道,当参数重命名之后,添加required=false之后,该参数就不要求必须传递了.

传递数组
java 复制代码
@RequestMapping("/r8")
public String r8(String[] array){
    return "接收到参数,array:"+ Arrays.toString(array);
}

可以这样传递:

也可以这样传递:

传递List
java 复制代码
@RequestMapping("/r9")
public String r9(List<String> list){
    return "接收到参数,list:"+list;
}

响应:

解决方法

java 复制代码
@RequestMapping("/r9")
public String r9(@RequestParam(required = false) List<String> list){
    return "接收到参数,list:"+list;
}

响应:

由此我们知道,当参数类型时List类型时,必须添加@RequestParam注解,否则会报错且错误码为500。

传递JSON
java 复制代码
@RequestMapping("/r10")
public String r10(@RequestBody Student student){
    return "接收到参数,student:"+student;
}

响应:

通过fiddler抓包:

原因分析:

是因为它把Json字符串当成了一个不可拆分的整体,所以这样拿不到传递的参数。

解决办法:

java 复制代码
@RequestMapping("/r10")
public String r10(@RequestBody Student student){
    return "接收到参数,student:"+student;
}

响应:

由此我们知道,当传递Json字符串时,必须添加@RequestBody注解!!!

从路径中获取参数
获取单个参数
java 复制代码
@RequestMapping("/article/{articleId}")
public String r11(Integer articleId){
    return "接收到参数,article:"+articleId;
}

响应(出错):

解决方法,使用@PathVariable注解。

java 复制代码
@RequestMapping("/article/{articleId}")
public String r11(@PathVariable("articleId") Integer articleId){
    return "接收到参数,article:"+articleId;
}

响应:

关于为什么需要加@PathVariable("articleId"),这里有几个关键点:

1.明确性:@PathVariable注解明确指出了哪个URL模板变量应该被绑定到方法的哪个参数上。虽然Spring MVC也可以尝试通过参数名来自动匹配(如果参数名与URL模板中的变量名相同),但使用@PathVariable增加了代码的清晰度和明确性。

2.灵活性:在某些情况下,URL模板中的变量名可能与你想在控制器方法中使用的参数名不同。通过@PathVariable,你可以指定一个不同的参数名,这提供了额外的灵活性。

3.可读性:对于阅读代码的人来说,@PathVariable注解使得URL模板变量到方法参数的绑定一目了然,有助于理解代码的功能和目的。

4.强制类型转换:@PathVariable注解允许你指定参数的类型(如Integer),这意味着Spring MVC会尝试将URL模板变量的值转换为指定的类型。如果没有这个注解,你可能需要手动进行类型转换。

5.必需性:虽然在这个特定示例中@PathVariable可能看起来不是绝对必需的(因为参数名与URL模板变量名相同),但在更复杂的URL模板或更复杂的控制器方法中,使用@PathVariable可以确保你的代码更加健壮和易于维护。

获取多个参数
java 复制代码
@RequestMapping("/article/{articleId}/{name}")
public String r12(@PathVariable("articleId") Integer articleId,@PathVariable("name") Integer name){
    return "接收到参数,article:"+articleId+",name:"+name;
}

响应:

在通过路径获取参数时,如果从路径中获取多个参数,传参时必须每个都传递,否则会报错,因为不知道是哪个/哪些参数没有传递!!!

上传文件
java 复制代码
@RequestMapping("/r13")
public String r13(@RequestPart("file")MultipartFile file){
    String originalFilename=file.getOriginalFilename();
    return "接收到参数,文件名称:"+originalFilename;
}

响应:

在上传文件时,文件不能太大,否则会上传失败!!!

相关推荐
奋进的芋圆12 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin12 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model200512 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉12 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国12 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_9418824813 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈13 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_9913 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹13 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理
专注_每天进步一点点13 小时前
【java开发】写接口文档的札记
java·开发语言