拦截器:自定义拦截器
什么是拦截器
SpringMVC框架中的拦截器,类似于web阶段学习的过滤器(filter)
拦截器可以对处理器方法执行预处理(前置增强)和执行后处理(后置增强),还有最终处理。
过滤器与拦截器的区别
组件 | 过滤器Filter | 拦截器 Interceptor |
---|---|---|
来源 | 来源于Servlet,重量级的组件 | 来源于SpringMVC框架,只能用在这个框架中 |
拦截范围 | 所有的资源:Servlet,JSP,HTML | 只能拦截处理器 |
拦截器执行流程
实现HandlerInterceptor接口,有以下方法:
preHandler:在处理器执行前执行的方法,返回boolean类型,如果返回true就继续执行控制器。如果返回false,后面的代码不再执行。
postHandler:在处理器执行后执行的方法,如果处理器方法出现了异常,则这个方法不执行。
afterCompletion:最终通知,无论处理器中是否出现了异常,都会执行
代码
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--Spring MVC的servlet配置-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
拦截器
package com.it.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 编写拦截器,这三个方法都是默认方法,可以有选择的重写
*/
public class AccountInterceptor implements HandlerInterceptor {
/**
* 前置处理
* @param request
* @param response
* @param handler HandlerMethod对象,可以获取处理器中信息
* @return true继续后面代码,false不再继续
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器前置处理");
return true;
}
/**
* 后置处理
* @param request
* @param response
* @param handler HandlerMethod对象
* @param modelAndView 获取处理器中返回的ModelAndView对象,可以获取其中信息,甚至可以修改
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//处理器返回的ModelAndView
System.out.println(modelAndView);
modelAndView.setViewName("update");
System.out.println("拦截器后置处理");
}
/**
* 最终处理
* @param request
* @param response
* @param handler HandlerMethod对象
* @param ex 异常对象,如果处理器中出现了异常,这里可以获取出现的异常对象
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//System.out.println("异常信息:" + ex.getMessage());
System.out.println("拦截器最终处理");
}
}
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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1. 控制器包的注解扫描-->
<context:component-scan base-package="com.it.controller"/>
<!--2. 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--页面前缀-->
<property name="prefix" value="/pages/"/>
<!--页面后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--3. 注册驱动-->
<mvc:annotation-driven/>
<!--4. 静态资源由默认Servlet处理-->
<mvc:default-servlet-handler/>
<!-- 配置拦截器集合 -->
<mvc:interceptors>
<!-- 配置其中一个拦截器 -->
<mvc:interceptor>
<!-- path表示拦截的路径:/* 拦截一级目录 /** 拦截下面所有子孙目录 -->
<mvc:mapping path="/account/**"/>
<!-- 排除哪个地址不拦截 -->
<mvc:exclude-mapping path="/account/find"/>
<!-- 配置拦截器对象 -->
<bean class="com.it.interceptor.AccountInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
控制器
package com.it.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/save")
public ModelAndView save(String name) {
System.out.println("处理器中保存方法");
if ("newboy".equals(name)) {
throw new RuntimeException("用户不存在");
}
return new ModelAndView("success", "msg", "保存方法");
}
@RequestMapping("/find")
public ModelAndView find() {
System.out.println("处理器中查询方法");
return new ModelAndView("success", "msg", "查询方法");
}
}