SpringMVC中的拦截器

概述

拦截器:拦截器其实就是一个类

SpringMVC 中的Interceptor拦截器主要用于:拦截指定的请求,并进行相应的预处理与后处理和最终处理。多个拦截器可以组成拦截器链,就是执行完一个拦截器再向下执行下一个拦截器...

拦截器的应用场景

1、日志记录:记录请求信息的日志

2、权限检查,如登录检查(在预处理方法中完成)

3、性能检测:检测方法的执行时间

拦截器的执行原理

实现拦截器的两种方式

1)自定义一个拦截器类继承HandlerInterceptorAdapter的父类

2**)自定义一个拦截器类实现HandlerInterceptor接口(推荐)**

HandlerInterceptor接口分析

该接口中含有三个方法:

(1) preHandle预处理方法

(2) postHandle后处理方法

(3)afterCompletion最终处理方法

HandlerInterceptor接口的源代码:

java 复制代码
package org.springframework.web.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;

public interface HandlerInterceptor {
	//只有预处理方法的返回值是boolean类型:
    //用于在预处理的时候要决定请求是否继续向下执行,返回true请求继续向下执行,
    //返回false,从哪来回哪去
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

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

拦截器中方法的执行时机

1)preHandle():请求被处理之前执行(预处理)

2)postHandle():请求被处理之后执行,但结果还没有渲染前进行操作,可以改变响应结果(后处理)

3)afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源(最终处理)

自定义拦截器来实现权限验证

拦截器的实现步骤:

  • 在判断是否登录的处理器方法中增加操作:如果登录成功,就在Session对象中存储用户信息,表示登录成功
java 复制代码
package com.bjpowernode.controller;

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

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

@Controller
public class WebInfAction {


    @RequestMapping("/showLogin")
    public String showLogin(){
        System.out.println("访问login.jsp");
        return "login";
    }

    //判断是否登录
    @RequestMapping("loginService")
    public String login(String username, String password, HttpServletRequest request){
        if("zar".equalsIgnoreCase(username) && "123".equalsIgnoreCase(password)){
            //如果登录成功,就在Session对象中存储用户信息,表示登录成功
            HttpSession session = request.getSession();
            session.setAttribute("username",username);
            return "main";
        }else {
            request.setAttribute("msg","用户或密码不正确");
            return "login";
        }

    }
}
  • 实现HandlerInterceptor接口,并重写其preHandle()方法
java 复制代码
package com.bjpowernode.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

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

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断是否登录成功过
        if(request.getSession().getAttribute("username") == null){
            //没用登录成功过,返回到登录页面,并给出提示
            request.setAttribute("msg","未登录状态,请登录");
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
            return false;
        }
        return true;
    }
}
  • 在springmvc.xml文件中配置拦截器
XML 复制代码
<?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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!--进行组件扫描-->
	<context:component-scan base-package="com.bjpowernode.controller"/>

	<!--声明视图解析器-->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>

	<!--添加注解驱动标签-->
	<mvc:annotation-driven></mvc:annotation-driven>

	<!--注册拦截器-->
	<mvc:interceptors>
		<mvc:interceptor>
			<!--映射要拦截的请求路径-->
			<mvc:mapping path="/**"/>
			<!--配置不拦截哪些请求路径-->
			<mvc:exclude-mapping path="/showLogin"/>
			<mvc:exclude-mapping path="/loginService"/>
			<!--配置使用哪个拦截器-->
			<bean class="com.bjpowernode.interceptor.LoginInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>

</beans>
相关推荐
立少→万能汉编2 分钟前
用“立少→超文本”写静态网页,标签<倍>
服务器·前端·javascript
weixin_4316004410 分钟前
NestJS 入门(7):生命周期钩子——构造函数和 `OnModuleInit` 差在哪?
前端·后端·学习·node.js·nest.js
小强库计算机毕业设计14 分钟前
基于 Spring Boot + Vue3 的校园管理系统
java·spring boot·后端·项目实战·管理系统·技术分享·校园管理系统实战
霸道流氓气质24 分钟前
Java中信号量(Semaphore):从本地到分布式
java·开发语言·分布式
怪奇云呼军26 分钟前
G.711、Opus 和重采样会拖慢识别吗?闪电智能VoiceAgent 的音频入口怎么选
java·人工智能·python·算法·云计算·音视频
编程令我快乐34 分钟前
maven部分构建参数讲解
java·maven
ZC跨境爬虫39 分钟前
LeetCode 27. 移除元素(双指针详解 + Java Python 多解法对比)
java·python·leetcode
路溪非溪1 小时前
Python语言的执行流程总结
开发语言·python
cindershade1 小时前
用原生 HTML5 视频与 Canvas 实现浏览器端视频抽帧封面
前端
民乐团扒谱机1 小时前
【超详解】量子克拉美罗下界QCRB:时延估计精度极限推导+MATLAB多场景绘图实战
开发语言·机器学习·matlab·量子力学·qcrb