目录
1.什么是 Spring MVC?
2.创建一个SpringMVC项目
3.MVC定义
4.MVC和SpringMVC的关系
5.如何学SpringMVC
6.SpringMVC注解介绍
1.@RequestMapping
2.@ResponseBody
3.@RestController = @Controller + @ResponseBody
4.更换五大注解
5.@RequestMapping 是 post 还是 get 请求?
6.@GetMapping(设置请求方法)
7.获取参数
7.1通过对象获取参数
7.2参数重命名@RequestParam
7.3指定接受数据格式
7.3.1@RequestBody将接收到的json数据格式转化为字符串
7.3.2@PathVariable 从url中拿数据(参数必传)
1.创建一个SpringBoot项目
2.删除不必要的文件
3.添加所需要的依赖
MVC是一种思想,SpringMVC是对MVC思想的一种具体实现
就等于DI是IoC的一种具体实现一样
总的来说:SpringMVC是一个实现了MVC模式,并继承了ServletAPI的Web框架,当用户在浏览器输入url后,SpringMVC就可以感知到用户的请求
SpringMVC是一切项目的基础
简单来说我们只需要掌握三个功能
RequestMapping是用来实现url映射的也就是浏览器连接程序的作⽤。
@RequestMapping既可以用来修饰类也可以用来修饰方法,用户访问的url地址就是类+方法
@RequestMapping还需要和五大注解一起使用,将这个类交给spring去管理,这样项目启动的时候,才会被扫描到
结果如下:
由上面的结果截图可以看到,我们返回的是一个html页面数据,这就是以前的MVC,它返回的是一个视图,但现在的项目都是前后端分离项目,所以我们返回的都是数据
使用ResponseBody注解来告诉前端我们返回的是数据而不是视图
那么现在我们直接返回数据会发生什么呢?
结果如下:
可以看到,index.html并不会以页面的形式返回,而是直接显示了文件名
当然现在我们有一个更方便的注解
上面的程序可以简化
但是用这个注解之后,当前类所有方法的返回对象都是数据而不能是视图
上面我们使用的注解是@Controller,那么我们换成其他的是否还能正常运行出来呢?
我们来试一下@Component
可以看到url访问不了了,如果我们将五大注解都试一遍的话就会发现只有@Controller能访问得了
那么这是什么原因呢?
因为在MVC项目中,url只能通过@Controller来设置
使用postman去测试
我们可以发现,@RequestMapping可以接受get,post以及其他的所有请求,那么如果我们只想让他支持get或post请求呢?
我们可以在@RequestMapping后面添加支持的方法
也可以直接在方法上面加上注解@GetMapping
这样post方法就访问不到了
之前servlet项目获取参数的方式就是通过request.getParameter来获取参数值
可以看到通过这样的方式还是可以拿到数据 ,说明在每个方法中都内置了request,response两个参数,那么有没有更简单的方式呢?
其实,在springMVC项目中,我们直接去拿参数也是可以的,就像这样
可以看到同样是获取成功了,但是这么写有一个 默认规定就是参数名要与url中的一致,不一致就拿不到了
那么这样可以拿多个参数吗?
我们来测试一下
可以看到同样是成功获取到了 ,并且他还将我们的类型转换成功了
如果我们传参错误,那么就会报错了
我们刚才使用的是int的包装类Integer,如果我们使用int修饰参数会发生什么呢?
我们来测试一下
可以看到如果不传参,就会报错,并且和之前r的报错信息不一样(Integer不传参输出就是空,不会报错),status=500表示是服务器内部的错误 ,这是为什么呢?因为int基本数据类型不能为空,所以在项目开发中,我们通常使用包装类Integer
我们发现当前这样写,有一个比较严重的问题,代码耦合性太高了,如果参数非常多的话,我们难道还要一个一个写吗?
解决办法就是将他包装成一个对象
此时我们重新使用对象获取参数
可以看到使用对象成功获取到了参数,url传递的参数和对象内的属性对应,如果有一个属性没有传递参数,那么就为null,这就是使用包装类的好处,不会报错,
如果我们多传了参数,传递了对象中没有的属性,那么也不会报错,只是不会显示出来罢了
此时我们如果需要加参数,那么我们只需要在对象中添加属性就可以了,这样是不是方便了许多呢 ,比如添加一个参数昵称nickname
此时只需要在Student类中添加一个属性nickname
我们再去访问:
可以看到添加成功了
并且通过对象传递参数还有另外一种好处,就是不论前端是通过哪种方式传递的(form表单,浏览器,或者ajax等方式),后端都能接收到,所以我们不必关心前端是如何传递参数的,只要能传过来就好了
我们可以使用postman测试一下前端传递参数能否成功
可以看到同样是成功传递了
我们刚才提到,使用对象传递参数的一大前提就是对象的属性必须和前端传递的参数名一致,这样才可以成功接收,但是如果我不想用前端传递过来的参数名称呢?有没有什么别的方法?
使用@RequestParam("username") String name 此时就可以将前端username传递过来的参数值赋值给name了
后端也是成功拿到了数据并返回了 ,此时若是前端使用name传递数据的话,就会报错了
我们查看日志发现,username是必传参数
我们去看看@RequestParam的源码
查看@RequestParam的源码发现,他默认就是必传参数,此时我们只需要将required改为false将其修改为非必传参数即可
我们在重新访问
此时就不会报错了,因为username不是必传参数了,但是后端还是拿不到数据,因为name已经重命名前端只能通过username传递了
此时如果我们使用json传递数据那么返回的是什么呢?
可以看到返回的数据为空,这是为什么呢?
我们使用fiddler抓包去查看
好像后端并没有解析出来我们使用json传递的数据
所以我们需要使用一个注解,@RequestBody将接收到的json数据格式转化为字符串
使用postman测试:
发现spring成功将json数据接收并转化为字符串格式并且转化成对象返回
那么使用@RequestBody注解后还能接受字符串传参吗?
使用postman测试:
我们发现报错了,所以使用@RequestBody后就只能接受json格式的数据了
那么如果我们想接受url中传递的数据呢?
使用postman进行测试:
可以看到后端也是成功拿到了数据并返回
也可以对其进行重命名
可以看到同样是成功获取到了数据