atwood-pan

 

SpringMVC08——拦截器——2021-05-11

拦截器概述

SpringMVC的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并做相应的处理。
例如:进行权限验证、记录请求信息的日志、判断用户是否登录等。

拦截器的定义

要使用SpringMVC的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。
  1. 通过实现HandlerInterceptor接口
  2. 继承HandlerInterceptor接口的实现类HAndlerInterceptorAdapter
  3. 实现WebRequestInterceptor接口
  4. 继承WebRequestInterceptor接口的实现类

这里我们用HandlerInterceptor接口的定义方式为例:

  1. 自定义拦截器类
/**
 * 这里不会强制要求重写方法
 */
public class MyInterceptor implements HandlerInterceptor {
    //在请求处理的方法之前执行
    //如果返回true执行下一个拦截器
    //如果返回false就不执行下一个拦截器
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("------------处理前------------");
        return true;
    }
    //在请求处理方法执行之后执行
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("------------处理后------------");
    }
    //在dispatcherServlet处理后执行,做清理工作.
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("------------清理------------");
    }
}
  1. 拦截器的配置
    要是自定义的拦截器类生效,还需要再SpringMVC的配置文件中进行配置
    <!--关于拦截器的配置-->
    <mvc:interceptors>
         <mvc:interceptor>
           <!--/** 包括路径及其子路径-->
           <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
           <!--/admin/** 拦截的是/admin/下的所有-->
           <mvc:mapping path="/**"/>
           <!--bean配置的就是拦截器-->
             <bean class="com.pp.config.LoginInterceptor"/>
         </mvc:interceptor>
    </mvc:interceptors>
  1. 编辑一个拦截器的控制器——InterceptorController
//测试拦截器的控制器
@Controller
public class InterceptorController {
    @RequestMapping("/interceptor")
    @ResponseBody
    public String test(){
        System.out.println("控制器中的方法执行了~~~");
        return "hello";
    }
}
  1. 配置tomcat测试
    在浏览器地址栏输入http://localhost:8080/interceptor
    这时候回发现拦截器放行时,前端显示hello!
    注意:配置多个拦截器,直接在配置文件中增加mvc:interceptor即可!

案例:实现用户登录权限验证!

需求:
只有登录后的用户才能访问系统的主页面,如果没有登陆系统而直接访问主页面,则拦截器会将请求拦截,并转发到登陆页面要求重新登录!相同的如果用户名或密码错误,也会要求重新登录。

  1. 创建一个User类
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
    private Integer id;
    private String username;
    private String password;
}
  1. 创建控制器类LoginController,在该类中定义向主页跳转,向登陆页面跳转,执行用户登录等操作。
@Controller
public class LoginController {
    /**
     * 向用户登录页面跳转
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String toLogin(){
        return "login";
    }
    /**
     * 用户登录
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(User user, Model model, HttpSession httpSession){
        //获取用户名和密码
        String username = user.getUsername();
        String password = user.getPassword();
        //模拟从数据库获取数据,进行判断
        if (username != null && username.equals("panpan") &&
                password != null && password.equals("123456")){
            //将用户对象添加到Session
            httpSession.setAttribute("USER_SESSION",user);
            //重定向到主页面的跳转方法
            //toMain();
            return "redirect:main";
        }
        model.addAttribute("msg","用户名或密码错误,请重新登录");
        return "login";
    }
    /**
     * 向用户主页面跳转
     */
    @RequestMapping("/main")
    public String toMain(){
        return "main";
    }
    /**
     * 退出登录
     */
    public String logout(HttpSession httpSession){
        //清楚Session
        httpSession.invalidate();
        //重定向到登录页面的跳转方法
        return "redirect:login";
    }
}

注意:向用户登录页面跳转和用户登录方法的@RequestMapping注解的value属性值相同,但是method属性值不同,这是因为跳转到登录页面接受的是GET方法提交的方法,而用户登录接受的是POST方式提交的方法。

  1. 创建LoginInterceptor
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求的URL
        String url = request.getRequestURI();
        //URL:除了login.jsp是可以公开的,其他的url都进行拦截控制
        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;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
  1. 在Spring-mvc.xml中添加拦截器
  <!--关于拦截器的配置-->
    <mvc:interceptors>
         <mvc:interceptor>
           <!--/** 包括路径及其子路径-->
           <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
           <!--/admin/** 拦截的是/admin/下的所有-->
           <mvc:mapping path="/**"/>
           <!--bean配置的就是拦截器-->
             <bean class="com.pp.config.LoginInterceptor"/>
         </mvc:interceptor>
           <!--多个拦截器配置-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.pp.config.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  1. 在jsp文件夹中创建main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
    当前用户:${USER_SESSION.username}
    <a href="${pageContext.request.contextPath}/logout">退出</a>
</body>
</html>

  1. 创建一个login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>登陆页面</h1>
    <span style="color: red">${msg}</span>
    <form action="${pageContext.request.contextPath}/login" method="post" >
        用户名:<input type="text" name="username">&nbsp;&nbsp;&nbsp;码:<input type="text" name="password">
        <input type="submit" value="登录">
    </form>
</body>
</html>
  1. 最后!配置tomcat测试
  • 当直接访问http://localhost:8080/main时,会发现要求重新登录
    在这里插入图片描述
  • 输入正确的用户名和密码即可正确跳转main页面,这里实现了退出登录,点击退出重新登陆!
    在这里插入图片描述
    在这里插入图片描述

posted on 2021-05-11 09:12  JavaCoderPan  阅读(7)  评论(0编辑  收藏  举报  来源

导航