Interceptor 拦截器 与 <mvc:annotation-driven />的冲突

本文深入探讨了在Spring MVC中配置拦截器时遇到的问题及解决方案,解释了`<mvc:annotation-driven />`标签在拦截器配置中的关键作用,并通过实例说明了配置不当可能导致的拦截失效及正确配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


最近在学习拦截器,没想到刚开始就碰到难题了。我明明配置好了拦截器,但是丝毫没有起作用,百思不得其解。

这是起初的配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
< context:component-scan  base-package = "sin.cara.controller"  />
     
      < mvc:annotation-driven  />  
 
      < bean
         class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" >
         < property  name = "interceptors" >
             < list >
                 < ref  bean = "myInterceptor" />
             </ list >
         </ property >
     </ bean
 
      < bean  id = "myInterceptor"  class = "sin.cara.interceptors.MyInterceptors" />    
 
     < bean  id = "viewResolver"
         class = "org.springframework.web.servlet.view.InternalResourceViewResolver" >
         < property  name = "prefix"  value = "/WEB-INF/views"  />
         < property  name = "suffix"  value = ".jsp"  />
     </ bean >

这是修改后的配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< context:component-scan  base-package = "sin.cara.controller"  />
 
     
< bean  class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"
    < property  name = "interceptors" > < list > < ref  bean = "myInterceptor"  /> </ list
    </ property
</ bean
< bean  id = "myInterceptor"  class = "sin.cara.interceptors.MyInterceptors"
</ bean
 
  < bean
     class = "org.springframework.web.servlet.view.InternalResourceViewResolver" >
     < property  name = "prefix"  value = "/WEB-INF/views/"  />
     < property  name = "suffix"  value = ".jsp"  />
</ bean >

细心的看官也许发现了不同之处,是的,少了

?
1
< mvc:annotation-driven  />

居然可以成功拦截。

原因是因为

?
1
< mvc:annotation-driven  />

会自动为我们注册DefaultAnnotationHandlerMapping 与AnnotationMethodHandlerAdapter 这两个bean。所以第一种配置无法注入  interceptors属性,就不能指定拦截器。

当使用这种配置时

?
1
2
3
< mvc:interceptors
     < bean  class = "sin.cara.interceptors.MyInterceptors"  /> 
</ mvc:interceptors >

使不使用

?
1
< mvc:annotation-driven  />

都没关系,都会成功拦截。


<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 1. 组件扫描(根据实际包名修改) --> <context:component-scan base-package="cn.edu.uibe.controller"/> <!-- 2. 注解驱动(必须启用) --> <mvc:annotation-driven/> <!-- 3. 静态资源处理(关键修改) --> <mvc:resources mapping="/statics/**" location="/statics/" cache-period="31536000"/> <mvc:resources mapping="/images/**" location="/images/" cache-period="31536000"/> <!-- 4. 兜底静态资源处理(必须添加) --> <mvc:default-servlet-handler/> <!-- 5. 视图解析器(优化配置--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> <!-- 开发阶段建议禁用缓存 --> <property name="cache" value="false"/> </bean> <!-- 6. 文件上传(优化配置--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"/> <!-- 10MB --> <property name="defaultEncoding" value="UTF-8"/> <property name="resolveLazily" value="true"/> </bean> <!-- 7. 拦截器配置(示例,可选) --> <mvc:interceptors> <bean class="cn.edu.uibe.interceptor.AccessInterceptor"/> </mvc:interceptors> <!-- 8. 消息转换器(可选) --> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="defaultCharset" value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </mvc:message-converters> </beans>/这是spring-mvc.xml文件,给出完整的修改后的文件
最新发布
07-11
(一)项目构建 使用 Maven 构建项目,在pom.xml中引入 Spring MVC 相关依赖,如spring - webmvc配置 Servlet、JSP 等相关依赖,确保项目具备 Spring MVC 运行环境 。示例关键依赖配置: <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring - webmvc</artifactId> <version>5.3.18</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet - api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp - api</artifactId> <version>2.3.3</version> <scope>provided</scope> </dependency> <!-- 其他如JSTL等依赖按需添加 --> </dependencies> (二)Spring MVC 配置 DispatcherServlet 配置:在 Web.xml(或 Servlet 3.0 + 环境下用 Java 配置)中配置 DispatcherServlet,指定 Spring MVC 配置文件位置,使其能拦截处理请求 。示例 Web.xml 配置: <servlet> <servlet - name>springmvc</servlet - name> <servlet - class>org.springframework.web.servlet.DispatcherServlet</servlet - class> <init - param> <param - name>contextConfigLocation</param - name> <param - value>classpath:springmvc - servlet.xml</param - value> </init - param> <load - on - startup>1</load - on - startup> </servlet> <servlet - mapping> <servlet - name>springmvc</servlet - name> <url - pattern>/</url - pattern> </servlet - mapping> Spring MVC 配置文件(springmvc - servlet.xml):开启组件扫描(扫描控制器等组件)、视图解析器(配置前缀后缀,解析 JSP 视图)、开启注解驱动等 。示例: <context:component - scan base - package="com.example.controller"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB - INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <mvc:annotation - driven/> 三)功能模块实现 1. 用户登录验证 o 控制器(Controller):创建LoginController,编写方法处理/login请求(对应login.jsp表单提交),接收用户名、密码参数(可通过@RequestParam注解),进行简单验证(如硬编码用户名 “admin”、密码 “123” 模拟,实际可连数据库查询),验证成功用return "redirect:/main";重定向到主页控制器方法,失败则带错误信息(通过model.addAttribute)返回login视图(即login.jsp )。示例代码: package com.example.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class LoginController { @RequestMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model) { if ("admin".equals(username) && "123".equals(password)) { return "redirect:/main"; } else { model.addAttribute("error", "用户名或密码错误"); return "login"; } } 2. 登录页面(login.jsp):使用 Spring 表单标签库(需引入相关标签库)或普通 HTML 表单,提交到/login,显示错误信息(通过 EL 表达式${error} )。示例关键代码: <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <html> <body> <form:form action="/login" method="post"> 用户名:<form:input path="username"/><br> 密码:<form:password path="password"/><br> <input type="submit" value="登录"> </form:form> <c:if test="${not empty error}"> <p style="color:red">${error}</p> </c:if> </body> </html> 3. 访问控制(拦截器实现) o 创建拦截器类:实现HandlerInterceptor接口,在preHandle方法中检查会话是否有用户登录标识(如session.getAttribute("user") ,假设登录成功时在会话存user对象),无则redirect到/login并返回false拦截,有则返回true放行 。示例: package com.example.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user = request.getSession().getAttribute("user"); if (user == null) { response.sendRedirect(request.getContextPath() + "/login"); return false; } return true; } } 4. 配置拦截器:在 Spring MVC 配置文件(springmvc - servlet.xml)中注册拦截器,指定拦截路径(如/main )。示例: <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/main"/> <bean class="com.example.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors> 5. 会话管理(登出功能) o 控制器方法:在MainController中编写处理登出的方法,调用session.invalidate()销毁会话,然后redirect到登录页 。示例: package com.example.controller; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class MainController { @RequestMapping("/main") public String main() { return "main"; } @RequestMapping("/logout") public String logout(HttpSession session) { session.invalidate(); return "redirect:/login"; } } 6. 主页(main.jsp):添加 “退出” 链接, href 指向/logout 。示例: <html> <body> <h1>欢迎访问主页</h1> <a href="${pageContext.request.contextPath}/logout">退出</a> </body> </html>
06-05
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值