Spring框架二----SpringMVC
1.什么是SpringMVC
●SpringMVC是一个基于Java实现的MVC设计模式轻量级Web框架(表示层框架),通过把Model,view,controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,方便组内开发人员的配合。
■Model:模型层,指工程中的Javabean,作用是处理数据,JavaBean也分为两种。
▼实体类Bean:专门存储业务数据,(Student,User)
▼业务类Bean:指Service或Dao对象,专门用于处理业务逻辑和数据访问。
■View:视图层,指工程中的html和jsp等页面,作用是与用户交互,展示数据
■Controller:控制层,指工程中的servlet,作用是接受请求和响应浏览器
2.SpringMVC和struts2区别
●SpringMVC入口是一个Servlet即前端控制器(DispatcherServlet),而Struts2入口是一个filter过滤器。
●SpringMVC是基于方法开发(一个url对应一个方法),请求参数传到方法的形参(可以实现单例)。而Struts是基于类开发,传递参数是通过类的属性(只能为多例)。
●SpringMVC通过参数解析器将request请求解析,并给方法形参赋值,将数据和视图封装到ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面,而Struts2采用值栈存储请求和响应的数据。
3.SpringMVC流程
●用户发送请求到前端控制器DispatcherServlet
●DispatcherServlet接受请求后,调用处理器映射器(HandlerMapping),获取Handler;
●处理器映射器根据请求url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatherServlet
●DispatcherServlet调用HandlerAdapter处理器适配器,请求执行Handler
●HandlerAdapter经过适配调用具体处理器处理业务逻辑
●Handler执行完成,返回ModelAndView
●HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
●DIspatcherServlet将ModelAndView传给视图解析器进行解析
●视图解析器解析后返回具体的view
●DispatcherServlet对view进行渲染视图(将模型数据填充到视图中)
●DispatcherServlet响应用户
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iS6dZC3K-1650540753443)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/149.png)]
●整个过程使用到的工具
■DispatcherSerlvet(前端控制器):接收请求,响应结果,相当于转发器,可以减少其他组件间的耦合度
■HandlerMapping(处理器映射器):根据请求的URL找到对应的Handler
■HandlerAdapter(处理器适配器):负责执行Handler
■Handler(处理器):我们看法的Controller
■ViewResolver(视图解析器):进行视图的解析,根据视图逻辑名将ModelAndView解析为真正的视图
■View(视图):一个接口,实现类支持不同的视图类型
4.SpringMVC优点
●可以支持多种视图技术,不限于JSP
●与Spring框架集成
●清晰的角色分配
●支持各种请求资源的映射策略
5.SpringMVC重定向和转发
●重定向和转发都是web开发中资源跳转的方式。
●转发:服务器内部的跳转,地址栏不发生变化,只有一个请求响应,可以通过request域传递对象,通过关键字forward:实现
●重定向:浏览器自动发起对跳转目标的请求,地址栏发生变化,相当于两次请求响应,无法通过request域传递对象,通过redirect:关键字实现。
6.SpringMVC常用注解
●@RequestMapping:用于处理请求url映射,可以作用于类或方法上,作用于类上则类中所有响应请求的方法都是以该地址为父地址。
■value属性:一个字符串型数组,表示请求能匹配到的多个地址。
■method属性:表示请求映射的方式
▼RequestMethod.POST:请求参数看不到(在服务器上创建一个新的资源,安全,效率不高)
▼RequestMethod.GET:请求参数直接在地址后面,参数名 = 参数值 and…(请求从服务器获取特定资源,不安全)
●@RequestBody:注解实现接收http请求的json数据,将json数据转化为java对象。
●@ResponseBody:注解实现将Controller方法返回对象转化为json对象返回给用户
●@Controller:这个就是之前说的IOC创建对象的注解,这里提到主要因为这个用于表示控制层对象
●@RestController:相当于@ResponseBody + @Controller,微服务常用。
7.SpringMVC获取请求参数方式(后台获取用户在浏览器中填写的信息)
●在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求时,匹配到请求映射后,DispatcherServlet就会将请求参数赋值给相应形参
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcoNuoD7-1650540753445)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/150.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Hxu5q4z-1650540753445)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/151.png)]
●如果两个参数名字不同,又无法修改时,可以在需要的形参前使用@RequestParam注解,将请求参数和控制器方法的形参创建映射关系,以下为注解属性:
■value:指定为此形参赋值的请求参数的参数名
■required:设置是否必须传输此请求参数(默认true)
■defaultValue:默认值,无论required是否为true,当没有传或者传“”时,会传入这个
●还可以使用POJO获取请求参数:即一对象为控制器的形参,对象的属性名与参数的参数名一致,会自动封装到对象中(私有属性要有setter)
8.SpringMVC请求中文乱码问题
●POST请求中文乱码:在web.xml中配置一个CharacterEncodingFilter过滤器,设置为utf-8(一定配置在其他过滤器之前)
●GET请求中文乱码:修改tomcat配置文件添加编码与工程编码一致。
9.SpringMVC的控制器是不是单例模式,有什么问题,怎么解决
●是单例模式(毕竟就是个bean嘛),在多线程访问的时候存在线程安全问题,解决方案:在控制器里面不能改写可变状态量,如果需要使用这些可变状态,可以使用ThreadLocal机制解决,为每个线程单独生成一份副本,独立操作,用于实现线程间的数据隔离。
10.域对象共享数据(将数据从后台传回浏览器)
●Request域对象共享数据
■使用ModelAndView:Model用来传递数据,view为要跳转到的页面,所以方法直接返回ModelAndView对象即可。(想要获取Request,只需要在形参中声明Request即可,springMVC就会自动装入,session同理)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W8AhTzri-1650540753446)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/152.png)]
■使用Model:返回对象还是原来的String,形参为model
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kgXDEgvW-1650540753447)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/153.png)]
■使用Map:形参为Map<String,Object>,返回对象还为string
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v1cD05h8-1650540753447)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/154.png)]
●Session共享数据:服务器为每个会话创建一个session对象,所以Session中数据可供当前会话中所有servlet共享。用户打开浏览器开始会话,关闭浏览器结束会话,形参为HttpSession(ServletApi)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZzydQimr-1650540753448)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/156.png)]
●application域共享数据:作用于整个服务器生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IkMFUdfX-1650540753449)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/157.png)]
●request:只在一次请求上生效,消息发送给客户端,该对象就被摧毁。一次性产品
●session:用于跟踪客户状态,用户访问某个站点,服务器端就会为其产生一个SessionID,以cookie形式返回给客户端,当客户去访问该站点其他服务时,就会带着sessionID一起发出,一个用户就好比一个session对象,互不干扰
●application:一个服务器就是一个application对象,用户共享一个application,当服务停止时摧毁。
11.视图
●当控制器中所设置的视图名称没有任何前缀(forward,redirect)的时候,此视图名称会被SpringMVC配置文件中所配置的视图解析器解析(ThymeleafView),视图名称拼接视图前缀和视图后缀得到最终路径,通过转发形式实现跳转。
●转发视图:当控制器方法中所设置的视图名称以forward:为前缀时,创建InternalResourceView视图(SpringMVC中的默认转发视图)。此视图不会被SpringMVC配置文件中所配置的视图解析器解析,而是将前缀去掉,剩余部分作为最终路径通过转发方式跳转。
●重定向视图:当控制器方法中所设置的视图名称以redirect:为前缀时,创建redirectView视图(SpringMVC的默认重定向视图),此时视图名称不会被SpringMVC配置的视图解析器解析,而是将前缀去掉,剩余部分作为最终路径跳转。
●视图控制器:当控制器方法仅仅是为了实现页面跳转,即只需要设置视图名称时,可以将处理方法用view-controller标签表示。
12.SpringMVC中函数的返回值是什么
●啊?不是一般都是String或者ModelandView么。
13.HttpMessageConverter
●报文信息转换器,将请求报文转换为java对象,或者将Java对象转换为响应报文(你不能指望网上传输的东西直接就是对象吧)
●@RequestBody:可以获取请求体,将请求体中的数据取出来呗,需要在控制器方法中设置个形参,使用@RequestBody标识,当前请求的请求体就会为当前注解锁标识的形参赋值(String类型,&号连接)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-31U8umzG-1650540753450)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/158.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BpcJm6l8-1650540753451)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/159.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vZCAvAqc-1650540753453)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/160.png)]
●RequestEntity:封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的请求报文就会赋值给形参,可以通过getHeaders获取请求头信息,getBody()获取请求体
●以上两个都是对请求报文进行处理,过来的毕竟是一个请求报文嘛。
●@ResponseBody:表示一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器。(之前就是传到model里,然后返回给view)将JAVA对象直接作为控制器方法的返回值,就会自动转换为JSON格式的字符串
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GjDfcvkt-1650540753453)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/161.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EjRt9CYP-1650540753454)(http://luxiaolumm.gitee.io/luxiao-lu-mm/pic/162.png)]
●ResponseEntity:用于控制器方法的返回值类型,则该控制器方法的返回值就是响应到浏览器的响应报文。
●@RestController,表示在控制器的类上,相当于为类添加了@Controller注解,并且为其中每个方法添加了@ResponseBody注解。
14.SpringMVC拦截器
●SpringMVC中拦截器主要是用于拦截控制器方法的执行,作用于控制器执行前后,实现了HandlerInterceptor接口,有三个抽象方法:
■preHandler:控制器方法执行之前执行这个方法,如果返回为true则正常调用,返回false则拦截
■postHandler:控制器方法执行之后执行
■afterComplation:处理完视图和模型数据,渲染视图完毕之后执行afterComplation()
●如果有多个拦截器则:
■如果每个拦截器的preHandler都返回true,则这些拦截器执行顺序与在SpringMVC的配置文件配置顺序有关,会按照配置的顺序执行,而postHandler和afterComplation会按配置的反序执行。
■如果某个拦截器的prehandler返回false,返回false的prehandler和他之前的prehandler都会执行,posthandler都不执行,返回false的拦截器之前的拦截器的afterComplation会执行。