拦截器

亡梦爱人 提交于 2020-01-18 03:26:38

SpringMVC拦截器介绍

  • SpringMVC拦截器(Interceptor)实现对每⼀个请求处理前后进⾏相
    关的业务处理,类似与servlet中的Filter。
  • SpringMVC 中 的Interceptor 拦截请求是通过HandlerInterceptor来实现的。

SpringMVC拦截器定义方式

在SpringMVC中定义⼀个Interceptor⾮常简单,主要有4种⽅式:

  • 实现Spring的HandlerInterceptor接⼝;
  • 继承实现了HandlerInterceptor接⼝的类,⽐如Spring 已经提供的实现了HandlerInterceptor 接⼝的抽象类HandlerInterceptorAdapter
  • 实现Spring的WebRequestInterceptor接⼝;
  • 继承实现了WebRequestInterceptor的类;

定义拦截器

实现HandlerIntercepter接⼝:

public class MyHandlerIntercepter1 implements HandlerInterceptor{
//Handler执⾏前调⽤
//应⽤场景:登录认证、身份授权
//返回值为true则是放⾏,为false是不放⾏
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
        return false; 
        }
//进⼊Handler开始执⾏,并且在返回ModelAndView之前调⽤
//应⽤场景:对ModelAndView对象操作,可以把公共模型数据传到前台,可以统⼀指定视图
    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
}
//执⾏完Handler之后调⽤
//应⽤场景:统⼀异常处理、统⼀⽇志处理
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {
} }

配置拦截器

SpringMVC拦截器是绑定在HandlerMapping中的 ,即;如果某个
HandlerMapping中配置拦截,则该HandlerMapping映射成功的Handler
会使⽤该拦截器。

针对单个HandlerMapping配置

只有通过该处理器映射器查找到的处理器,才能使⽤该拦截器。
如果现在有两个处理器映射器:其中⼀个设置了处理器拦截器,另外⼀个没有
设置,如果通过第⼆个映射器查找到的处理器,是⽆法使⽤拦截器的。

<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
"> 
    <property name="interceptors"> 
        <list>
            <ref bean="interceptor" />
        </list>
    </property>
</bean> 
<bean id="interceptor" class="com.kkb.ssm.interceptor.MyHandlerInterceptor" />

全局拦截器配置(推荐)

  • SpringMVC的全局拦截器配置,其实是把配置的拦截器注⼊到每个已初始化的
    HandlerMapping中了。
<!-- 配置全局mapping的拦截器 -->
<mvc:interceptors>
<!-- 公共拦截器可以拦截所有请求,⽽且可以有多个 -->
    <bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor1" /
>
    <bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor2" /
>
<!-- 如果有多个拦截器,则按照顺序进⾏配置 -->
<mvc:interceptor>
<!-- /**表示所有URL和⼦URL路径 -->
    <mvc:mapping path="/test/**" />
 <!-- 特定请求的拦截器只能有⼀个 -->
        <bean class="com.kkb.ssm.interceptor.MyHandlerInterceptor3" />
    </mvc:interceptor>
</mvc:interceptors>

多拦截器拦截规则

如果有多个拦截器,那么配置到springmvc.xml中最上⾯的拦截器,拦截优先级最⾼。

拦截器应⽤(实现登录认证)

需求

拦截器对访问的请求URL进⾏拦截校验

  • 如果请求的URL是公开地址(⽆需登录就可以访问的URL,具体指的就是保护login字段的请求URL),采取放⾏。
  • 如果⽤户session存在,则放⾏。
  • 如果⽤户session中不存在,则跳转到登录⻚⾯。

登录jsp⻚⾯

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://
www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>登录⻚⾯</title>
</head> 
<body>
<form action="${pageContext.request.contextPath }/login" method="post"> 
    <table align="center" border="1" cellspacing="0" > 
        <tr>
            <td>⽤户名:<input type="text" name="username"/></td>
        </tr> 
       <tr>
            <td>密 码:<input type="text" name="password"/></td>
      </tr> 
        <tr>
            <td><input type="submit" value="登录"/></td>
        </tr>
    </table>
</form>
</body>
</html>

Controller类

@Controller
public class LoginController {
//显示登录⻚⾯
    @RequestMapping("/loginPage")
    public String loginPage(){
        return "login";
    }
    // 登录
    @RequestMapping("/login")
    public String login(HttpSession session, String username, String password) {
    // Service进⾏⽤户身份验证
    // 把⽤户信息保存到session中
        session.setAttribute("username", username);
    // 重定向到商品列表⻚⾯
        return "redirect:/item/queryItem"; 
    }
// 退出
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
//清空session
        session.invalidate();
// 重定向到登录⻚⾯
        return "redirect:/loginPage"; 
    } 
}

HandlerInterceptor类

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
//获取请求的URI
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);
// 1、 如果请求的URL是公开地址(⽆需登录就可以访问的URL),采取放⾏。
        if(requestURI.indexOf("login")>-1) 
            return true;
// 2、 如果⽤户session存在,则放⾏。
        String username = (String) 
        request.getSession().getAttribute("username");
        if(username !=null && !username.equals("")) 
            return true;
// 3、 如果⽤户session中不存在,则跳转到登录⻚⾯。
        response.sendRedirect("/ssm/loginPage");
        return false; 
    }
    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
    }
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {
// TODO Auto-generated method stub
    } 
}

HandlerInterceptor配置

<!-- 配置全局mapping的拦截器 -->
<mvc:interceptors>
<!-- 如果有多个拦截器,则按照顺序进⾏配置 -->
    <mvc:interceptor>
<!-- /**表示所有URL和⼦URL路径 -->
        <mvc:mapping path="/**" />
        <bean class="com.kkb.ssm.interceptor.LoginInterceptor" />
    </mvc:interceptor>
<!-- 如果有多个拦截器,则按照顺序进⾏配置 -->
    <mvc:interceptor>
<!-- /**表示所有URL和⼦URL路径 -->
        <mvc:mapping path="/**" />
            <bean class=" com.kkb.ssm.interceptor.MyHandlerInterceptor" />
        </mvc:interceptor>
</mvc:interceptors>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!