SpringMVC之拦截器使用

拦截器的介绍

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理,可以通过自定义拦截器来实现特定的功能。

过滤器与拦截器的区别:拦截器是AOP思想的具体应用

过滤器:

  1. servlet规范中的一部分,任何java web工程都可以使用

  2. 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截过滤

拦截器:

  1. 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用

  2. 拦截器只会拦截访问的控制器方法(Controller层被注解@Controller标注的类), 如果访问的是jsp/html/css/image/js是不会进行拦截的

自定义拦截器

  1. SpringMVC实现拦截器必须实现HandleIntercepter接口

  2. 配置web.xml和Springmvc.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--1.注册DispatcherServlet-->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--启动级别-1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <!--/ 匹配所有的请求;(不包括.jsp)-->
        <!--/* 匹配所有的请求;(包括.jsp)-->
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
<!--配置字符编码过滤器-->
    <filter>
        <filter-name>encoding</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>encoding</filter-name>
<!--        /*处理所有请求-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
</web-app>
<?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:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启mvc注解驱动-->
    <mvc:annotation-driven>
<!--        配置json类型编码为UTF-8-->
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
<!--让Spring MVC不处理静态资源-->
    <mvc:default-servlet-handler/>
<!--自动扫描包,让指定包下的注解生效,由SpringIOC容器统一管理 -->
    <context:component-scan base-package="com.chenhui.controller"/>


<!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--    前缀    -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--        后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  1. 编写自定义拦截器类
package com.chenhui.controller.config;

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

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

/**
 * @Auther Sunshine
 * @Date 2021/3/11 21:29
 */
public class MyInterceptor implements HandlerInterceptor {
    
    
    //在业务处理器处理请求之前被调用
    //预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
    //返回值:true表示继续流程(如调用下一个拦截器或处理器);
    //false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
    @Override
    //在请求处理的Controller类方法之前执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("处理前");
        return true;
    }
    //在业务处理器处理请求完成之后,生成视图之前执行
    //后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
    @Override
    //在请求处理方法执行之后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("处理后");
    }
    // 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
    //整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finall
    //但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("清理");
    }
}

  1. 在springmvc.xml配置文件中配置拦截器
<!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!--/** 包括路径及其子路径-->
            <!--/admin/* 拦截的是/admin/下面一个目录的所有路径 , /admin/*/user不会被拦截-->
            <!--/admin/** 拦截的是/admin/下的所有-->

            <!--注册拦截器交给SpringIOC管理-->
            <bean class="com.chenhui.controller.config.MyInterceptor" id="myInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  1. 编写Controller类
@ResponseBody
    @RequestMapping("/interceptor")
    public String interceptor(){
    
    
        System.out.println("interceptor方法执行了");
        return "ok";
    }
  1. 启动Tomcat测试结果:
    在这里插入图片描述
    在这里插入图片描述
    测试二:验证用户是否登录才放行(认证用户)

实现步骤:

  1. 有一个登录页面,需要写一个Controller类访问页面

  2. 登陆页面有一提交表单的动作。需要在controller中处理。判断用户名密码是否正确。如果正确,向session中写入用户信息,返回登陆成功。

  3. 拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面 。

  4. 编写一个登录页面login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
        <form method="get" action="${pageContext.request.contextPath}/user/login">
           用户名: <input type="text" name="username">
           密码: <input type="text" name="password">
            <input type="submit" value="登录">
        </form>
</body>
</html>

  1. 编写一个controller类处理请求
package com.chenhui.controller;

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

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

/**
 * @Auther Sunshine
 * @Date 2021/3/11 22:37
 */
@Controller
@RequestMapping("/user")
public class UserController {
    
    

    //跳转到登陆页面
    @RequestMapping("/goLogin")
    public String goLogin(HttpSession session){
    
    
        //如果session存入了userInfo则证明用户已认证,进入主页
        if (session.getAttribute("userInfo")!=null){
    
    
            return "main";
        }else {
    
    
            //否则跳转到登录页
            return "login";
        }
    }
    //登录表单提交请求
    @RequestMapping("/login")
    public String login(String username, String password, HttpSession session){
    
    
        //向session中存入用户身份信息
        session.setAttribute("userInfo",username);
        //返回登录成功主页面
        return "main";
    }
    //跳转到登录成功主页面
    @RequestMapping("/main")
    public String main(){
    
    
        return "main";
    }
    //退出登录
    @RequestMapping("/goOut")
    public String goOut(HttpServletRequest request){
    
    
        //将用户存入session中的值移除
        HttpSession session = request.getSession();
        session.removeAttribute("userInfo");
        //跳转到登录页面
        return "login";
    }
}

  1. 编写一个登录成功页面的主页面main.jsp
<%--
  Created by IntelliJ IDEA.
  User: LEGION
  Date: 2021/3/11
  Time: 22:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
     ${
    
    userInfo}
    <a href="${pageContext.request.contextPath}/user/goOut">注销</a>
</body>
</html>

  1. 编写用户登录拦截器
package com.chenhui.controller.config;

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

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

/**
 * @Auther Sunshine
 * @Date 2021/3/11 22:38
 */
//拦截器需要实现HandlerInterceptor接口
public class UserInterceptor implements HandlerInterceptor {
    
    

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        //如果请求是/xxxgoLogin则证明去登录页面,不用拦截,放行
        if (request.getRequestURI().contains("goLogin")){
    
    
            return true;
        }
        //如果请求是提交表单请求时,不用拦截,放行,否则用户信息无法通过后台存储用户的session信息
        if (request.getRequestURI().contains("login")){
    
    
            return true;
        }
        //如果用户登录成功后,也不拦截,放行
        if (request.getSession().getAttribute("userInfo")!=null){
    
    
            return true;
        }
        //其他请求用户没有权限,则全部拦截,返回登录页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        return false;
    }


}

  1. 在springMVC的配置文件中注册拦截器
<!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
        <!--配置拦截请求,如果请求路径为/user/**子路径的所有请求都会被拦截器拦截-->
            <mvc:mapping path="/user/**"/>
            <!--将自定义拦截器交给SpringIOC容器管理-->
            <bean class="com.chenhui.controller.config.UserInterceptor" id="userInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  1. 启动Tomcat测试

当访问主页面时,没有登录认证则直接跳转到登录页面

在这里插入图片描述
当登录成功后进入主页

在这里插入图片描述
当注销用户后跳转到登录页面

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45608165/article/details/115182584