Spring Web MVC基础第一篇
目录
1.什么是Spring Web MVC?
2.创建Spring Web MVC项目
3.注解使用
3.1@RequestMapping(路由映射)
3.2一般参数传递
3.3@RequestParam(参数重命名)
3.4@RequestBody(传递JSON数据)
3.5@PathVariable(获取URL中参数)
3.6@RequestParam(上传文件)
1.什么是Spring Web MVC?
Spring Web MVC 是 Spring 框架的一个模块,用于构建基于 Java 的 Web 应用程序。它遵循模型 - 视图 - 控制器(MVC)设计模式,将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller),以实现关注点分离,提高代码的可维护性和可扩展性。
1.模型(Model)
是应用程序的主体部分,用来处理程序中数据逻辑的部分
2. 视图(View)
指在应用程序中专门用来与浏览器进行交互,展示数据的资源
3. 控制器(Controller)
可以理解为⼀个分发器,用来决定对于视图发来的请求,需要用哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即用来连接视图和模型
MVC 的工作流程
1. 用户通过界面操作向控制器发送请求。
2. 控制器接收请求后,调用模型的相关方法进行业务处理。
3. 模型处理完业务逻辑后,将数据返回给控制器。
4. 控制器根据返回的数据选择合适的视图,并将数据传递给视图。
5. 视图将数据呈现给用户。
Spring Web MVC是 Web 框架, 那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求, 并给予响应.
咱们学习Spring MVC, 重点也就是学习如何通过浏览器和用户程序进行交互. 主要分以下三个方面:
1. 建立连接:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调用到我们的Spring 程序。
2. 请求: 用户请求的时候会带⼀些参数,在程序中要想办法获取到参数, 所以请求这块主要是获取参数的功能.
3. 响应: 执行了业务逻辑之后,要把程序执行的结果返回给用户, 也就是响应.
2.创建Spring Web MVC项目
3.注解使用
Spring Web MVC的学习,主要就是学习注解
3.1@RequestMapping(路由映射)
@RequestMapping即可以修饰类也可以修饰方法,它是用来注册接口的路由映射的.表示服务收到请求时, 路径为 /sayHi 的请求就会调用 t1 这个方法的代码.
路由映射: 当用户访问⼀个 URL 时, 将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射.
我们通过在浏览器中输入http://127.0.0.1:8080/user1/t1便可访问到
127.0.0.1是换回地址,访问当前主机,8080是tomcat的端口号,tomcat集成在了Spring MVC项目里面
1.@RequestMapping 的URL 路径最前面加不加 / (斜杠)都可以, Spring程序启动时, 会进行判断, 如果前面没有加 / , Spring会拼接上⼀个 /
2.@RequestMapping 的URL路径也可以是多层路径, 最终访问时, 依然是 类路径 + 方法路径
3.@RequestMapping 既支持Get请求, 又支持Post请求. 同理, 也支持其他的请求方式.
@RequestMapping设置请求方式
@RequestMapping(value = "/t1",method ={RequestMethod.GET,RequestMethod.POST} )
public String t1(){
return "hello world";
}
设置几个请求方式就在{}括号里面写几个请求方式
若不设置,则默认所有请求方式都可以
设置一个请求方式可不写{}
除此之外,还可以使用
@GetMapping() @PostMapping()
表示只能使用get请求或post请求
@GetMapping("/t2")
public String t2(){
return "GetMappiing";
}
@PostMapping("/t3")
public String t3(){
return "PostMapping";
}
@GetMapping() @PostMapping()路径名可以相同,但方法名要不同
@GetMapping("/m7")
public String m7(){
return "m7";
}
@PostMapping("/m7")
public String m8(){
return "m8";
}
3.2一般参数传递
传递字符串:
@RequestMapping("t4")
public String t4(String name){
return name;
}
传递整型:
@RequestMapping("/t5")
public Integer t5(Integer age){
return age;
}
当使用包装类型传递参数时:参数为空时,返回结果为空
抓包发现状态码为200,能够正常放回
当不使用包装类传递参数时:当参数为空时
@RequestMapping("/t6")
public int t6(int age){
return age;
}
抓包发现状态码为500
对于包装类型, 如果不传对应参数,Spring 接收到的数据则为null 所以企业开发中,对于参数可能为空的数据,建议使⽤包装类型
传递多个参数:
@RequestMapping("/t1")
public String t1(String name ,Integer age){
return "姓名:"+name+" 年龄:"+age;
}
当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置是不影响后端获取参数的结果.
传递对象:
如果参数比较多时, 方法声明就需要有很多形参. 并且后续每次新增⼀个参数, 也需要修改方法声明. 我们不妨把这些参数封装为⼀个对象.
package com.example.demo2;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/U2")
public class UserInfo {
String name;
Integer age;
String gender;
public UserInfo(String name, Integer age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public UserInfo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "UserInfo{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
@RequestMapping("/t2")
public String t2(UserInfo userInfo){
return "传递对象:"+userInfo.toString();
}
Spring 会根据参数名称自动绑定到对象的各个属性上, 如果某个属性未传递, 则赋值为null(基本类型则赋值为默认初识值, 比如int类型的属性, 会被赋值为0)
传递数组:
@RequestMapping("/t5")
public String t5(String []str){
return Arrays.toString(str);
}
传递集合:
集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使用 @RequestParam 绑定参数关系
默认情况下,请求中参数名相同的多个值,是封装到数组. 如果要封装到集合,要使用@RequestParam 绑定参数关系
@RequestMapping("/t6")
public String t6(@RequestParam List<String> str){
return str.toString();
}
3.3@RequestParam(参数重命名)
在某些特殊的情况下,前端可能为了加密,传递给后端的数据名称五花八门,后端为了见名知意需要在使用时对前端传过来的数据进行重命名
我们就可以使用 @RequestParam 来重命名前后端的参数值
@RequestMapping("/t3")
public String t3(@RequestParam("q") String name){
return name;
}
如果使用前端规定的名字,传递参数是没有问题的
但是如果使用后端重命名的名字传递参数,就会报错
状态码 400 也是一种常见的 HTTP 状态码,它表示客户端发送的请求存在错误,服务器无法理解或处理该请求。
结论:
1. 使用 @RequestParam 进行参数重命名时, 请求参数只能和 @RequestParam 声明的名称⼀致, 才能进行参数绑定和赋值.
2. 使用@RequestParam 进行参数重命名时, 参数就变成了必传参数.
查看@RequestParam的源码,我们可以看到required的默认值为true,这代表@RequestParam进行参数重命名时,参数为必传参数,将required修改为false,参数就为非必传参数
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
当将required设置为false,非必传参数,传递参数为空就不会报错
@RequestMapping("/t4")
public String t4(@RequestParam(value = "q",required = false) String name){
return name;
}
3.4@RequestBody(传递JSON数据)
什么是JSON:
JSON即JavaScript Object Notation,是一种轻量级的数据交换格式,以纯文本形式存储和传输数据,在前后端数据交互等场景广泛应用,以下是详细介绍:
数据结构:
对象:是一个无序的“键 - 值”对集合,以“{ }”包裹,键和值之间用冒号“:”分隔,不同“键 - 值”对之间用逗号“,”分隔,比如`{"name": "Alice", "age": 25}` 。
数组:是值的有序集合,以“[ ]”包裹,值之间用逗号“,”分隔,值可以是字符串、数字、对象、数组等数据类型,例如`["apple", "banana", {"color": "red"}]` 。
语法规则:
键:必须是字符串。
值:可以是双引号包裹的字符串、数值、true、false、null、对象或者数组。
特点:
轻量级:相比一些其他数据交换格式(如XML),JSON数据格式简洁,文件体积小,在网络传输时能减少带宽占用,提高传输效率。
易于阅读和编写:JSON以人类可读的文本形式表示数据,对于开发人员来说,编写和理解都比较容易。
语言无关性:虽然名称中包含JavaScript,但JSON可以被多种编程语言解析和生成,如Java、Python、C#等,这使得它在不同语言编写的系统间进行数据交互时非常方便。
可以使用JSON检查器来判断JSON是否正确:JSON在线解析格式化验证 - JSON.cn
下面是一段JSON代码,可自行阅读,熟悉JSON语法
{
"squadName": "Super hero squad",//字符串
"homeTown": "Metro City",//字符串
"formed": 2016,//数字
"secretBase": "Super tower",//字符串
"active": true,//布尔类型
"members": [{//数组对象嵌套
"name": "Molecule Man",
"age": 29,
"secretIdentity": "Dan Jukes",
"powers": ["Radiation resistance", "Turning tiny", "Radiation
blast"]
}, {
"name": "Madame Uppercut",
"age": 39,
"secretIdentity": "Jane Wilson",
"powers": ["Million tonne punch", "Damage resistance", "Superhuman
reflexes"]
}, {
"name": "Eternal Flame",
"age": 1000000,
"secretIdentity": "Unknown",
"powers": ["Immortality", "Heat Immunity", "Inferno",
"Teleportation", "Interdimensional travel"]
}]
}
JSON的语法:
1. 数据在 键值对(Key/Value) 中
2. 数据由逗号 , 分隔
3. 对象用 {} 表示
4. 数组用 [] 表示
5. 值可以为对象, 也可以为数组, 数组中可以包含多个对象
集合嵌套:需要使用@RequestBody修饰,@RequestBody修饰是传递JSON数据,集合会被封装成数组,所以使用JSON使用[ ]
@RequestMapping("/t7")
public String t7(@RequestBody List<List<String>> list){
return list.toString();
}
在Postman中,传递JSON数据,Body->raw->JSON
对象传递数据:
@RequestMapping("/t8")
public String t8(@RequestBody UserInfo userInfo){
return userInfo.toString();
}
请求方式为JSON
3.5@PathVariable(获取URL中参数)
path variable: 路径变量
和字面表达的意思⼀样, 这个注解主要作用在请求URL路径上的数据绑定
默认传递参数写在URL上,SpringMVC就可以获取到
@PathVariable可以对参数进行重命名,重命名后便不可以使用之前的参数名了
每一个需要使用参数都要使用@PathVariable修饰
@RequestMapping("/t9/{name}/{age}")
public String t9(@PathVariable String name,@PathVariable("age") Integer userAge){
return "name:"+name+" age:"+userAge;
}
3.6@RequestParam(上传文件)
@RequestMapping("/m16")
public String m16(@RequestParam("file11") MultipartFile file) throws IOException {
System.out.println(file.getName());
file.transferTo(new File("D:\\图片\\代码测试图片\\"+file.getOriginalFilename()));
return "文件上传成功";
}