spring中的拦截器

what?

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

Spring MVC中的拦截器定义方式

  • 通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(HandlerInterceptorAdaptor)来定义。
  • 通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。
package com.yzb.chapter15;

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

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

public class CustomInterceptor implements HandlerInterceptor {
    /*
    * 该方法在控制器方法前执行,其返回值表示是否执行中断后续操作,当返回值是true的时候,表示继续向下执行,当返回值是fals时 
    * ,中断后续的所有的操作(包括调用下一个拦截器和控制器中的方法。)
    * */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        return false;
    }
    /*
    * 该方法在控制器方法调用之后,在解析视图之前执行,可以通过此方法对请求域中的模型和视图进行进一步的修改
    * */
    @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 {

    }
}

拦截器的配置

 <!--配置拦截器-->
    <mvc:interceptors>
        <!--使用bean直接定义在<mvc.interceptors下面的Interceptor将拦截所有请求>-->
        <!--全局拦截器-->
        <bean class="com.yzb.chapter15.interceptor.CustomInterceptor"/>
        <!--拦截器1-->
        <mvc:interceptor>
            <!--1:拦截器拦截的路径-->
            <mvc:mapping path="/**"/>
            <!--2:拦截器放行的路径-->
            <mvc:exclude-mapping path=""/>
            <!--3:表示在<mvc.interceptor>下面的,表示对匹配路径的请求才进行拦截-->
            <bean class="com.yzb.chapter15.interceptor.Interceptor1"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--表示拦截所有以hello结尾的拦截请求-->
            <mvc:mapping path="/hello"/>
            <bean class="com.yzb.chapter15.interceptor.Interceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--在编写这个拦截器的时候,一定要按照123的顺序编写-->

单个拦截器

在这里插入图片描述

代码

在web.xml中配置DispatcherServelt,以及在初始化init-param中配置springmvc.xml的映射路径
在springmvc.xml中配置包组件的自动扫描,以及视图解析器的配置。

HelloCustommer

package com.yzb.chapter15.controller;

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

@Controller
public class HelloController {
    /*
    * 页面跳转
    * */
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("hello!");
        return "success";
    }

}

CustomerInterceptor

package com.yzb.chapter15.interceptor;

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

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

public class CustomInterceptor implements HandlerInterceptor {
    /*
    * 该方法在控制器方法前执行,其返回值表示是否执行中断后续操作,当返回值是true的时候,表示继续向下执行,当返回值是fals时
    * ,中断后续的所有的操作(包括调用下一个拦截器和控制器中的方法。)
    * */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("Customer.....preHandle");
        //对拦截的请求进行放行处理
        return true;
    }
    /*
    * 该方法在控制器方法调用之后,在解析视图之前执行,可以通过此方法对请求域中的模型和视图进行进一步的修改
    * */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Customer.....postHandle");
    }
    /*
    * 该方法在整个请求完成之后,也就是在视图渲染结束之后,可以通过这个方法进行资源的清理,日志信息的记录等。
    * */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("Customer.....afterHandle");
    }
}

springmvc.xml

    <!--配置拦截器-->
    <mvc:interceptors>
        <!--使用bean直接定义在<mvc.interceptors下面的Interceptor将拦截所有请求>-->
        <!--全局拦截器-->
        <bean class="com.yzb.chapter15.interceptor.CustomInterceptor"/>
    </mvc:interceptors>

多个拦截器

Interceptor1

package com.yzb.chapter15.interceptor;

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

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

public class Interceptor1 implements HandlerInterceptor {
    /*
     * 该方法在控制器方法前执行,其返回值表示是否执行中断后续操作,当返回值是true的时候,表示继续向下执行,当返回值是fals时
     * ,中断后续的所有的操作(包括调用下一个拦截器和控制器中的方法。)
     * */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("Interceptor1.....preHandle");
        //对拦截的请求进行放行处理
        return true;
    }
    /*
     * 该方法在控制器方法调用之后,在解析视图之前执行,可以通过此方法对请求域中的模型和视图进行进一步的修改
     * */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor1.....postHandle");
    }
    /*
     * 该方法在整个请求完成之后,也就是在视图渲染结束之后,可以通过这个方法进行资源的清理,日志信息的记录等。
     * */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("Interceptor1.....afterHandle");
    }
}

Interceptor2

package com.yzb.chapter15.interceptor;

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

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

public class Interceptor2 implements HandlerInterceptor {
    /*
     * 该方法在控制器方法前执行,其返回值表示是否执行中断后续操作,当返回值是true的时候,表示继续向下执行,当返回值是fals时
     * ,中断后续的所有的操作(包括调用下一个拦截器和控制器中的方法。)
     * */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("Interceptor2.....preHandle");
        //对拦截的请求进行放行处理
        return true;
    }
    /*
     * 该方法在控制器方法调用之后,在解析视图之前执行,可以通过此方法对请求域中的模型和视图进行进一步的修改
     * */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor2.....postHandle");
    }
    /*
     * 该方法在整个请求完成之后,也就是在视图渲染结束之后,可以通过这个方法进行资源的清理,日志信息的记录等。
     * */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("Interceptor2.....afterHandle");
    }
}

Springmvc.xml

 <mvc:interceptors>
       <bean class="com.yzb.chapter15.interceptor.CustomInterceptor"></bean>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.yzb.chapter15.interceptor.Interceptor1"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean class="com.yzb.chapter15.interceptor.Interceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

结果图

在这里插入图片描述
从结果图可以看出来,当有多个拦截器同时工作时,他们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而他们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。

模拟用户登录

User

package com.yzb.chapter15.po;

public class User {
    private Integer id;
    private String username;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

UserController

package com.yzb.chapter15.controller;

import com.yzb.chapter15.po.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpSession;

@Controller
public class UserController {
    /*
    * 跳转登录页面
    * */
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String toLogin(){
        return "login";
    }
    /*
    * 用户登录
    * */
    @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("xiaoyue") &&password!=null &&password.equals("123")){
            //将对象加入到sessio中
            httpSession.setAttribute("USER_SESSION",user);
            //重定向到主页面的跳转方法
            return "redirect:main";
        }
        model.addAttribute("msg","用户名或密码错误,请重新登录");
        return "login";
    }
    /*
    * 向主页面跳转
    * */
    @RequestMapping("main")
    public String toMain(){
        return "main";
    }
    /*
    * 退出登录
    * */
    @RequestMapping("logout")
    public String logout(HttpSession session){
        //清除session
        session.invalidate();
        //重定向到登录页面
        return "redirect:login";
    }
}

LoginInterceptor

package com.yzb.chapter15.interceptor;

import com.yzb.chapter15.po.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //获取请求的URL
        String url = httpServletRequest.getRequestURI();
        //在url中,除了login.jsp是可以公开访问的,其他的URL都可以进行控制
        if(url.indexOf("/login")>0){
            return true;
        }
        //获取session
        HttpSession session = httpServletRequest.getSession();
        User user_session = (User) session.getAttribute("USER_SESSION");
        //判断session中是否又用户数据,如果有,则返回true,继续向下执行
        if(user_session!= null){
            return true;
        }
        //不符合条件的给出提示信息,并转发到登录页面
        httpServletRequest.setAttribute("msg","您还没有登录");
        httpServletRequest.getRequestDispatcher("/WEB-INF/JSP/login.jsp").forward(httpServletRequest,httpServletResponse);
        return false;


    }

    @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 {

    }
}

main.jsp

<%--
  Created by IntelliJ IDEA.
  User: 岳振彪
  Date: 2020/7/1
  Time: 15:52
  To change this template use File | Settings | File Templates.
--%>
<%@ 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>

login.jsp

<%--
  Created by IntelliJ IDEA.
  User: 岳振彪
  Date: 2020/7/1
  Time: 15:53
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
${msg}
<form action="${pageContext.request.contextPath}/login" method="post">
    用户名:<input type="text" name="username"><br/>
    密&nbsp;&nbsp;&nbsp;码<input type="password" name="password"><br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

springmvc.xml

 <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.yzb.chapter15.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值