16.拦截器(传智播客)

SpringMVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

一.拦截器demo

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;
    }
    //进入Handler方法之后,返回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");
    }
}

2.配置拦截器

<!-- 拦截器 -->
<mvc:interceptors>
    <!-- 多个拦截器,顺序执行 -->
    <mvc:interceptor>
        <!-- 拦截所有url包括子url -->
        <mvc:mapping path="/**"/>
        <bean class="com.steven.ssm.utils.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.steven.ssm.utils.interceptor.HandlerInterceptor1"></bean>
    </mvc:interceptor>     
</mvc:interceptors>

3.测试结果总结

  1. 拦截器1和拦截器2都放行:
    拦截器1preHandle…
    拦截器2 preHandle…
    拦截器2 postHandle…
    拦截器1postHandle…
    拦截器2 afterCompletion…
    拦截器1 afterCompletion…
    分析:先执行拦截器1的preHandle再执行拦截器2的preHandle,后处理是限制性拦截器2再执行拦截器1.
  2. 拦截器1放行拦截器2不放行:
    拦截器1preHandle…
    拦截器2 preHandle…
    拦截器1 afterCompletion…
    分析:拦截器1preHandle执行拦截器2preHandle也执行,被拦截器2中断后,后面的方法都不执行,除了拦截器1的afterCompletion。
  3. 拦截器1不放行拦截器2不放行:
    拦截器1preHandle…
    分析:只执行拦截器1的preHandle方法。
    如果要是统一的日志处理需求,需要放到拦截器1的前处理中。
    拦截器是按照在springmvc.xml中的配置顺序执行。

二.用户认证

需求:访问网站的任何url(登陆页面除外)先判断是否登陆,如果未登录跳转到登陆页面。
1.编写拦截器

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        //获取请求的url
        String requestURI = request.getRequestURI();
        if (requestURI.contains("login")) {
            return true;
        }

        //判断用户的登陆状态
        String username = (String) request.getSession().getAttribute("username");
        //如果session中没有用户信息跳转到登陆页面
        if (username != null) {
            return true;
        }
        request.getRequestDispatcher("/WEB-INF/views/items/login.jsp").forward(request,response);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

2.配置拦截器

<!-- 拦截器 -->
<mvc:interceptors>
   <!-- 多个拦截器,顺序执行 -->
   <!-- 拦截所有url包括子url -->
   <mvc:interceptor>
       <mvc:mapping path="/**"/>
       <bean class="com.steven.ssm.utils.interceptor.LoginInterceptor"></bean>
   </mvc:interceptor>
</mvc:interceptors>

3.handler编写

@Controller
public class LoginController {

    //登录
    @RequestMapping("/login")
    public String login( HttpSession session, String username, String password){
        //调用service进行用户身份验证
        session.setAttribute("username", username);
        return "redirect:items/queryItems";
    }

    //登出
    @RequestMapping("/logout")
    public String logout( HttpSession session){
        //调用service进行用户身份验证
        session.invalidate();
        return "redirect:items/queryItems";
    }
}

4.web层编写

<form action="${pageContext.request.contextPath}/login">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    <input type="submit" value="登陆">
</form>
当前用户:${username},
<c:if test="${username!=null}">
    <a href="${pageContext.request.contextPath}/logout">退出</a>
</c:if>

5.测试
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u010286027/article/details/84864488
今日推荐