当前位置:   article > 正文

SpringMVC必知必会_springmvc底层原理

springmvc底层原理

SpringMVC是spring内置的一个MVC框架,支持RESTful风格的URL请求。

1、springmvc原理

SpringMVC底层就是Servlet,SpringMVC就是对Servlet进行深层次的封装。

2、springmvc的优势

  1. 基于MVC框架,功能分工明确,解决页面代码和后台代码的分离。
  2. 简单易用,SPringMVC是轻量级的,jar很小。不依赖特定的接口和类就可以开发一个注解的SpringMVC项目
  3. 作为Spring框架的一部分,能够使用springIOC和APO。方便整合MyBatis,Hiberate,JAP等其他框架

3、springMVC的工作原理

MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。

  • Model: 模型层 javaBean 负责数据访问和业务处理 dao service pojo
  • View: 视图 JSP技术 负责收集和展示数据
  • Controller: 控制器 servlet技术 中间调度

image.png

springMVC的工作流程
image.png
(1)用户通过浏览器发送请求到前端控制器DispatcherServlet。
(2)前端控制器直接将请求转给处理器映射器HandleMapping。
(3)处理器映射器HandleMapping会根据请求,找到负责处理该请求的处理器,并将其封装为处理器 执行链HandlerExecutionChina后返回给前端控制器DispatcherServlet。
(4)前端控制器DispatcherServlet根据处理器执行链中的处理器,找到能够执行该处理器的处理器适 配器HandlerAdaptor。
(5)处理器适配器HandlerAdaptor调用执行处理器Controller。
(6)处理器Controller将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给 处理器适配器HandlerAdaptor。
(7)处理器适配器直接将结果返回给前端控制器DispatcherServlet。
(8)前端控制器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象。
(9)视图解析器ViewResolver将封装了的视图View对象返回给前端控制器DispatcherServlet.
(10)前端控制器DispatcherServlet调用视图对象,让其自己进行渲染,即进行数据填充,形成响应对 象。 (11)前端控制器响应浏览器。

4、springMVC的注解

  1. @RequestMapping("/hero")

映射请求路径,相当于servlet中的@WebServlet注解,用于Controller层的类和方法体, 访问时是两层路径,类是一级路径,方法是二级路径。

  1. @MapperScan(“package包路径”)

作用:扫描指定包下所有的接口,然后所有接口在编译之后都会生成相应的实现类 位置:是在SpringBoot启动类上面添加,

  1. @RequestBody

表示当前方法,返回的是字符串

  1. @PathVariable

用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数

@Controller  
public class TestController {  
    @RequestMapping(value="/user/{userId}/roles/{roleId}",method = RequestMethod.GET)  
    public String getLogin(@PathVariable("userId") String userId,  
                           @PathVariable("roleId") String roleId){  
        System.out.println("User Id : " + userId);  
        System.out.println("Role Id : " + roleId);  
        return "hello";  
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. @requestParam

@requestParam主要用于在SpringMVC后台控制层获取参数,类似一是request.getParameter("name"),它有三个常用参数:defaultValue = "0", required = false, value = "isApp";defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。

5、springMVC的拦截器

SpringMVC 中的 拦截器( Interceptor)是非常重要的,它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理。

拦截的时间点在“处理器映射器HandlerMapping根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器HandlerAdaptor执行处理器之前”。

在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链 HandlerExecutionChain,并返回给了前端控制器。

自定义拦截器,需要实现 HandlerInterceptor 接口。而该接口中含有三个方法:

  1. preHandle(request,response, Object handler): 该方法在处理器方法执行之前执行。其返回值为boolean,若为true,则紧接着会执行处理器方法,且会将afterCompletion()方法放入到一个专门的方法栈中等待执行。
  2. postHandle(request,response, Object handler,modelAndView): 该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处 理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
  3. afterCompletion(request,response, Object handler, Exception ex): 当 preHandle()方法返回true时,会将该方法放到专门的方法栈中,等到对请求进行响应的所工作完 成之后才执行该方法。即该方法是在前端控制器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView再操作也对响应无济于事。

afterCompletion最后执行的方法,清除资源,例如在Controller方法中加入数据

自定义拦截器

/**
* ClassName: MyInterceptor
* 自定义拦截器
* @author wanglina
* @version 1.0
*/
public class MyInterceptor implements HandlerInterceptor {
    //执行时间: 控制器方法执行之前,在ModelAndView返回之前
    //使用场景: 登录验证
    // 返回值 true : 继续执行控制器方法 表示放行 false: 不会继续执行控制器方法,表示拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse
                             response, Object handler) throws Exception {
        System.out.println("preHandle-------------------");
        return true;
    }
    //执行时间: 控制器方法执行之hou后,在ModelAndView返回之前,有机会修改返回值
    //使用场景: 日记记录,记录登录的ip,时间
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse
                           response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle-------------------");
    }
    //执行时间: 控制器方法执行之后,在ModelAndView返回之后,没有机会修改返回值
    //使用场景: 全局资源的一些操作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse
                                response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion-------------------");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
/**
* ClassName: MyInterceptor
* 自定义拦截器
* @author wanglina
* @version 1.0
*/
public class MyInterceptor2 implements HandlerInterceptor {
    //执行时间: 控制器方法执行之前,在ModelAndView返回之前
    //使用场景: 登录验证
    // 返回值 true : 继续执行控制器方法 表示放行 false: 不会继续执行控制器方法,表示拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse
                             response, Object handler) throws Exception {
        System.out.println("preHandle2-------------------");
        return true;
    }
    //执行时间: 控制器方法执行之hou后,在ModelAndView返回之前,有机会修改返回值
    //使用场景: 日记记录,记录登录的ip,时间
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse
                           response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle-2------------------");
    }
    //执行时间: 控制器方法执行之后,在ModelAndView返回之后,没有机会修改返回值
    //使用场景: 全局资源的一些操作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse
                                response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion2-------------------");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在springmvc.xml中添加如下配置

<!-- 配置拦截器 -->
<mvc:interceptors>
  <!-- 这里可以同时配置多个拦截器,配置的顺序就是拦截器的拦截顺序 -->
  <mvc:interceptor>
    <!-- 拦截器要拦截的请求路径 拦截所有用/** -->
    <mvc:mapping path="/**"/>
    <!-- 指定干活的拦截器 -->
    <bean class="com.kkb.interceptor.MyInterceptor2"
          id="myInterceptor"></bean>
  </mvc:interceptor>
  <mvc:interceptor>
    <!-- 拦截器要拦截的请求路径 拦截所有用/** -->
    <mvc:mapping path="/**"/>
    <!-- 指定干活的拦截器 -->
    <bean class="com.kkb.interceptor.MyInterceptor2"
          id="myInterceptor2"></bean>
  </mvc:interceptor>
</mvc:interceptors>
如果有多个拦截器的时候:
preHandle:按照配置前后顺序执行
postHandle:按照配置前后逆序执行
afterCompletion:按照配置前后逆序执行

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

面试题

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/67739
推荐阅读
相关标签
  

闽ICP备14008679号