详解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;
}

响应:

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

相关推荐
天天扭码9 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶10 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺14 分钟前
Spring Boot框架Starter组件整理
java·spring boot·后端
小曲程序21 分钟前
vue3 封装request请求
java·前端·typescript·vue
陈王卜39 分钟前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、39 分钟前
Spring Boot 注解
java·spring boot
java亮小白199744 分钟前
Spring循环依赖如何解决的?
java·后端·spring
飞滕人生TYF1 小时前
java Queue 详解
java·队列
武子康1 小时前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康1 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql