您现在的位置是:首页 >其他 >SpringMVC网站首页其他
SpringMVC
简介
springMVC和spring boot息息相关。spring boot把mvc引入了。
MVC是什么?
MVC是"Model-View-Controller"的缩写,是一种软件架构模式。它的目的是将应用程序的逻辑和用户界面分离,以便更好地组织和管理代码。MVC是一种思想;而spring MVC是具体实现;是继承servlet API的web框架
1:模型(Model):模型代表应用程序的数据和业务逻辑。它负责处理数据的读取、存储、验证和更新等操作。模型并不关心数据如何被展示或被用户操作,它只专注于数据的管理和处理。
2:视图(View):视图负责展示数据给用户,并处理用户界面的交互。它是用户与应用程序交互的界面,可以是图形界面、网页或其他形式。视图从模型中获取数据来显示,并将用户的操作传递给控制器进行处理。
3:控制器(Controller):控制器接收来自用户界面的输入,并根据用户的操作更新模型和视图。它负责协调模型和视图之间的交互,并根据用户的请求调用适当的模型操作。控制器还可以处理应用程序的逻辑,例如验证输入、处理错误等。
创建Spring MVC项目
就是创建spring boot项目;注意添加spring web依赖
创建连接
加Controller修饰的类是给外部系统使用的类;当在这写个地址(路由的注册);外部通过这个地址就可以访问到这个类。添加@Controller注解的目的是告诉Spring容器该类是一个控制器组件,需要由Spring来管理和处理。这样,Spring就可以根据配置和请求的映射来调度和执行相应的控制器类。依赖于spring容器。
支持什么请求类型:
get肯定能支持;(因为我们输入URl就是get请求)post支不支持;postman试了;确实可以。
如果需求设定只需要支持一种请求?
这个注解有很多属性可以设置
选择后会自动帮你补充value属性;这里使用name和value、path都是一个东西。405是方法不被运行;设置post你get请求就会报405
生产者、消费者
消费者:简单来说只有这种类型的数据我才进行接收请求
consumes属性:用于指定处理器方法可以接受的请求的媒体类型(Media Type)或内容类型。它限制了客户端请求的Content-Type必须与指定的媒体类型匹配才会触发该处理器方法。例如,consumes = "application/json"表示处理器方法仅接受Content-Type为"application/json"的请求。
生产者:使用后;返回的指定类型的数据。
produces属性:用于指定处理器方法产生的响应的媒体类型或内容类型。它限制了处理器方法返回的响应的Content-Type必须与指定的媒体类型匹配。例如,produces = “application/json"表示处理器方法返回的响应的Content-Type将被设置为"application/json”。
更简单限制请求类型:用相应注解
读取参数
前端传过来的参数可能千奇百怪;什么样类型都有;那么要怎么获取呢?
1:获取单个参数;地址栏的query string。
Integer和int现在
哪怕你只有一个参数;这个也不能乱写;因为对应不上就获取不到。假设地址栏key是name1;拿不到的时候;或者不给传参数;都是string的默认值null。如果是int类型不传参就报错(状态码500);int你必须得赋值;没有默认值的。所以我们在接收参数推荐使用Integer;至少程序在没参数不报错;我可以加个if(?==null)进行另外逻辑。
2:获取多个参数;也是一样的;参数后面继续写就好了;顺序无关紧要;要key对应上就好了
3:传递对象怎么获取
之前怎么接收;现在就怎么接收。就创建对象类型;里面的属性名得和传过来的对象属性名一样。我们的参数就放这个类型。
如果是get传参使用对象接收;key对应也是能赋值到;我明明传的多个参数;怎么就变成对象了。spring mvc帮你的参数映射进行复制的;你只需要属性名保持一致就好了。 它会有方法判断你参数类型、如果是对象就转换成json进行转换;所以你在query string传多个属性用对象接收;请求的类型是Content-Type=applicstion/json。
这时候能不能把@RequestBody去掉?
上述问题;如果前端的规定是用name;但是后端要求要用username;么处理呢:
使用@RequestParam注解;对象是重命名不了;只能把username拆成多个属性重命名。但是使用这个注解后就必须要传递参数了;看它下面的required方法是true(就是你使用这个方法username是必传的;如果你这个属性是可传可不传;你在后面加个require=false即可)现在就只认username;
4:怎么获取json对象
对象和json对象这是两个东西;上述对象的接收方法是获取不到的;postman模拟一下;确实是获取不到
要拿json必须加requestBody注解;这个注解把前端json字符串给搞到对象里。
postman这里模拟id是int类型不用加双引号也行;string就必须加双引号
5:获取URL中参数@PathVariable(这个是URL的部分)
path(url)=/usser/12345和/user?uid=12345区别
1:搜索引擎在抓取关键字时;url的权重更高
2:url更简洁
这个花括号里获取:这时候没有key值;加花括号;在层路径下输入什么都可以;按URL目录层级获取顺序。
下面使用@PathVariable注解;参数名字对应上花括号里的就行;也能进行一个重命名
使用这个注解有个required属性;默认是true;如果名字对应不上;或者是没有参数;直接报错;因为这样子设置是必须给这个name传参数的;可以设置为required=false。上述就是进行一个重命名;
总结:
6:上传文件
MultipartFile类型接收;接收类型必须是这个类型;其它类型还接收不了。因为这个类型有一个方法;可以让我们把上传的文件流保存成一个图片。这个方法没有返回值。抓包会发现传过来的还是字节流;使用这个方法;相当于把这些字节流写到我们创建的文件里;按照它传递的方式进行写回去。
@RequestPart注解:
得加@RequestPart注解;可以进行一个重命名操作;传文件还是一个以key-value方式
@RequestPart注解用于将multipart/form-data类型的请求中的部分(即文件或表单字段)绑定到处理器方法的参数上。
虽然挺好玩的;但是上述的写法还是漏洞不少;
1:文件超过1MB就被限制;
2:多个用户进行上传;会把前面的覆盖掉
改造一下代码:
使用uuid命名;全球唯一id;电脑的mac地址(网卡的地址);时间戳;随机数;随机种子;里面也有算法同一时间访问也让你得到的uuid是不一样的。
上传的文件可能是jpg、png……可以使用获取后缀;从.开始获取后面字符
7:获取Cookie/Session/header
使用注解CookieValue即可;也是默认必须传参的
没传任何的cookie就什么都不显示
开发者工具伪造cookie:
传统的方法拿的是所有的cookie;要拿一个还是比较不容易;这个就能直接拿到相应的。具体需求看使用哪种方式。
8:获取Header
使用注解:@RequestHeader;名字对应上就能获取到。
查看有哪些Header内容
9:获取session
获取session的前提是你存了才能取到;存的方式还是之前的存法;但是取的方式有所不同。
存:套娃;键值对里存键值对。
存的方式不能使用初始化方法里传request参数:@PostConstruct 注解的方法在 Bean 实例化后,属性注入完成后调用,但在这个阶段,HttpServletRequest 对象还不可用,因为它需要在请求到达时才能被创建。通过 RequestContextHolder.currentRequestAttributes() 方法也能获取;但是避免在bean生命周期依赖HttpServletRequest这样做;解耦性差。
取:
执行:先在浏览器执行这个set存一下;再get获取。
spring MVC是基于servlet;所以servlet的写法在这里也是能使用的。我们就可以用servlet的方法去接收也行。我们可以直接在这些方法的参数获取这两个对象;这两个是送的;直接获取就行了。
返回数据
三类返回数据类型:
1.静态页面;如果单单是一个注解controller;默认返回静态页面。
注意:/index.html和index.html区别
加了斜杠;表示从根路径去找这个路径(http://localhost:8080/index.html)。不加/是在hi下找的(http://localhost:8080/hi/index/index.html);找得到吗;因为我们静态页面放在根目录下的。
如果是凑巧;static也有hi/index目录下方index.html这时候不加斜杠也能访问到
2.返回JSON数据
使用注解ResponseBody;这个注解;会根据你的返回结果是什么来判断是返回页面;还是返回json 等类型。
3:返回链接
注意:要实现这两种功能不能有@ResponseBody 注解;请求重定向或请求转发的情况下,需要进行的是URL的跳转或者将请求转发到其他处理器或视图,而不是直接返回数据给客户端。
实现:
请求转发:当服务器端收到客户端请求;会将请求转发给目标地址;再将目标地址返回的结果转发给客户端。假设:张三找李四借100块;但是李四没钱了;李四就去找王五接100块;最后李四拿着王五给的100块借给张三。(这里内部的过程客户端是感知不到;它只是知道结果)
请求重定向:当服务器端收到客户端请求;会给客户端返回一个临时响应头(记录要重定向的URL地址);客户端收到这个地址后就会再次发送请求到这个新的地址。假设:张三找李四借100块;但是李四没钱了;李四说你去王五那借钱。
区别:
1.请求方不同:
请求转发:服务器端帮客户端去请求。再把结果响应给客户端。
重定向:两次客户端请求。
2.数据的共享不同:
转发的数据是共享;因为但是一次请求。
重定向:两次请求;两次响应;数据是不共享的;地址变化了。url不同
3.代码实现不同
注意:请求转发如果资源和转发的页面不在同一个目录下;会导致外部资源不可访问。()
热部署
JVM是用target运行;你修改idea的代码;但是这里还是老的代码;就得重启服务器。热部署就解决我们手动去重启服务器的工作。但是还是很鸡肋的;因为它会等个3-5秒判断你没修改代码就重启;首先有这个时间我已经手动启动完;如果我在代码写到一半在思考;代码没写完它又自动重启;
1:添加依赖
2:进行设置
两个地方要设置两遍