SpringMVC拦截器的应用

SpringMVC拦截器的应用

SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对用户请求进行拦截和处理。
SpringMVC中定义拦截器需要实现HandlerInterceptor接口。先来看下HandlerInterceptor接口的源码。

 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      return true;
    }

 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

HandlerInterceptor接口中定义了三个方法:

  • preHandle:在处理器处理请求之前调用,只有返回true,才会继续执行后续的拦截器和最终处理请求的处理器。如果配置了多个拦截器,当返回值为true 时就会继续调用下一个拦截器的preHandle的方法,如果已经是最后一个拦截器且最后一个拦截器在preHandle方法中返回true才会继续调用处理器处理请求。
  • postHandle:在处理器处理请求完成DispatcherServlet返回ModelAndView之后进行调用。可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。
  • afterCompletion:在处理器处理请求完成之后,DispatcherServlet 渲染了对应的视图之后执行。

单个拦截器

这里只演示preHandle方法的使用,即在请求之前验证用户是否已经登录,如果登录则放行,否则返回到登录页面让用户进行登录。

新建包com.jiuyue.interceptor,在该包下新建一个LoginInterceptor类,实现HandlerInterceptor接口。

/**
 * Create bySeptember
 * 2019/1/9
 * 12:46
 */
public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("====>用户登录验证拦截器:preHandle");
        if(request.getSession().getAttribute("token")==null){
            request.getRequestDispatcher("/user/login").forward(request, response);
            return false;
        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

LoginInterceptor拦截器中preHandle方法判断用户是否已经登录,如果已经登录则放行,未登录则将请求重定向到登录页面。

spring-mvc.xml文件中配置拦截器。(类全局配置,所有的处理器适配器都会获得该拦截器链)

       <!--配置拦截器链,多个拦截器按顺序执行-->
        <mvc:interceptors>
            <!--用户登录拦截器-->
            <mvc:interceptor>
                <!--拦截的路径-->
                <mvc:mapping path="/**"/>
                <!--不进行拦截的路径,/user/login和 /user/doLogin不拦截-->
                <mvc:exclude-mapping path="/user/*ogin"/>
                <bean class="com.jiuyue.interceptor.LoginInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

标签中可包含多个拦截器配置,即,多个拦截器按照顺序执行。每个拦截器都需要配置映射该拦截器需要拦截的url,使用标签配置不需要拦截器的url,最后需要配置拦截器bean。

修改doLogin方法,当用户提交登录请求时,设置一个token值保存到session中,不然程序就会一直拦截到未登录重定向到登录页面了。

  @RequestMapping(value = "/doLogin",method = RequestMethod.POST)
    public @ResponseBody Map<String,Object> doLogin(HttpServletRequest request, HttpServletResponse response, User user){
        System.out.println(request);
        System.out.println(response);
        Map<String,Object> result = new HashMap<String, Object>();
        result.put("error_code",0);
        result.put("error_message","登录成功");
        result.put("user",user);
        request.getSession().setAttribute("token",user.getUserName()+user.getPassword());
        return result;
    }

多个拦截器

添加一个用户管理处理器AdminController。

@Controller
@RequestMapping(value = "/admin")
public class AdminController {
    @RequestMapping(value = "/findUserByUserName")
    public String findUserByUserName(){
        return "userList";
    }
}

既然是用户管理肯定不能让普通用户访问了。添加一个拦截器AdminInterceptor,在preHandle拦截判断登录的用户是否有权限访问。

public class AdminInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("=====》管理员权限验证拦截器:preHandle");
        //能执行到这里,说明token不为空
        String token = request.getSession().getAttribute("token").toString();
        //如果是管理员则放行
        System.out.println("token:"+token);
        if(token.contains("admin")){
            return true;
        }else {
            System.out.println("没有权限。。。");
            request.getRequestDispatcher("/user/permissiondenied").forward(request, response);
            return false;
        }
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

在spring-mvc配置文件中添加一个拦截器的配置即可。

        <!--配置拦截器链,多个拦截器按顺序执行-->
        <mvc:interceptors>
            <!--用户登录拦截器-->
            <mvc:interceptor>
                <!--拦截的路径-->
                <mvc:mapping path="/**"/>
                <!--不进行拦截的路径,/user/login和 /user/doLogin不拦截-->
                <mvc:exclude-mapping path="/user/*ogin"/>
                <bean class="com.jiuyue.interceptor.LoginInterceptor"/>
            </mvc:interceptor>

            <!--配置管理员权限拦截-->
            <mvc:interceptor>
                <mvc:mapping path="/admin/**"/>
                <bean class="com.jiuyue.interceptor.AdminInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

启动tomcat,先访问登录页面,随便输个用户名和密码登录,再访问"/admin/findUserByUserName",则跳转到相关jsp页面,并在控制台输出。(如果登录页面用户是admin,请求允许访问,执行完方法跳转到userList页面。)

=====》用户登录验证拦截器:preHandle
=====》管理员权限验证拦截器:preHandle
没有权限。。。

猜你喜欢

转载自blog.csdn.net/qq_37745470/article/details/86150491