当前位置: 移动技术网 > IT编程>开发语言>Java > 【Spring】SpringMVC 常见面试题

【Spring】SpringMVC 常见面试题

2020年07月23日  | 移动技术网IT编程  | 我要评论
一、SpringMVC 概念1.1 什么是MVCMVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式● Model(模型):处理应用程序数据逻辑的部分● View(视图):处理数据显示的部分● Controller(控制器):处理与用户交互的部分示例流程图如下:1.2 SpringMVC 设计模式1.2.1 改进SpringMVC 将传统的 Model 层再次进行细化,拆分为 Service.

目录

一、SpringMVC 概念

1.1 什么是MVC

1.2 SpringMVC 设计模式

1.2.1 改进

1.2.2 设计模型图

1.2.3 SpringMVC 组件解析

1.2.4 SpringMVC 模型图和流程分析

1.2.5 SpringMVC 有什么优势

1.2.6 SpringMVC 与 Strust2 比较

二、Spring 面试题

2.1 SpringMVC 常用注解

2.2 SpringMVC 如何处理线程并发问题?是否是线程安全的?如何保证性能?

2.3 父子容器

2.3.1 什么是父子容器

2.3.2 父子容器的特点

2.3.3 SpringMVC 中只使用一个容器是否可行?

2.3.4 为什么SpringMVC中要使用父子容器?

2.3.5 SpringMVC 和 Spring 父子容器的扫描配置

2.4 Springmvc 统一异常处理

2.5 SpringMVC 中文乱码的解决方式

2.5.1 Post 请求

2.5.2 Get 请求

2.6 请求带参转发,和页面重定向

2.7 Filter(过滤器) 、Interceptor(拦截器)、Listener(监听器)

2.7.1 三者的区别

2.7.2 Filter 与 Interceptor 的区别

2.7.3 实现方式


一、SpringMVC 概念

1.1 什么是MVC

MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式

● Model(模型):处理应用程序数据逻辑的部分

● View(视图):处理数据显示的部分

● Controller(控制器):处理与用户交互的部分

示例流程图如下:

 

1.2 SpringMVC 设计模式

1.2.1 改进

SpringMVC 将传统的 Model 层再次进行细化,拆分为 Service 层和 Dao层

● Service(业务层):处理业务逻辑代码

● Dao(数据访问层):处理数据库操作

 

1.2.2 设计模型图

可以看到,Spring 是 SpringMVC 的父容器,SpringMVC 为子容器

 

1.2.3 SpringMVC 组件解析

组件 组件名 作用
前端适配器 DispatcherServlet 相当于mvc模式中的c。它是整个流程控制的中心,由它调用其他组件处理用户的请求,相当于组件的控制中枢。它的存在降低了组件之间的耦合性。
处理器映射器 HandlerMapping 负责根据用户请求找到对应的处理器Handler(处理类和方法)。Spring提供了不同的映射器实现不同的映射方式,如:配置文件方式、实现接口方式、注解方式等。
处理器 Handler 即具体业务控制器,当 DispatcherServlet 将用户的请求转发到 Handler, 由 Handler 对具体的用户请求进行处理
处理器适配器 HandlerAdapter 通过 HandlerAdapter 对处理器进行执行,可以通过扩展适配器实现对更多类型的处理器的执行
视图解析器 View Resolver 负责将 Handler 处理的结果生成 View 视图,View Resolver 先根据逻辑视图名解析成物理视图名(即具体的页面地址),再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
视图 View 展现给用户的界面

 

1.2.4 SpringMVC 模型图和流程分析

模型图如下:


流程为:

  • 用户先进行 http 请求,请求被 DispatcherServlet(前端控制器) 拦截
  • DispatcherServlet(前端控制器) 根据实际配置,选择将请求发送到 HandlerMapping(处理器映射器) 或是直接放过(静态资源)
  • HandlerMapping(处理器映射器) HandlerMapping 根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
  • DispatcherServlet 获取到映射器的返回数据,发送给 HandlerAdapter(处理器适配器),让他调用对应的 Handler 处理业务
  • HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名)
  • Handler 处理完将结果 ModelAndView 返回给 HandlerAdapter,HandlerAdapter 将 ModelAndView 返回给 DispatcherServlet
  • DispatcherServlet 将 ModelAndView 发送给 ViewResolver(视图解析器)进行解析
  • ViewResolver 解析后返回具体的 View 给DispatcherServlet
  • DispatcherServlet 对 View 进行渲染(即填充数据到视图中),并响应给用户

 

从上面的流程分析,有几个关键点:

1. 拦截器什么时候生效?

拦截器生效是在HandlerAdapter 找到真正的处理器,即将对 Handler 处理时,先执行拦截器

 

2. HandlerAdapter 有什么作用?

在 HandlerMapping 时就已经找到了请求对应的执行方法,那么为什么还要 HandlerAdapter呢?

这是由于不同的 Handler 对应了不同的处理器,处理器类型分别为:

HandleAdapter实现类  请求处理器类型 介绍
RequestMappingHandlerAdapter  HandlerMethod 每个HandlerMethod对应一个@RequestMapping注解的控制器方法
HttpRequestHandlerAdapter HttpRequestHandler

HttpRequestHandler的例子比如静态资源请求处理器

ResourceHttpRequestHandler,一般通过 ResourceHandlerRegistry 程序化配置进来

ResourceHttpRequestHandler Controller 请求处理器是实现了接口 Controller的某个对象


 

1.2.5 SpringMVC 有什么优势

  • 支持各种视图技术,不仅仅局限于jsp
  • 与 Spring 框架无缝结合,能够使用 IOC、AOP等
  • 支持各种请求的映射策略(RequestMapper)
  • 代码结构更加清晰,利于多人共同开发、功能拓展和维护

 

1.2.6 SpringMVC 与 Strust2 比较

共同点:

● 框架

SpringMVC 和 Strust2 都是基于 MVC 的表现层框架

● 请求处理

SpringMVC 和 Strust2 都是一个核心控制器

● 线程安全

SpringMVC 默认通过单例模式创建 Controller Bean,即并发请求下用的是同一个实例,当没有共享属性时是线程安全的,也不应该在 Controller、Service、Dao 内创建共享属性!

而 Strust2 对每一个请求分配一个新的 action 实例处理,故也是线程安全的

 

区别:

● 入口

SpringMVC 的入口是 Servlet,Strust2 的入口是 Filter。但Filter在容器启动后就初始化,服务停止后销毁,晚于Servlet;Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。

● 拦截机制

SpringMVC 是方法级别的拦截,一个方法对应一个 Request 上下文,所以方法都是独立的,独享 request、response 数据。且每个方法和一个url对应,传递的参数是直接注入到方法中的,是方法独有的。

Strust2 是类级别的拦截。每一次请求都会创建一个 Action,通过 ActionBean 的 setter 和 getter 方法将数据注入到属性中。由于是通过属性接收的,故属性参数是让类中的多个方法共享的。

● 性能

由于 SpringMVC 中使用了单例模式,没有重复创建 Controller Bean 的消耗,而 Strust2 的每个 Action 都需要重新创建对象,即多例模式,故 SpringMVC 的性能略优于 Strust2

● 配置

由于 SpringMVC 与 Spring 的配置是无缝的,基本使用注解就可以完成配置,而 Strust2 需要通过 xml 文件配置 

 

二、Spring 面试题

2.1 SpringMVC 常用注解

● @Controller

包位置:org.springframework.stereotype.Controller

作用:将当前类标记为控制器对象,SpringMVC 使用扫描机制查找应用程序中所有基于注解的控制类,控制类中用 @RequestMapping 标注了不同url对应的方法,分发处理器会扫描并记录url对应的方法处理器。

相关注解: @RequestMapping

 

● @RequestMapping

包位置:org.springframework.web.bind.annotation

作用:将特定url的请求与处理方法绑定

 

● @PathVariable

包位置:org.springframework.web.bind.annotation

作用:获得请求url中的动态参数

示例:

@RequestMapping("/login/{account}/{password}")
@ResponseBody
public String userProfile(@PathVariable String username, @PathVariable String password){
    return "user" + username + " pass = " + password; 
}

 

● @RequestParam

包位置:org.springframework.web.bind.annotation

作用:从请求体中读出对应的数据

示例:

@RequestMapping("/user")
@ResponseBody
public String getUserBlog(@RequestParam("id") int blogId) {
    return "blogId = " + blogId;
}

与 @PathVariable 的区别:

@PathVariable 是通过占位符映射的方式获取参数的,即 http://xxxx.com/login/tom/123456,而 @RequestParam 是将对应请求路径下的请求参数值进行匹配映射

例子:都是做登录请求,区别主要在于请求方式,以及 @RequestMappding 书写方式

  请求 处理
@PathVariable http://xxxx.com/login/tom/123456 @RequestMapping("/login/{account}/{password}")
@ResponseBody
public String userProfile(@PathVariable String username, @PathVariable String password){
    return "user" + username + " pass = " + password; 
}
@PathParam http://xxxx.com/login?account=tom&password=123456 @RequestMapping("/login")
@ResponseBody
public String getUserBlog(@RequestParam("account") String account, @RequestParam("password") String password) {
    return "account= " + account+ " password = " + password;
}

 

● @RequestBody

包位置:org.springframework.web.bind.annotation

作用:将请求体中的 JSON 字符串绑定到相应的 bean 上,也可以绑定到对应的字符串上。要求请求者以 application/json 方式请求

示例:

# 直接转成对象
@requestMapping("/login")
@requestBody
public void login(User user){
    System.out.println(userName+" :"+user);
}

# 获取参数
@requestMapping("/login")
public void login(@requestBody String userName,@requestBody String pwd){
    System.out.println(userName+" :"+ userName;
}

 

● @ResponseBody

包位置:org.springframework.web.bind.annotation

作用:将 Controller 对象返回的方法,通过适当的转换器转换为指定格式后,写入到 response 的 body 区中,长用来返回 JSON 数据或是 XML 数据。使用此注解后不会再走视图解析器

示例:

@RequestMapping("/login")
@ResponseBody
public User login(User user){
    return user;
}
# User字段:userName pwd
# 那么在前台接收到的数据为:'{"userName":"xxx","pwd":"xxx"}'

# 效果等同于如下代码:
@RequestMapping("/login")
public void login(User user, HttpServletResponse response){
    response.getWriter.write(JSONObject.fromObject(user).toString());
}

 

● 其他注解

@RestController:等同于 @Controller + @ResponseBody

@SessionAttribute:声明将什么模型数据存入session

@CookieValue:获取cookie值

@ModelAttribute:将方法返回值存入model中

@HeaderValue:获取请求头中的值

 

2.2 SpringMVC 如何处理线程并发问题?是否是线程安全的?如何保证性能?

2.2.1 无状态对象

无状态的对象即是自身没有状态的对象,它们只是用来执行某些操作的,不会因为多个线程的交替调度而破坏自身状态导致线程安全问题

 

2.2.2 SpringMVC 如何处理线程并发问题?是否是线程安全?

当 SpringMVC 接收到一个请求时,都会新开一个线程去处理。由于 Spring 中多线程环境下共享的对象都是无状态对象,无状态对象无论是单例模式还是多例模式都不存在线程安全问题。

同时,Spring 对 Bean 中非线程安全状态采用的是 ThreadLocal 进行处理,解决了线程安全问题。

 

2.2.3 常见的处理并发问题的机制

常见的解决多线程中相同变量的访问冲突,有两种方式:线程同步机制(锁) 或 ThreadLocal

线程同步机制:同步机制采用了"时间换空间"的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队等待

ThreadLocal: 采用了"空间换时间"的方式,为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。由于每一个线程都拥有了自己的变量副本,就无需锁了。在编写代码时,应该将不安全的变量封装进 ThreadLocal

 

2.2.4 SpringMVC 如何保证性能?

  • SpringMVC 会对每一个请求创建独有的一个线程,保证了处理效率
  • SpringMVC 默认是使用单例模式的无状态对象,省去了对象创建的 GC 的时间,效率略优于 Strust2

 

2.3 父子容器

2.3.1 什么是父子容器

在 Spring 的框架核心中,容器是核心思想,用来管理 Bean 的整个生命周期的。在项目中,容器不一定只有一个,Spring 中可以包括多个容器,且容器之间有上下层关系。最常见的就是 SpringMVC 和 Spring,其中 Spring 为父容器,SpringMVC 为子容器。整个结构可以想象成一棵树,Spring 是主干, SpringMVC 是分支

 

2.3.2 父子容器的特点

  • 父容器和子容器之间是相互隔离的,各自内部可以存在名称相同的 bean
  • 子容器对父容器不可见,父容器对子容器可见(子容器可以访问父容器的 bean,父容器不能访问子容器的 bean)
  • 调用子容器的 getBean 方法获取 bean 的时候,会沿着当前容器开始向上查找,知道找到对应的 bean 为止
  • 子容器可以注入父容器的 bean,而父容器无法注入子容器的 bean

 

2.3.3 SpringMVC 中只使用一个容器是否可行?

可以在 SpringMVC 的配置中管理全部对象,但不能在 Spring 的配置中管理 controller(向上不可见)

 

2.3.4 为什么SpringMVC中要使用父子容器?

SpringMVC 中的父子容器:

在 SpringMVC 中,将 controller 层交给 SpringMVC 容器加载,其他的 service 和 dao 层则是交给 Spring 容器加载。在 controller 层中注入 service 层的 bean

作用:

  • 避免模块混乱:避免在 service 层或 dao 层注入 controller 层的 bean,导致依赖层次混乱
  • 明确各自需求:父子容器的需求不同。在 Sring 容器中需要使用到事务,而 SpringMVC 中就完全用不到。将互不相关的东西隔开,让视图层相关代码和业务层相关代码分离开,也有利于代码维护和容器加载速度
  • 拓展性更强:使用Spring 可以兼容更多的模块,如 mybatis、redis 等

 

2.3.5 SpringMVC 和 Spring 父子容器的扫描配置

先增加 springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--  容器扫描时,只扫描 Controller  -->
    <context:component-scan base-package="xyz.tom">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--   视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--    文件目录    -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!--    文件后缀名    -->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--  告诉前端控制器,哪些静态资源不拦截  -->
    <mvc:resources mapping="/js/**" location="/js/**"></mvc:resources>
    <mvc:resources mapping="/css/**" location="/css/**"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/**"></mvc:resources>

    <!--  开启SpringMvc框架注解的支持  -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

增加 applicationContext.xml 文件,里面为 spring 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--  开启注解扫描  -->
    <context:component-scan base-package="xyz.tom">
        <!--    配置Controller注解不扫描    -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

在 web.xml 文件中添加监听器

ContextLoaderListener 的作用就是在启动 web 容器时,自动装配 ApplicationContext 的配置信息

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Archetype Created Web Application</display-name>

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--  指定加载 springmvc.xml  -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!-- 配置Spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
</web-app>

 

2.4 Springmvc 统一异常处理

SpringMVC 支持通过统一异常处理,实现友好的前后端交互。主要是通过继承 HandlerExceptionResolver 接口。

构建 exception 文件夹,和自定义异常处理类 SysException.java

public class SysException extends Exception{
 
    private String message;
 
    public SysException(String message) {
        this.message = message;
    }
 
    @Override
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}

构建异常处理类 SysExceptionResolver.java

public class SysExceptionResolver implements HandlerExceptionResolver {
 

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
        SysException e = null;
        if (ex instanceof SysException) {
            e = (SysException) ex;
        } else {
            e = new SysException("系统正在维护");
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("errorMsg", e.getMessage());
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

修改 springmvc.xml 文件,配置异常处理器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
 
    <context:component-scan base-package="xyz.tom.www"></context:component-scan>
 
    <!--   视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--    文件目录    -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!--    文件后缀名    -->
        <property name="suffix" value=".jsp"></property>
    </bean>
 
    <!--  告诉前端控制器,哪些静态资源不拦截  -->
    <mvc:resources mapping="/js/**" location="/js/**"></mvc:resources>
    <mvc:resources mapping="/css/**" location="/css/**"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/**"></mvc:resources>
 
    <!--  配置异常处理器  -->
    <bean id="sysExceptionResolver" class="xyz.tom.www.exception.SysExceptionResolver"></bean>
 
    <!--  开启SpringMvc框架注解的支持  -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

 

2.5 SpringMVC 中文乱码的解决方式

2.5.1 Post 请求

通过在 web.xml 中配置过滤器,指定编码格式来解决

<!-- 配置解决中文乱码的过滤器 -->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2.5.2 Get 请求

get请求中文参数出现乱码解决方法有两个:

①修改tomcat配置文件添加编码与工程编码一致,如下:

<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

 ②另外一种方法对参数进行重新编码:

String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。

 

2.6 请求带参转发,和页面重定向

使用 forward 转发请求,使用 redirect 重定向页面

@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    System.out.println("testVoid方法执行了...");
 
    // 请求转发
    req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req, res);
 
    // 重定向,不能跳转 WEB-INF 中的
    res.sendRedirect(req.getContextPath() +"/index.jsp");
 
    // 设置中文乱码
    res.setCharacterEncoding("UTF-8");
    res.setContentType("text/html;charset=UTF-8");
    res.getWriter().print("你好");
    return;
}

 

2.7 Filter(过滤器) 、Interceptor(拦截器)、Listener(监听器)

2.7.1 三者的区别

  Filter Interceptor Listener
实现机制 依赖于 servlet 框架,基于 Java 回调机制实现 依赖于 spring 容器,基于 Java 的反射机制实现 web监听器是Servlet中的特殊的类,用于监听web的特定事件
拦截时间 拦截方法的请求和响应,并对请求和响应做处理 在方法处理之前和方法处理之后进行操作 当监听的对象的方法被调用,或是属性改变时
调用次数 只能在容器初始化时被调用一次 在 controller 中可以多次触发 有变化时触发一次
用途 当有一堆东西,只希望选择出符合的东西 在一个请求进行中的时候,你想干预它的进展,甚至控制是否终止 专门用来监听另一个java对象的方法调用或属性改变,当被监听对象发生变动时,监听器某个方法立即被执行
使用场景 设置字符编码,登录验证、鉴权操作 用于处理页面提交的请求响应并进行处理,例如做国际化,做主题更换,过滤等 统计网站的访问量、统计在线人数和在线用户、特定功能定制
生命周期 随应用启动而启动,随应用消亡而销毁 随应用启动而启动,随应用消亡而销毁 随应用启动而启动,随应用消亡而销毁
启动顺序 监听器 > 过滤器 > 拦截器 > AOP

 

2.7.2 Filter 与 Interceptor 的区别

过滤器和拦截器的作用看起来非常相似,都是对客户端发来的请求进行处理,区别如下:

作用域不同

过滤器依赖于 servlet 容器,只能在 servlet 容器, web 环境下使用

拦截器依赖于 spring 容器,可以在 spring 容器中使用,无论此时 Spring 是什么环境

细粒度不同

过滤器的控制比较粗,只能在请求进来时进行处理,对请求和响应进行包装

拦截器支持更精细的控制,可以在 controller 对请求处理之前或之后被调用,也可以在渲染视图呈现给用户后被调用

中断链执行的难易程度不同

过滤器较为复杂,需要处理请求和响应对象来引发中断,如将用户重定向到错误界面

拦截器只需要在 preHandle 方法内返回 false 进行中断

总结

拦截器相比过滤器有更细粒度的控制,依赖于Spring容器,可以在请求之前或之后启动,过滤器主要依赖于servlet,过滤器能做的,拦截器基本上都能做

 

2.7.3 实现方式

https://blog.csdn.net/qq_34416331/article/details/107532076

本文地址:https://blog.csdn.net/qq_34416331/article/details/107489618

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网