本篇博客讲解
MVC思想、及Spring MVC(是对MVC思想的一种实现)。
Spring MVC的基本操作、学习了六个注解
@RestController注解
@RequestMappering注解
@RequestParam注解
@RequestBody注解
@PathVariable注解
@RequestPart注解
MVC
View(视图)
指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
Model(模型)
是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
Controller(控制器)
可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型。
CM相当于后端
V相当于前端。如今前后端分离。因此实际上我们已经不学V。虽然叫SpringMVC。
实际上我们学的是Spring Web。
一、什么是SpringMVC
官方解释:
Spring Web MVC是基于Servlet API构建的原始Web框架,从⼀开始就包含在Spring框架中。它的 正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc),但通常被称为Spring MVC。
MVC是⼀种架构设计模式,也⼀种思想,而SpringMVC是对MVC思想的具体实现.除此之外,Spring
MVC还是⼀个Web框架.
总结来说,SpringMVC是⼀个实现了MVC模式的Web框架.
所以,SpringMVC主要关注有两个点:
1. MVC
2. Web框架
Spring MVC全称是Spring Web MVC
在创建SpringBoot项⽬时,我们勾选的Spring Web框架
其实就是Spring MVC框架:
Spring实现了MVC这个思想。因此叫做SpringMVC。
二、在IDEA创建项目方式
和上文Springboot创建方式是一样的
三、学习SpringMVC(基本操作)
既然是Web框架,那么当⽤⼾在浏览器中输⼊了url之后,我们的 SpringMVC项⽬就可以感知到⽤⼾
的请求,并给予响应.
咱们学习SpringMVC,重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互.
主要分以下三个⽅⾯:
3.1 建立+连接(两大注解):
使用@ReQuestMapping注解,设置网址中资源访问的部分。
3.1.1 @RequestMappering作用在类上
作用在类上就是类路径。
3.1.2 @RequestMappering作用在方法上
作用在类上就是方法路径。
如上图,访问时:类路径+方法路径
我们通常会加上类路径的,这样方便我们查找是哪里的问题出错。如果只有方法路径,不好找并且容易冲突。如果加上类路径,那么这个路径通常对应这个类名。因此方便我们找到对应的代码。
端口号是1208
因此它的访问地址就是127.0.0.1:1208/calc/sum
程序写好之后要建立连接
通过@RequestMappering注解和浏览器建立连接。是url的一个映射。通过这个还是不能成功建立连接。因为项目中会有很多文件代码。为了更方便Spring找到建立了连接的方法。
通过
3.1.3 @RestController注解
来告知程序这边代码里建立连接了
将⽤⼾(浏览器)和Java程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring程序。
注解括号中的 / 也可以不写。建议加上。
注:路径是不能重复的,不然会报错。
3.2 使用Postman请求:
用户请求的时候会带⼀些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数的功能.
我们可以通过postman来查看请求方式是get还是post
通过浏览器访问的方式都是get。
Spring既支持get请求方式,又支持post请求方式。
后端请求时:使用postman或者浏览器,前端form表单等方式都可以。对于后端都是一样的。
也可以
使用Fiiddler
来查看请求和响应的数据
传入url,请求时可以设置请求方式、设置cookie 、添加参数
点击Send后我们可以查看响应、查看HTTP请求状态。
在body中,有
none:代表什么都没有
form-data:代表form表单,有两种form表单形式,第一种是普通form表单,第二种可以上传一些图片、文件。
raw:表示请求体中的数据是原始的、未经过编码的数据。传递json数据就可以用到。
指定请求方式 :
在@RequestMapping传入参数method = RequestMethod.GET可以指定请求方式为get,此时就只能通过get来进行请求而不能使用别的方式了。
如果使用别的方式请求,则会报错。405表示请求方式出错。
@RestController public class HelloController { @RequestMapping(value = "/hello",method = RequestMethod.GET) public String hello(){ return "呜呜呜zzx大笨蛋!!!!!!"; } }
注解里双引号的值会赋值给value这个属性。如果对多个属性赋值,需要写上属性的名字。如果只有一个属性且为value,那么属性名字可以省略。如下图就省略了value这个属性名字。
按住ctrl点进去可以查看注解里有什么属性。
@RestController
@RequestMapping
3.2.1 请求单个参数
注:不能使用基本类型。默认值为null。基本类型不支持。Spring范畴
方法名和路径我们可以保持一样也可以保持不一样,最好保持一样方便我们好找。
@RequestMapping("/r1") public String r1(String name){ return "接收到参数 name:"+name; }
定义参数要使用包装类型
@RequestMapping("/r2") //注:传入数字类型不能使用int,因为int为基本数据类型,不能转换为空值 // 其默认值不为null,我们需要将int写变为Integer。包装类型。 public String r2(Integer age){ return "age:"+age; }
我们使用postman来传入参数。
3.2.2 请求多个参数
@RequestMapping("/r3") public String r3(String name,Integer age){ return "name:"+name+"age:"+age; }
3.2.3 传入对象参数
添加有参构造函数时,记得把无参构造函数补上
首先新建一个类,对参数进行包装,利用get,set方法和toStirng方法。来进行构造。
注:这里可以使用基本类型,如int 默认值为0;java范畴。
package org.example.springbootdemo; public class UserInf { private Integer id; private String name; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } 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; } @Override public String toString() { return "UserInf{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
使用刚刚新建的类,来传入类参数,返回一个toString方法。
@RequestMapping("/r4") public String r4(UserInf user){ return user.toString(); }
传参与之前一样。
3.2.4 参数重命名(@RequestParam注解)
@RequestMapping("/r5") //重命名后,才能正常访问到url //必须传入正确的参数?name = age = public String r5(@RequestParam("name") String username,Integer age){ return "username:"+username+",age:"+age; }
我们需要重命名哪个参数就在哪个参数前使用@RequestParam注解。
前端传参时我们使用重命名的参数来传参,在后端操作时我们继续使用原来的名字
注:加上@RequestParam注解重命名后的参数为必传参数。否则会报错400
若发生缓存错误我们进行clean。
从请求中获取name的参数,并赋值给username参数。
后端要用的话只能使用username,而前端那边使用name。
令参数为非必传参数 (required = false)。
在@RequestParam注解的第二个参数传入
@RequestMapping("/r5") //重命名后,才能正常访问到url //必须传入正确的参数?name = age = public String r5(@RequestParam(value = "name",required = false) String username,Integer age){ return "username:"+username+",age:"+age; }
3.2.5 传递数组参数
@RequestMapping("/r6") public String r6(String[] arr){ return Arrays.toString(arr)+"数组长度:"+arr.length; }
它可以是数组,也可以是字符串。
如上图这样传,那么他就是一个数组。
这样传那么就相当于传入字符串
当我们有多个名字一个的参数时,会把他拼接成一个数组
3.2.6 传递集合参数(List<String> list)
集合参数:和数组类似,同一个请求参数名有为多个,但需要@RequestParam来绑定参数关系
如果我们这样写会发生500错误,服务器端错误,在传入集合类时,我们需要用到
@RequestMapping("/r7") public String r7(List<String> list){ return list.toString(); }
@RequestParam注解来绑定list这个参数才可以。
默认情况下,请求中参数名相同的多个值是封装到数组,如果要封装到集合,需要使用@RequestParam来绑定参数关系。
注:加上@RequestParam注解的参数为必传参数,如果我们不想传参就可以令@RequestParam注解第二个参数为required = false。
@RequestMapping("/r7") public String r7(@RequestParam(value = "list",required = false) List<String> list){ return list.toString(); }
如果定义集合为非必传,如果没有传入,此时如果运行,我们会发现会报一个500的错误,是因为此时list发生空指针异常。我们需要额外添加代码。
@RequestMapping("/r7") public String r7(@RequestParam(value = "list",required = false) List<String> list){ if(list != null){ return list.toString()+"size:"+list.size(); } return "list为空"; }
3.2.7 传递json(@RequestBody注解)
Json(JavaScript Object Notation)【JavaScript对象表示法】
Json和JavaScript没有关系,只是语法相似。
简单来说:json就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON的本质是字符串,主要负责在不同语言中数据传递和交换。
Json的两种结构:
1.对象用{}表示
2.数组用[]表示
@RequestMapping("/r8") public String r8(@RequestBody UserInf userInf){ return userInf.toString(); }
将{}中的参数转成了userinfo。传给了服务器。
区别是之前写的参数都是key,value的形式。
使用json传的是一个json字符串。也可以传入一个压缩的形式:
{"name":"张三","age":18,"id":120}
在企业开发中,用的最多的就是json和对象的方式,因为这两个扩展性很好。可以很好的增减参数。
注意:在body中raw中传入json数据时,如果params中还有参数存在,可以会影响json数据的传入。
用的最多的就是使用对象,和json的方式
3.2.8 获取url中的参数 (@PathVariable注解)
path variable:路径变量
必传参数,虽然可以修改required = false 我们尽量不去修改。
和字⾯表达的意思⼀样,这个注解主要作用在请求URL路径上的数据绑定
@RequestMapping("/r9/{articleId}") public String r9(@PathVariable Integer articleId){ return "articleId:"+articleId; }
对参数重命名
@RequestMapping("/r9/{article}") public String r9(@PathVariable("article") Integer articleId){ return "article:"+articleId;
要注意红方框中的数据要保持一致。
3.2.9 上传文件(@RequestPart)
file.getOriginalFilename();返回文件原始名称
注解不加也可以运行成功,建议加上
//虽然注解不加也可以,但是建议加上 @RequestMapping("/r11") public String r11(@RequestPart MultipartFile file) throws IOException { String FileName = file.getOriginalFilename();//获取文件名 file.transferTo(new File("J:/Test/"+FileName));//将此文件传到..目录下 return "获取上传文件"+ file.getOriginalFilename(); }