拦截器
概述:SpringMVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并做响应的处理,例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
实例代码:
// 定义一个拦截器
public class CustomerInterceptor implements HandlerInterceptor{
/*
* 该方法会在整个请求完成,即视图渲染结束之后执行,可以通过此方法实现一些资源清理、记录日志信息等工作。
*
*/
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
/*
* 该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做进一步修改。
*
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
}
/*
* 该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续
* 所有操作。
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
return false;
}
}
单个拦截器执行流程:
实例代码:
编写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-config.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>
定义拦截器类:
// 定义一个拦截器
public class CustomerInterceptor implements HandlerInterceptor{
/*
* 该方法会在整个请求完成,即视图渲染结束之后执行,可以通过此方法实现一些资源清理、记录日志信息等工作。
*
*/
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
System.out.println("这里是afterCompletion...");
}
/*
* 该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做进一步修改。
*
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
System.out.println("这里是postHandle...");
}
/*
* 该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续
* 所有操作。
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("这里是preHandle...");
return true;
}
}
定义一个Controller类:
@Controller
public class HelloController {
@RequestMapping("/hello")
public String Hello(){
System.out.println("Hello!");
return "success";
}
}
配置springmvc-config.xml文件:
<!-- 指定需要扫描的包 -->
<context:component-scan base-package="com.bdqn.cn.controller" />
<!-- 视图解析器 -->
<bean id="viewResolve"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置一个前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 设置一个后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 使用bean直接定义在<mvc:interceptors>下面的拦截器将拦截所有请求 -->
<bean class="com.bdqn.cn.interceptor.CustomerInterceptor" />
</mvc:interceptors>
多个拦截器的执行流程:
Interceptor1代码:
public class Interceptor1 implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
System.out.println("Interceptor1.afterCompletion...");
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
System.out.println("Interceptor1.postHandle...");
}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("Interceptor1.preHandle...");
return true;
}
}
Interceptor2代码:
public class Interceptor2 implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
System.out.println("Interceptor2.afterCompletion...");
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
System.out.println("Interceptor2.postHandle...");
}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("Interceptor2.preHandle...");
return true;
}
}
配置文件代码:
<mvc:interceptors>
<!-- 拦截器1 -->
<mvc:interceptor>
<!-- 配置拦截器作用的路径 /**表示拦截所有的请求 -->
<mvc:mapping path="/**"/>
<bean class="com.bdqn.cn.interceptor.Interceptor1" />
</mvc:interceptor>
<!-- 拦截器2 -->
<mvc:interceptor>
<!-- 当给了具体的拦截路径那就就只会拦截给定路径 -->
<mvc:mapping path="/hello"/>
<bean class="com.bdqn.cn.interceptor.Interceptor2" />
</mvc:interceptor>
</mvc:interceptors>
Controller代码:
拦截器案例
案例示意图:
Controller代码:
@Controller
public class UserContoller {
/*
* 向用户登录页面跳转
*/
@RequestMapping(value = "/login")
public String toLogin() {
return "login";
}
/*
* 用户登录
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(User user, Model model, HttpSession session) {
// 获取用户账号和密码
String username = user.getUsername();
String password = user.getPassword();
// 模拟从数据库中获取账号和密码进行判断
if (username != null && username.equals("Tom") && password != null
&& password.equals("123.com")) {
// 将账号和面存储到Session
session.setAttribute("USER_SESSION", user);
// 重定向到主页面的跳转方法
return "redirect:main";
}
model.addAttribute("msg", "账号或密码错误");
return "login";
}
@RequestMapping("/main")
public String toMain(){
return "main";
}
}
拦截器代码:
public class LoginInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object obj) throws Exception {
// TODO Auto-generated method stub
// 获取请求的url
String url = request.getRequestURI();
// url:除了login.jsp是可以公开访问的,其他的请求都进行拦截
if(url.indexOf("/login")>=0){
return true;
}
// 获取session
HttpSession session = request.getSession();
User user = (User) session.getAttribute("USER_SESSION");
// 判断session中是否有数据,如果有,则返回true,继续执行
if(user != null){
return true;
}
// 不符合条件
request.setAttribute("msg", "您还没有登录,请先登录!");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
}
配置文件代码:
<!-- 指定需要扫描的包 -->
<context:component-scan base-package="com.bdqn.cn.controller" />
<!-- 视图解析器 -->
<bean id="viewResolve"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置一个前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 设置一个后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 使用bean直接定义在<mvc:interceptors>下面的拦截器将拦截所有请求 -->
<bean class="com.bdqn.cn.interceptor.LoginInterceptor" />
</mvc:interceptors>
Login.jsp
Main.jsp