SpringMVC(四)拦截器

1. 拦截器相关概念

  • Servlet:处理Request请求和Response响应
  • 过滤器(Filter):对Request请求起到过滤的作用,作用在Servlet之前,如果配置为/*可以对所有的资源访问(servlet、js/css静态资源等)进行过滤处理
  • 监听器(Listener):实现了javax.servlet.ServletContextListener 接口的服务器端组件,它随Web应用的启动而启动,只初始化一次,然后会一直运行监视,随Web应用的停止而销毁
    • 作用一:做一些初始化工作
    • 作用二:监听web中的特定事件,比如HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控,比如统计在线人数,利用HttpSessionLisener等。
  • 拦截器(Interceptor):是SpringMVC、Struts等表现层框架自己的,不会拦截jsp/html/css/image的访问等,只会拦截访问的控制器方法(Handler)。底层采用的是aop的思想
    • 从配置的角度也能够总结发现:serlvet、filter、listener是配置在web.xml中的,而interceptor是配置在表现层框架自己的配置文件中的
    • 在Handler业务逻辑执行之前拦截一次
    • 在Handler逻辑执行完毕但未跳转页面之前拦截一次
    • 在跳转页面之后拦截一次

2. 自定义拦截器

步骤:

  1. 实现接口HandlerInterceptor
  2. 重写方法:
    • preHandle:handler之前执行,返回true表示放行
    • postHandle:handler逻辑真正执行完成但尚未返回页面
    • afterCompletion:返回页面之后
      在这里插入图片描述
  • 自定义拦截器如下:
public class MyHandlerInterceptor implements HandlerInterceptor {

    // 在Controller控制器中的Handler方法执行前执行
    // 返回值true,执行后续的请求(请求一:执行后续的其他的拦截器,情况二:所有的拦截器搜执行完毕,并放行执行Handler方法)
    // 返回值false
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle执行了");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle执行了");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion执行了");
    }
}
  • springmvc.xml配置拦截器
 	<!--配置拦截器-->
 	<mvc:interceptors>
        <mvc:interceptor>
            <!--/**为拦截浏览器所有的请求-->
            <mvc:mapping path="/**"/>
            <bean id="interceptor" class="com.szz.interceptor.MyHandlerInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
  
  • handler处理请求(Controller层)
@Controller
public class DefaultController {
    /**
     * 定义方法, 相当于以前Servlet中用于处理请求的方法
     */
    @RequestMapping("gotoResult")
    public ModelAndView gotoResult(ModelAndView modelAndView){
        System.out.println("gotoResult执行了");
        // 封装数据
        modelAndView.addObject("nowDate",new Date());
        //指定页面
        modelAndView.setViewName("result");
        return modelAndView;
    }
}

3. 拦截器登录案例

  • 需求分析
    • 有一个登录页面,判断用户是否登录,若未登录跳转到登录界面,并写一个Handler用于接收登录请求,实现页面跳转。
  • 实现步骤:
  1. 登录页面有一个提交表单的动作,需要在Controller中做如下处理:
    • 判断用户名密码是否正确(zhangsan/123)
    • 如果正确,向session中写入用户信息(写入用户名username),跳转到登录成功页面
    • 如果不正确, 跳转到登录页面
  2. 开发拦截器:
    • 拦截用户请求,判断用户是否登录(登录页面跳转请求和登录提交请求不能拦截)
    • 如果用户已经登录则放行
    • 如果用户未登录则跳转到登录页面

3.1 各部分代码设计

  • index.jsp 登录页面:
<fieldset>
    <h3>测试登录案例</h3>
    <form method="post" action="${pageContext.request.contextPath}/user/login.action">
        用户名:<input type="text" name="username"><br>
        密 码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</fieldset>
  • UserController
@Controller
@RequestMapping("default")
public class DefaultController {
    /**
     * 定义方法, 相当于以前Servlet中用于处理请求的方法
     */
    @RequestMapping("login")
    public String login(String username, String password, HttpServletRequest request){
        // 业务判断
        if ("zhang3".equals(username)&&"123".equals(password)){
            // 登录成功
            request.getSession().setAttribute("username",username);
            //跳转show页面, 显示数据
            return "redirect:/account/findAll.do";
        }else {
            // 登录失败,跳转到登录页面
            return "redirect:http://localhost:8080/index.jsp";
        }
    }
}
  • AccountController负责查询,并跳转到显示页面:
@Controller
@RequestMapping("account")
public class AccountController {

    @RequestMapping("findAll")
    public String findAll(ModelMap modelMap){
        modelMap.addAttribute("message","模拟查询出2条信息");
        return "result";
    }
}

  • 拦截器LoginInterceptor
 /*
    首先判断是否登录了,如果登录了,放行,如果没有登录,跳转到登录页面
      细节:
          判断是否是登录请求,如果是登录请求,放行
          如果不是登录请求: 判断session中是否存储了用户信息
     */
public class LoginInterceptor implements HandlerInterceptor {

    // 用户登录拦截器
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器执行了");

        // 1.获取当前拦截的请求信息
        String requestURI = request.getRequestURI();
        System.out.println("requestURI = " + requestURI);
       
        // 2.如果当前请求是否是登录请求,如果是放行
        if ("/default/login.do".equals(requestURI)){
            return true;
        }

        // 3.如果当前用户已经登录,用户执行的操作都放行
        Object username = request.getSession().getAttribute("username");
        if (username == null){
            // 用户未登录,跳转到登录页面
            response.sendRedirect(request.getContextPath()+"/index.jsp");
            return false;
        }else {
            // 用户登录,放行
            return true;
        }
    }
}
  • springmvc.xml的配置
 <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/**为拦截浏览器所有的请求-->
            <mvc:mapping path="/**"/>
            <bean id="interceptor" class="com.szz.interceptor.LoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值