2023/4/26-27复习一下spring mvc
1.什么是SpringMVC
它是基于MVC开发模式的框架,用来优化控制器.它是Spring家族的一员.它也具备IOC和AOP.
什么是MVC?
它是一种开发模式,它是模型视图控制器的简称.所有的web应用都是基于MVC开发.
M:模型层,包含实体类,业务逻辑层,数据访问层
V:视图层,html,javaScript,vue等都是视图层,用来显现数据
C:控制器,它是用来接收客户端的请求,并返回响应到客户端的组件,Servlet就是组件
2.SpringMVC执行的流程 (问的不多)
一天吃透SpringMVC面试八股文_牛客网 (nowcoder.com) 牛客版
Spring MVC的工作原理如下:
- DispatcherServlet 接收用户的请求
- 找到用于处理request的 handler 和 Interceptors,构造成 HandlerExecutionChain 执行链
- 找到 handler 相对应的 HandlerAdapter
- 执行所有注册拦截器的preHandler方法
- 调用 HandlerAdapter 的 handle() 方法处理请求,返回 ModelAndView
- 倒序执行所有注册拦截器的postHandler方法
- 请求视图解析和视图渲染
Spring MVC的主要组件?
- 前端控制器(DispatcherServlet):接收用户请求,给用户返回结果。
- 处理器映射器(HandlerMapping):根据请求的url路径,通过注解或者xml配置,寻找匹配的Handler。
- 处理器适配器(HandlerAdapter):Handler 的适配器,调用 handler 的方法处理请求。
- 处理器(Handler):执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装到ModelAndView对象中。
- 视图解析器(ViewResolver):将逻辑视图名解析成真正的视图View。
- 视图(View):接口类,实现类可支持不同的View类型(JSP、FreeMarker、Excel等)。
一般来说,Controller是Handler,但Handler不一定是Controller。
张阿荣老师版本
好汉: DispatcherServlet 三个帮 : 处理器映射器 处理器适配器 视图解析器
1.向服务器发送HTTP请求,请求被前端控制器 DispatcherServlet 捕获。
2.DispatcherServlet 根据<servlet-name>中的配置对请求的URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用 HandlerMapping 获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回。
(例如 请求url:http://localhost:8080/demo.action 那么得到demo)
因为我不是只需要demo这个字符串,还要创建控制器的对象,因此需要步骤三3
3.DispatcherServlet 根据获得的Handler,选择一个合适的 HandlerAdapter。
4.提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等。
数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。
数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
5.Handler(Controller)执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象。
(String 目标资源的地址)
6.根据返回的ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet。
(目标资源的地址拼接)
7.ViewResolver 结合Model和View,来渲染视图。
8.视图负责将渲染结果返回给客户端
3.@RequestMapping注解详解
此注解就是来映射服务器访问的路径.
1)此注解可加在方法上,是为此方法注册一个可以访问的名称(路径)
@RequestMapping("/demo")
public String demo(){
System.out.println("服务器被访问到了.......");
return "main"; //可以直接跳到/admin/main.jsp页面上
}
2)此注解可以加在类上,相当于是包名(虚拟路径),区分不同类中相同的action的名称
@RequestMapping("/user")
public class DemoAction1 {..}
3)此注解可区分get请求和post请求
@Controller
public class ReqAction {
@RequestMapping(value = "/req",method = RequestMethod.GET)
public String req(){
System.out.println("我是处理get请求的........");
return "main";
}
@RequestMapping(value = "/req" ,method = RequestMethod.POST)
public String req1(){
System.out.println("我是处理post请求的........");
return "main";
}
}
4.五种数据提交方式
1) 单个提交数据
2)对象封装提交数据
在提交请求中,保证请求参数的名称与实体类中成员变量的名称一致,则可以自动创建对象,则可以自动提交数据,自动类型转换,自动封装数据到对象中.
3)动态占位符提交
仅限于超链接或地址拦提交数据.它是一杠一值,一杠一大括号,使用注解@PathVariable来解析.
<a href="${pageContext.request.contextPath}/three/张三/22.action">动态提交</a>
@RequestMapping("/three/{uname}/{age}")
public String three(
@PathVariable("uname") //从路径中取变量
String name,
@PathVariable
int age){
System.out.println(name+":"+age);
return "main";
}
4)映射名称不一致 提交请求参数与action方法的形参的名称不一致,使用注解@RequestParam来解析
5)手工提取数据
5.四种跳转方式 (了解) 以及@ResponseBody注解
注意:@ResponseBody,解析返回的是json串。不是跳转页面。 ( 所以之前返回类型是String 走视图解析器 返回的是jsp页面或者action 不需要加@ResponseBody )
@ResponseBody 将controller的方法返回的对象通过适当的转换器转换为指定的格式之后, 写入到response对象的body区,通常用来返回JSON数据或者是XML数据。 在使用此注解之后不会再走视图处理器, 而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
本质还是两种跳转:请求转发和重定向,衍生出四种是请求转发页面,转发action,重定向页面,重定向action
具体代码看springmvc的 spring_004_jump jumpAction OtherAction转发重定向
对于springboot也是同理 可以参考springboot跳转到指定页面和(重定向,请求转发的写法)_springboot请求转发_健康平安的活着的博客-CSDN博客
资源在WEB-INF目录下(了解)
很多企业会将动态资源放在WEB-INF目录下,这样可以保证资源的安全性。在WEB-INF目录下的动态资源不可以直接访问,必须要通过请求转发的方式进行访问。这样避免了通过地址栏直接对资源的访问。重定向也无法访问动态资源。
-
转发和重定向的本质区别?(掌握)
-
转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。
-
重定向:是浏览器完成的。具体跳转到哪个资源,是浏览器说了算。
-
-
转发和重定向应该如何选择?什么时候使用转发,什么时候使用重定向?
-
如果在上一个Servlet当中向request域当中绑定了数据,希望从下一个Servlet当中把request域里面的数据取出来,使用转发机制。
-
剩下所有的请求均使用重定向。(重定向使用较多。)
-
6.SpringMVC默认的参数类型(了解)
不需要去创建,直接拿来使用即可.
1)HttpServletRequest
2)HttpServletResponse
3)HttpSession
4)Model
5)Map
6)ModelMap
注意:Map,Model,ModelMap和request一样,都使用**请求作用域**进行数据传递.所以服务器端的跳转必须是**请求转发**.
7.拦截器(重点)
7.1拦截器和过滤器的区别
拦截器是mvc的组件 过滤器是servlet规范的一员
针对请求和响应进行的额外的处理.在请求和响应的过程中添加预处理,后处理和最终处理.
- 功能相同:拦截器和 Filter 都能实现相应的功能
- 容器不同:拦截器构建在 Spring MVC 体系中;Filter 构建在 Servlet 容器之上
- 使用便利性不同:拦截器提供了三个方法,分别在不同的时机执行;过滤器仅提供一个方法
7.2拦截器执行的时机
1)preHandle():在请求被处理之前进行操作,预处理
2)postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理
3)afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理.
7.3拦截器实现的两种方式
1)继承HandlerInterceptorAdapter的父类
2)实现HandlerInterceptor接口,实现的接口,推荐使用实现接口的方式
7.4拦截器实现的步骤(springmvc版)
(1)改造登录方法,在session中存储用户信息,用于进行权限验证
(2)开发拦截器的功能.实现HandlerInterceptor接口,重写preHandle()方法
public class LoginInterceptor implements HandlerInterceptor {
//返回值是布尔 意义是true放行 false则拦截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession(false);
if (session!=null && session.getAttribute("user") !=null){
return true;
}else {
//未登录 打回到登陆页面
request.setAttribute("msg","请先登录");
//思考这里 不是访问不了web-inf吗? 但是内部的转发是可以访问的 之前使用控制器访问本质也是转发
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
}
(3)在springmvc.xml文件中注册拦截器
<!-- 注册拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!--映射要拦截的请求-->
<mvc:mapping path="/**"/>
<!--什么不能拦截?-->
<mvc:exclude-mapping path="/showLogin"/>
<mvc:exclude-mapping path="/login"/>
<!-- 拦截器在哪呢 -->
<bean class="com.bjpowernode.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>