Spring MVC(5)(拦截器)

版本:idea2020.1.1    jdk1.8   maven3.6.3

注:本文章摘自Java EE企业级应用开发教程,黑马程序员/编著,仅用于记录学习笔记,分享学习经历。

Tomcat配置参考:https://mp.csdn.net/editor/html/114296147

一、拦截器(Interceptor)

拦截用户请求并做响应的处理,例如可以进行权限验证,记录请求信息的日志,判断用户是否登录等。

1、定义

(1)通过实现HandlerInterceptor接口或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义

(2)实现WebRequestInterceptor接口或继承WebRequestInterceptor接口的实现类来定义

例:实现HandlerInterceptor接口

public class InterceptorDemo implements HandlerInterceptor {
    @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 {

    }
}
HandlerInterceptor接口中的方法
方法名说明
perHandler()在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)
postHandle()在控制器方法调用之后,解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。
afterCompletion()在整个请求完成,即视图渲染结束之后执行,可以通过此方法实现一些资源清理、记录日志等工作。

 2、配置

    <!--配置拦截器-->
    <mvc:interceptors>
        <!--使用bean直接定义在<mvc:interceptors>下面的Interceptor将拦截所有请求-->
        <bean class="com.jc.Interceptro.InterceptorDemo"/>
        <!--拦截器1-->
        <mvc:interceptor>
            <!--配置拦截器作用的路径-->
            <mvc:mapping path="/**"/>
            <!--配置不需要拦截器作用的路径-->
            <mvc:exclude-mapping path=""/>
            <!--定义在<mvc:interceptor>下面的,表示对匹配路径的请求才进行拦截-->
            <bean class="com.jc.Interceptro.InterceptorDemo"/>
        </mvc:interceptor>
        <!--拦截器2-->
        <mvc:interceptor>
            <!--拦截所有以hello结尾的路径-->
            <mvc:mapping path="/hello"/>
            <bean class="com.jc.Interceptro.InterceptorDemo"/>
        </mvc:interceptor>
        ...
    </mvc:interceptors>

二、执行流程

1、单个拦截器

首先执行拦截器中的preHandle()方法,如果返回true,将继续执行,否则终止执行。在控制器Controller类处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应,在DispatcherServlet处理完请求后执行afterCompletion()方法

创建HelloController  ——>  创建CustomInterceptor  ——>  编辑springmvc-config.xml  ——>  创建success.jsp并测试

@Controller
public class HelloController {
    //页面跳转
    @RequestMapping("/hello")
    public String Hello() {
        System.out.println("hello!");
        return "success";
    }
}
public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--指定需要扫描的包-->
    <context:component-scan base-package="com.jc.controller"/>
    <!--定义视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--设置前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--设置后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--配置拦截器-->
    <mvc:interceptors>
        <!--拦截所有请求-->
        <bean class="com.jc.Interceptro.CustomInterceptor"/>
    </mvc:interceptors>
</beans>
<%--
  Created by IntelliJ IDEA.
  User: jiangchao
  Date: 2021/4/12
  Time: 上午 10:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>My JSP '' starting page</title>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>

<body>
This is my JSP page. <br>
ok
</body>
</html>

2、多个拦截器

创建Interceptor1 ——>  创建Interceptor2  ——>  修改springmvc-config.xml  ——>运行测试

public class Interceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle1");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle1");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion1");
    }
}
public class Interceptro2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle2");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle2");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion2");
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--指定需要扫描的包-->
    <context:component-scan base-package="com.jc.controller"/>
    <!--定义视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--设置前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--设置后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--配置拦截器-->
    <mvc:interceptors>
        <!--拦截器1-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.jc.Interceptro.Interceptor1"/>
        </mvc:interceptor>
        <!--拦截器2-->
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean class="com.jc.Interceptro.Interceptro2"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

三、案例——用户登录权限验证

只有登录后的用户才能访问系统中的主页,没有登录直接访问的拦截器会将请求拦截,并转发到登录页面,同时在登录页面给出提示信息,如果密码错误同样会给出提示信息。点击退出时,会返回到登录页面。

导入maven依赖  ——>  创建User  ——>  创建UserController  ——>  创建LoginInterceptor  ——>  创建springmvc-config.xml  ——>  编辑web.xml  ——>  创建main.jsp  ——>  创建login.jsp  ——>  测试

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- Spring dao依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- Spring web依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- Spring test依赖:方便做单元测试和集成测试 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>
    <!--servlet依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.8.RELEASE</version>
    </dependency>
    <!--json-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.7.4</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.7.4</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.7.4</version>
    </dependency>
  </dependencies>
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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
@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 session) {
        //获取用户名和密码
        String username = user.getUsername();
        String password = user.getPassword();
        //模拟从数据库中获取用户名和密码进行判断
        if (username != null && username.equals("jiangchao") && password != null && password.equals("1234")) {
            //将用户对象添加到session
            session.setAttribute("user",user);
            //重定向到主页的跳转方法
            return "redirect:main";
        }
        model.addAttribute("msg","用户名或密码错误,请重新登录!");
        return "login";
    }
    //向用户主页面跳转
    @RequestMapping(value = "/main")
    public String toMain() {
        return "main";
    }
    //退出登录
    @RequestMapping(value = "/logout")
    public String logout(HttpSession session) {
        //清除session
        session.invalidate();
        //重定向到登录页面的跳转方法
        return "redirect:login";
    }
}
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 = (User) session.getAttribute("user");
        //判断session中是否有用户数据,如果有,则返回true,继续向下执行
        if (user != 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 {

    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--指定需要扫描的包-->
    <context:component-scan base-package="com.jc.controller"/>
    <!--定义视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--设置前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--设置后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--配置拦截器-->
    <mvc:interceptors>
        <!--拦截器1-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.jc.Interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
 <display-name>Archetype Created Web Application</display-name>
 <!--配置编码过滤器-->
 <filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <servlet>
  <!--配置前端过滤器-->
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <!--初始化时加载配置文件-->
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:springmvc-config.xml</param-value>
  </init-param>
  <!--表示容器在启动时立即加载Servlet-->
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <!--拦截所有url-->
  <url-pattern>/</url-pattern>
 </servlet-mapping>
 </web-app>
<%--
  Created by IntelliJ IDEA.
  User: jiangchao
  Date: 2021/4/13
  Time: 下午 12:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>系统主页</title>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>

<body>
<%@ page isELIgnored="false" %>
当前用户:${user.username}
<a href="${pageContext.request.contextPath }/logout">退出</a>
</body>
</html>
<%--
  Created by IntelliJ IDEA.
  User: jiangchao
  Date: 2021/4/13
  Time: 下午 12:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>用户登录</title>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>

<body>
<%@ page isELIgnored="false" %>
${msg}
<form action="${pageContext.request.contextPath }/login" method="post">
    用户名:<input type="text" name="username"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit" value="登录"/>
</form>

</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值