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>
相关推荐
huali14 小时前
vue-split-screen:让 Vue Router 的导航轨迹变成两个页面
前端·javascript·vue.js
淘源码d15 小时前
基于Java开发的上门家政系统源码,采用SpringBoot+MySQL+UniApp+Vue3技术栈,构建三端一体化平台
java·源码·上门家政·家政系统·同城家政·源码部署
Wang's Blog15 小时前
Java框架快速入门: Spring Security+OAuth2之多因子认证逻辑与实体类改造
java·开发语言·spring
ashiho15 小时前
【Spring】RequestParam/PathVariable/RequestBody详解
java·后端·spring·servlet·springmvc
传奇开心果编程15 小时前
【Rust入门知识点学与练】第26课:Unsafe Rust
开发语言·学习·rust
bug总结15 小时前
uniapp总结
开发语言·前端·javascript
zyeyeye15 小时前
C++入门:从HelloWorld到命名空间揭秘
c语言·开发语言·c++·算法
云运维笔记15 小时前
华为VRP系统文件管理全攻略
前端·华为
励志不掉头发的内向程序员15 小时前
【LibreCAD 2D架构】从 addHistory 到 RS_UndoCycle:LibreCAD 里的两套 History 与撤销机制
开发语言·c++·qt·学习·系统架构
Escalating_xu15 小时前
【mmap 进程间通信】从共享内存到跨进程唤醒:用互斥锁、条件变量控制多个进程
java·linux·开发语言·jvm