SSM整合之拦截器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fjnmbb12/article/details/74001567

拦截器的定义

定义拦截器,实现HandlerInterceptor接口,实现三个方法 preHandle() 、postHandle()、afterCompletion()

/**
 * Created by Alex on 2017/6/30.
 * 测试拦截器1
 */
public class HandlerInterceptor1 implements HandlerInterceptor{

    //进入handler方法之前执行该拦截器
    //用于身份认证(身份授权)
    //比如身份认证,若果认证通过标识当前用户没有登录,需要此方法拦截不再向下执行
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

        //return false 表示拦截,不向下执行
        //return true 表示放行
        return false;
    }

    //进入handler方法之后,在返回modelandview之前执行该拦截器
    //应用场景从modelAndView出发:将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    //在执行handler之后,执行此拦截器
    //应用场景:统一的异常处理,统一的日志处理
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}


拦截器配置

1、springmvc拦截器针对HandlerMapping进行拦截设置。

如果在某个HandlerMapping中配置拦截器,经过该 HandlerMapping映射成功的handler最终使用该拦截器
<bean
	class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
	<property name="interceptors">
		<list>
			<ref bean="handlerInterceptor1"/>
			<ref bean="handlerInterceptor2"/>
		</list>
	</property>
</bean>
	<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
	<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>


一般不推荐使用

2、全局拦截器配置

springmvc配置类似全局的拦截器,springmvc框架会将配置的拦截器自动注入到每一个handlermapping当中去

    <!--全局拦截器-->
    <mvc:interceptors>
        <!-- 多个拦截器 , 顺序执行-->
        <mvc:interceptor>
            <!--/**标识所有url包括子url路径 -->
            <mvc:mapping path="/**"/>
            <bean class="com.alex.ssm.interceptor.HandlerInterceptor1"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--/**标识所有url包括子url路径 -->
            <mvc:mapping path="/**"/>
            <bean class="com.alex.ssm.interceptor.HandlerInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器测试

1、测试需求

多个拦截器每个方法的执行时机

2、编写两个拦截器

package com.alex.ssm.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Alex on 2017/6/30.
 * 测试拦截器1
 */
public class HandlerInterceptor1 implements HandlerInterceptor{

    //进入handler方法之前执行该拦截器
    //用于身份认证(身份授权)
    //比如身份认证,若果认证通过标识当前用户没有登录,需要此方法拦截不再向下执行
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("HandlerInterceptor1...preHandle");
        //return false 表示拦截,不向下执行
        //return true 表示放行
        return false;
    }

    //进入handler方法之后,在返回modelandview之前执行该拦截器
    //应用场景从modelAndView出发:将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("HandlerInterceptor1...postHandle");
    }

    //在执行handler之后,执行此拦截器
    //应用场景:统一的异常处理,统一的日志处理
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("HandlerInterceptor1...afterCompletion");
    }
}


package com.alex.ssm.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Alex on 2017/6/30.
 * 测试拦截器2
 */
public class HandlerInterceptor2 implements HandlerInterceptor{

    //进入handler方法之前执行该拦截器
    //用于身份认证(身份授权)
    //比如身份认证,若果认证通过标识当前用户没有登录,需要此方法拦截不再向下执行
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("HandlerInterceptor2...preHandle");
        //return false 表示拦截,不向下执行
        //return true 表示放行
        return false;
    }

    //进入handler方法之后,在返回modelandview之前执行该拦截器
    //应用场景从modelAndView出发:将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("HandlerInterceptor2...postHandle");
    }

    //在执行handler之后,执行此拦截器
    //应用场景:统一的异常处理,统一的日志处理
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("HandlerInterceptor2...afterCompletion");
    }
}

3、两个拦截器都放行

HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle
HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion

总结:
  1.   preHandle方法按照顺序执行
  2. postHandle和afterCompletion方法按照逆向顺序执行

4、拦截器1放行,拦截器2不放行

HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion

总结:
  1. 拦截器1放行,拦截器2preHandle方法才会执行。
  2. 拦截器2preHandle方法不放行,拦截器2postHandleafterCompletion方法不会执行
  3. 只要有一个拦截器被拦截,一个postHandle都不会执行

5、两个拦截器都不放行

HandlerInterceptor1...preHandle
总结:
  1. 拦截器1preHandle不放行,postHandleafterCompletion也不会执行
  2. 拦截器1不放行,拦截器2也不执行

6、小结

根据测试结果,对拦截器应用。
比如:同意日志处理拦截器,需要该拦截器preHandle一定要放行,同时将它放在拦截器连接中第一位

比如:登录认证拦截器,放在拦截器连接中的第一位。权限校验拦截器,放在登录认证拦截器之后执行(因为只有登录成功后才能校验权限)


拦截器的应用(实现登录认证功能)

1、需求

1.用户请求url
2.拦截器进行拦截校验(首先判断url是否为公开地址(无需登录即可访问),再判断,若用户session不存在,则跳转至登录页面,若存在则放行)

2、登录的controller方法

package com.alex.ssm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;

/**
 * Created by Alex on 2017/6/30.
 */
@Controller
public class LoginCotroller {

    //登录
    @RequestMapping("/login")
    public String login(HttpSession session,String username, String password) throws Exception{
        //调用service进行用户身份认证

        //在session中保存用户身份信息
        session.setAttribute("username",username);
        //重定向至商品列表页面
        return "redirect:/items/queryItems.action";
    }

    //退出登录
    @RequestMapping("/logout")
    public String logout(HttpSession session) throws Exception{
        //清除session
        session.invalidate();
        //重定向至商品列表页面
        return "redirect:/items/queryItems.action";
    }
}

3、登录认证拦截器的实现

代码实现
    //进入handler方法之前执行该拦截器
    //用于身份认证(身份授权)
    //比如身份认证,若果认证通过标识当前用户没有登录,需要此方法拦截不再向下执行
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //获取请求的url
        String url = httpServletRequest.getRequestURI();
        //判断url是否为公开地址(实际使用时需要配置在配置文件中)
        //这里公开地址就是登录的地址
        if(url.indexOf("login.action")>=0){
            //如果是登录提交,则放行
            return true;
        }
        //判断session
        HttpSession session = httpServletRequest.getSession();
        //从session中取出用户身份信息
        String usernmae = (String)session.getAttribute("usernmae");
        if(usernmae != null ){
            //身份存在session 放行
            return true;
        }
        //执行至此,表示用户身份需要认证,就跳转至登录页面
        httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(httpServletRequest,httpServletResponse);
        //return false 表示拦截,不向下执行
        return false;
    }


配置拦截器
    <!--全局拦截器-->
    <mvc:interceptors>
        <!-- 多个拦截器 , 顺序执行-->
        <!-- 登录认证拦截器  -->
        <mvc:interceptor>
            <!--/** 表示拦截所有url包括子url路径 -->
            <mvc:mapping path="/**"/>
            <bean class="com.alex.ssm.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>


4、测试


可以看到,这里你若没有执行登录操作,直接访问商品列表的地址的话,拦截器会将你的请求拦截下来,重新定向至登录页面,要求你登录。


猜你喜欢

转载自blog.csdn.net/fjnmbb12/article/details/74001567