Spring MVC拦截器详解
浅谈SpringMVC中Interceptor和Filter区别
浅谈SpringMVC中Interceptor和Filter区别Interceptor主要作⽤:拦截⽤户请求,进⾏处理,⽐如判断⽤户登录情况、权限验证,只要针对Controller请求进⾏处理,是通过HandlerInterceptor。
Interceptor分两种情况,⼀种是对会话的拦截,实现spring的HandlerInterceptor接⼝并注册到mvc的拦截队列中,其中preHandle()⽅法在调⽤Handler之前进⾏拦截(上图步骤3),postHandle()⽅法在视图渲染之前调⽤(上图步骤5),afterCompletion()⽅法在返回相应之前执⾏;另⼀种是对⽅法的拦截,需要使⽤@Aspect注解,在每次调⽤指定⽅法的前、后进⾏拦截。
Filter主要作⽤:过滤字符编码、做⼀些业务逻辑判断,主要⽤于对⽤户请求进⾏预处理,同时也可进⾏逻辑判断。
Filter在请求进⼊servlet容器执⾏service()⽅法之前就会经过filter过滤(上图步骤1),不像Intreceptor⼀样依赖于springmvc框架,只需要依赖于servlet。
Filter启动是随WEB应⽤的启动⽽启动,只需要初始化⼀次,以后都可以进⾏拦截。
Filter有如下⼏个种类:⽤户授权Filter:检查⽤户请求,根据请求过滤⽤户⾮法请求;⽇志Filter:记录某些特殊的⽤户请求;解码Filter:对⾮标准编码的请求解码。
Filter和Interceptor的区别1. Filter是基于函数回调(doFilter()⽅法)的,⽽Interceptor则是基于Java反射的(AOP思想)。
2. Filter依赖于Servlet容器,⽽Interceptor不依赖于Servlet容器。
3. Filter对⼏乎所有的请求起作⽤,⽽Interceptor只能对action请求起作⽤。
4. Interceptor可以访问Action的上下⽂,值栈⾥的对象,⽽Filter不能。
关于Spring MVC拦截器的简介以及使用
关于Spring MVC拦截器的简介以及使用作者:陶艳芳来源:《知音励志·社科版》2017年第01期摘要Spring MVC拦截器作为Spring MVC中的一部分,在实际工作中得到广泛的应用,在项目中合理使用拦截器,可以解决许多常见的问题,本文主要会简单概述什么是Spring MVC拦截器,如何通过代码的方式来配置拦截器,使用拦截器的场景,最后就是简述拦截器与过滤器的对比,通过详细的描述,你会对Spring MVC中拦截器的使用会有更深刻的理解。
【关键词】拦截器;Spring MVC;过滤器1 什么是拦截器在了解拦截器之前,我们首先要了解一些基本知识。
我们都知道,当我们在浏览器中输入URL地址的时候,作为客户端的浏览器就会向对应的服务器发送一个请求,同时,浏览器中的Burl地址通过各种get或者post的方式向服务器提交数据,服务器在得到这些数据前,如果我们想对数据进行修改或者配置,那么这个时候我们就需要使用到拦截器,简单来说,拦截器就像海关,如果你携带的东西不合标准,就扣下,符合了标准,才会让你通行。
拦截器在Spring MVC中处理字符编码和权限管理的时候有很大的作用。
2 拦截器的工作原理要想了解拦截器的工作原理,我们首先要对Spring MVC的整体工作流程有了解,下面我就简单介绍Spring MVC的工作流程,在最新版的Spring MVC中,工作流程如下:当用户在浏览器地址栏输入一个Burl请求的时候,该请求首先会找到配置文件中的DispatcherServlet,如果你没有配置,那么此时会报错,如果配置好了,那么下一步就是找到HandlerMapping来找到对应的HandlerAdapter,这样能找到你自己写好的Handler,这里的Handler指的就是你用来处理该请求的类,当然,你可以通过注解的方式来配置。
在这个Handler中,返回对象会是一个ModelAndView对象,这其中的Model表示的就是处理这个url请求得到的数据结果,这里的View就是服务器返回给该请求的响应界面,这样Spring MVC框架就会携带数据到对应的界面,从而展示结果给该URL请求。
SpringMVC--拦截器、异常处理器、全注解开发、SpringMVC执行流程
SpringMVC--拦截器、异常处理器、全注解开发、SpringMVC执⾏流程⼗、拦截器1、拦截器的配置SpringMVC中的拦截器⽤于拦截控制器⽅法的执⾏SpringMVC中的拦截器需要实现HandlerInterceptorSpringMVC的拦截器必须在SpringMVC的配置⽂件中进⾏配置:2、拦截器的三个抽象⽅法SpringMVC中的拦截器有三个抽象⽅法:preHandle:控制器⽅法执⾏之前执⾏preHandle(),其boolean类型的返回值表⽰是否拦截或放⾏,返回true为放⾏,即调⽤控制器⽅法;返回false表⽰拦截,即不调⽤控制器⽅法postHandle:控制器⽅法执⾏之后执⾏postHandle()afterComplation:处理完视图和模型数据,渲染视图完毕之后执⾏afterComplation()3、多个拦截器的执⾏顺序a>若每个拦截器的preHandle()都返回true此时多个拦截器的执⾏顺序和拦截器在SpringMVC的配置⽂件的配置顺序有关:preHandle()会按照配置的顺序执⾏,⽽postHandle()和afterComplation()会按照配置的反序执⾏b>若某个拦截器的preHandle()返回了falsepreHandle()返回false和它之前的拦截器的preHandle()都会执⾏,postHandle()都不执⾏,返回false的拦截器之前的拦截器的afterComplation()会执⾏⼗⼀、异常处理器1、基于配置的异常处理SpringMVC提供了⼀个处理控制器⽅法执⾏过程中所出现的异常的接⼝:HandlerExceptionResolver HandlerExceptionResolver接⼝的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolverSpringMVC提供了⾃定义的异常处理器SimpleMappingExceptionResolver,使⽤⽅式:2、基于注解的异常处理⼗⼆、注解配置SpringMVC使⽤配置类和注解代替web.xml和SpringMVC配置⽂件的功能1、创建初始化类,代替web.xml在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接⼝的类,如果找到的话就⽤它来配置Servlet容器。
springbootspringmvc拦截器拦截POST、PUT、DELETE请求参数和响。。。
springbootspringmvc拦截器拦截POST、PUT、DELETE请求参数和响。
1.操作⽇志实体类@Document(collection = "operation_log")@Getter@Setter@ToStringpublic class OperationLog extends BaseEntityWithId {private String userId; // 操作⼈private String resource; // 操作的资源private String requestMethod; // 请求⽅式private String beanName; // 操作的类private String methodName; // 操作的模块private String requestParams; // 请求的参数private String responseData; // 返回数据}2.拦截器package com.vian.admin.config;import com.alibaba.fastjson.JSON;import com.vian.admin.entity.OperationLog;import com.vian.admin.event.OperationLogEvent;import com.vian.core.configuration.event.EventPublisher;import com.vian.microservice.security.SecurityUtils;import lombok.extern.slf4j.Slf4j;import ng.JoinPoint;import ng.annotation.AfterReturning;import ng.annotation.Aspect;import ng.annotation.Before;import ng.annotation.Pointcut;import org.springframework.beans.factory.annotation.Autowired;import ponent;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;@Aspect@Component@Slf4jpublic class RequestLogAspect {@Autowired private EventPublisher eventPublisher;private ThreadLocal<OperationLog> logThreadLocal = new ThreadLocal<>();//拦截web下所有⽅法@Pointcut("execution(* com.vian.admin.web..*.*(..))")public void pointcut() {("拦截请求start");}@Before("pointcut()")public void doBefore(JoinPoint joinPoint) {ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String beanName = joinPoint.getSignature().getDeclaringTypeName();String methodName = joinPoint.getSignature().getName();String uri = request.getRequestURI();String userId = SecurityUtils.getCurrentUserId();//get⽅法不记录⽇志if ("GET".equals(request.getMethod())) {return;}//请求参数Object[] paramsArray = joinPoint.getArgs();("请求⽇志拦截:userId={}, uri={}, method={}, request={}",userId,uri,request.getMethod(),paramsArray);// 组装⽇志数据OperationLog optLog = new OperationLog();optLog.setUserId(userId);optLog.setResource(uri);optLog.setRequestMethod(request.getMethod());optLog.setBeanName(beanName);optLog.setMethodName(methodName);optLog.setRequestParams(argsArrayToString(paramsArray));logThreadLocal.set(optLog);}@AfterReturning(returning = "result", pointcut = "pointcut()") public void doAfterReturning(Object result) {try {// 处理完请求,从线程变量中获取⽇志数据,并记录到dbOperationLog optLog = logThreadLocal.get();if (null != optLog) {optLog.setResponseData(JSON.toJSONString(result));eventPublisher.publish(new OperationLogEvent(this, optLog)); }} catch (Exception e) {log.error("***操作请求⽇志记录失败doAfterReturning()***", e); } finally {// 清除threadlocallogThreadLocal.remove();}}/*** 请求参数拼装** @param paramsArray* @return*/private String argsArrayToString(Object[] paramsArray) {String params = "";if (paramsArray != null && paramsArray.length > 0) {for (int i = 0; i < paramsArray.length; i++) {Object jsonObj = JSON.toJSON(paramsArray[i]);params += jsonObj.toString() + " ";}}return params.trim();}}测试结果:。
黑马程序员springmvc教程第二天:拦截器(1)
拦截器拦截定义定义拦截器,实现HandlerInterceptor接口。
接口中提供三个方法。
publicclass HandlerInterceptor1implements HandlerInterceptor { //进入 Handler方法之前执行//用于身份认证、身份授权//比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行@Overridepublicboolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {//return false表示拦截,不向下执行//return true表示放行returnfalse;}//进入Handler方法之后,返回modelAndView之前执行//应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图@Overridepublicvoid postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception { }//执行Handler完成执行此方法//应用场景:统一异常处理,统一日志处理@Overridepublicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {}}拦截器配置针对HandlerMapping配置springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。
springmvc-机制(拦截器、aop、异常)
◆Spring-mvc知识➢概念Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
图1 Spring Web MVC核心架构图理解这张图之前我们得先知道以下的几个名词:前端控制器(DispatcherServlet)、请求到处理器映射(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)、处理器或页面控制器(Controller)、验证器(Validator)、命令对象(Command 请求参数绑定到的对象就叫命令对象)、表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)步骤解析:核心架构的具体流程步骤如下:1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;2、DispatcherServlet——>HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;3、DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);5、ModelAndView的逻辑视图名——> ViewResolver,ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;6、View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
JavaEE开发之SpringMVC中的自定义拦截器及异常处理
本文由我司收集整编,推荐下载,如有疑问,请与我司联系JavaEE 开发之SpringMVC 中的自定义拦截器及异常处理上篇博客我们聊了《JavaEE 开发之SpringMVC 中的路由配置及参数传递详解》,本篇博客我们就聊一下自定义拦截器的实现、以及使用ModelAndView 对象将Controller 的值加载到JSTL 上、最后再聊一下异常的捕获处理。
这些在日常开发中都是经常使用的东西。
具体请看下方内容。
一、自定义拦截器顾名思义,拦截器是负责拦截某些东西的工具。
本部分我们创建的拦截器是负责拦截请求的。
这个拦截器类似于高速收费站,只要是想上高速的,都得经过我这个拦截器才可以。
也就是说,接下来我们所创建的拦截器就类似于收费站的作用、所有的用户请求都会经过我们这个拦截器。
废话少说,接下来我们就来创建一个拦截器,并部署到我们的Spring 中。
1、自定义拦截器的创建接下来我们就要创建自定义拦截器了,首先我们创建一个Java 类,命名为CustomInterceptor。
因为我们要创建的是Spring 中的拦截器,因此要继承与springframework 中的HandlerInterceptorAdapter 抽象类。
创建CustomInterceptor 类的过程如下HandlerInterceptorAdapter 是Spring 框架中自定义拦截器的适配器,我们可以看一下HandlerInterceptorAdapter 抽象类的具体实现,下方是我们关联的Spring 框架的源代码中的HandlerInterceptorAdapter 抽象类的实现。
从下方源代码中我们不难看出HandlerInterceptorAdapter 抽象类实现了AsyncHandlerInterceptor 接口,在HandlerInterceptorAdapter 的每个方法中并没有具体实现什么东西,因此我们继承HandlerInterceptorAdapter 后,要对相应的方法进行实现。
SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系
SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系⼀简介(1)过滤器:依赖于servlet容器。
在实现上基于函数回调,可以对⼏乎所有请求进⾏过滤,但是缺点是⼀个过滤器实例只能在容器初始化时调⽤⼀次。
使⽤过滤器的⽬的是⽤来做⼀些过滤操作,获取我们想要获取的数据,⽐如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest 的⼀些参数,包括:过滤低俗⽂字、危险字符等关于过滤器的⼀些⽤法可以参考我写过的这些:(2)拦截器:依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。
在实现上基于的反射机制,属于⾯向切⾯(AOP)的⼀种运⽤。
由于拦截器是基于web框架的调⽤,因此可以使⽤Spring的依赖注⼊(DI)进⾏⼀些业务操作,同时⼀个拦截器实例在⼀个controller⽣命周期之内可以多次调⽤。
但是缺点是只能对controller请求进⾏拦截,对其他的⼀些⽐如直接访问静态资源的请求则没办法进⾏拦截处理关于过滤器的⼀些⽤法可以参考我写过的这些⽂章:⼆多个过滤器与拦截器的代码执⾏顺序如果在⼀个中仅仅只有⼀个拦截器或者过滤器,那么我相信相对来说理解起来是⽐较容易的。
但是我们是否思考过:如果⼀个项⽬中有多个拦截器或者过滤器,那么它们的执⾏顺序应该是什么样的?或者再复杂点,⼀个项⽬中既有多个拦截器,⼜有多个过滤器,这时它们的执⾏顺序⼜是什么样的呢?下⾯我将⽤简单的代码来测试说明:(1)先定义两个过滤器:i)过滤器1:package cn.zifangsky.filter;import java.io.IOException;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.filter.OncePerRequestFilter;public class TestFilter1 extends OncePerRequestFilter {protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {//在DispatcherServlet之前执⾏system.out.println("############TestFilter1 doFilterInternal executed############");filterChain.doFilter(request, response);//在视图页⾯返回给客户端之前执⾏,但是执⾏顺序在Interceptor之后System.out.println("############TestFilter1 doFilter after############");// try {// Thread.sleep(10000);// } catch (InterruptedException e) {// e.printStackTrace();// }}}ii)过滤器2:package cn.zifangsky.filter;import java.io.IOException;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.filter.OncePerRequestFilter;public class TestFilter2 extends OncePerRequestFilter {protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {System.out.println("############TestFilter2 doFilterInternal executed############");filterChain.doFilter(request, response);System.out.println("############TestFilter2 doFilter after############");}}iii)在web.xml中注册这两个过滤器:<!-- ⾃定义过滤器:testFilter1 --><filter><filter-name>testFilter1</filter-name><filter-class>cn.zifangsky.filter.TestFilter1</filter-class></filter><filter-mapping><filter-name>testFilter1</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- ⾃定义过滤器:testFilter2 --><filter><filter-name>testFilter2</filter-name><filter-class>cn.zifangsky.filter.TestFilter2</filter-class></filter><filter-mapping><filter-name>testFilter2</filter-name><url-pattern>/*</url-pattern></filter-mapping>2)再定义两个拦截器:i)拦截器1,基本拦截器:package cn.zifangsky.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class BaseInterceptor implements HandlerInterceptor{/*** 在DispatcherServlet之前执⾏* */public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("************BaseInterceptor preHandle executed**********");return true;}/*** 在controller执⾏之后的DispatcherServlet之后执⾏* */public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {System.out.println("************BaseInterceptor postHandle executed**********");}/*** 在页⾯渲染完成返回给客户端之前执⾏* */public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {System.out.println("************BaseInterceptor afterCompletion executed**********");// Thread.sleep(10000);}}ii)指定controller请求的拦截器:package cn.zifangsky.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class TestInterceptor implements HandlerInterceptor {public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("************TestInterceptor preHandle executed**********");return true;}public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {System.out.println("************TestInterceptor postHandle executed**********");}public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {System.out.println("************TestInterceptor afterCompletion executed**********");}}iii)在SpringMVC的中注册这两个拦截器:<!-- 拦截器 --><mvc:interceptors><!-- 对所有请求都拦截,公共拦截器可以有多个 --><bean name="baseInterceptor" class="cn.zifangsky.interceptor.BaseInterceptor"/><!-- <bean name="testInterceptor" class="cn.zifangsky.interceptor.TestInterceptor" /> --><mvc:interceptor><!-- 对/test.html进⾏拦截 --><mvc:mapping path="/test.html"/><!-- 特定请求的拦截器只能有⼀个 --><bean class="cn.zifangsky.interceptor.TestInterceptor"/></mvc:interceptor></mvc:interceptors>(3)定义⼀个测试使⽤的controller:package cn.zifangsky.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controllerpublic class TestController {@RequestMapping("/test.html")public ModelAndView handleRequest(){System.out.println("---------TestController executed--------");return new ModelAndView("test");}}4)视图页⾯test.jsp:<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><base href="/7311475/"><title>FilterDemo</title></head><body><%System.out.println("test.jsp is loading");%><div align="center">This is test page</div></body></html>5)测试效果:启动此测试项⽬,可以看到控制台中输出如下:这就说明了过滤器的运⾏是依赖于servlet容器的,跟springmvc等框架并没有关系。
基于SpringMVC拦截器和注解实现controller中访问权限控制
基于SpringMVC拦截器和注解实现controller中访问权限控制SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion⽅法。
1. preHandle在业务处理器处理请求之前被调⽤;2. postHandle在业务处理器处理请求执⾏完成后,⽣成视图之前执⾏;3. afterCompletion在DispatcherServlet完全处理完请求后被调⽤,可⽤于清理资源等;所以要想实现⾃⼰的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个⽅法。
⼀、⾃定义拦截器配置⽅法1. 在sping的xml配置中可以⽤<mvc:interceptors>和<mvc:interceptor>来配置拦截器类(实现HandlerInterceptorAdapter)2. 在javaConfig中配置通过WebMvcConfiguration的实现类配置拦截器类(实现HandlerInterceptorAdapter)⼆、⽰例2.1、javaconfig中配置SpringMVC⽰例1、新建⼀个springboot项⽬auth-demo22、权限校验相关的注解package com.dxz.authdemo2.web.auth;import ng.annotation.ElementType;import ng.annotation.Retention;import ng.annotation.RetentionPolicy;import ng.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Permission {/** 检查项枚举 */PermissionEnum[] permissionTypes() default {};/** 检查项关系 */RelationEnum relation() default RelationEnum.OR;}package com.dxz.authdemo2.web.auth;import java.io.PrintWriter;import ng.annotation.Annotation;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;import ponent;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;/*** 权限检查拦截器*/@Componentpublic class PermissionCheckInterceptor extends HandlerInterceptorAdapter {/** 权限检查服务 */@Autowiredprivate PermissionCheckProcessor permissionCheckProcessor;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//Class<?> clazz = handler.getClass();Class<?> clazz = ((HandlerMethod)handler).getBeanType();System.out.println("PermissionCheckInterceptor.preHandle()" + clazz);for(Annotation a : clazz.getAnnotations()){System.out.println(a);}if (clazz.isAnnotationPresent(Permission.class)) {Permission permission = (Permission) clazz.getAnnotation(Permission.class);return permissionCheckProcessor.process(permission, request, response);}return true;}public boolean preHandle2(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("SecurityInterceptor:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod()); HttpSession session = request.getSession();if (session.getAttribute("uid") == null) {System.out.println("AuthorizationException:未登录!"+request.getMethod());if("POST".equalsIgnoreCase(request.getMethod())){response.setContentType("text/html; charset=utf-8");PrintWriter out = response.getWriter();out.write("未登录!");out.flush();out.close();}else{response.sendRedirect(request.getContextPath()+"/login");}return false;} else {return true;}}}package com.dxz.authdemo2.web.auth;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import ponent;@Componentpublic class PermissionCheckProcessor {public boolean process(Permission permission, HttpServletRequest request, HttpServletResponse response) {PermissionEnum[] permissionTypes = permission.permissionTypes();try {String uid = request.getParameter("uid");if ("duanxz".equals(uid)) {System.out.println("认证成功");return true;} else {System.out.println("认证失败");return false;}} catch (Exception e) {return false;}}}package com.dxz.authdemo2.web.auth;public enum PermissionEnum {DEVELOPER_VALID, DEVELOPER_FREEZE;}package com.dxz.authdemo2.web.auth;public enum RelationEnum {OR, AND;}3、SpringMVC拦截器配置package com.dxz.authdemo2.web.auth;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class WebMvcConfiguration extends WebMvcConfigurerAdapter {@AutowiredPermissionCheckInterceptor permissionCheckInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// addPathPatterns ⽤于添加拦截规则// excludePathPatterns ⽤户排除拦截// 映射为 user 的控制器下的所有映射registry.addInterceptor(permissionCheckInterceptor).addPathPatterns("/admin/*").excludePathPatterns("/index", "/");super.addInterceptors(registry);}}4、测试controllerpackage com.dxz.authdemo2.web;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.servlet.ModelAndView;import com.dxz.authdemo2.web.auth.Permission;import com.dxz.authdemo2.web.auth.PermissionEnum;@Controller@RequestMapping("/admin")@Permission(permissionTypes = { PermissionEnum.DEVELOPER_VALID })public class AppDetailController {@RequestMapping(value="/appDetail", method = RequestMethod.GET)public String doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) { //1. 业务操作,此处省略System.out.println("appDetail.htm 处理中...");return "appDetail";}}package com.dxz.authdemo2.web;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import com.dxz.authdemo2.web.auth.Permission;import com.dxz.authdemo2.web.auth.PermissionEnum;@Controller@RequestMapping("index")public class IndexController {@RequestMapping(method = RequestMethod.GET)public void doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {System.out.println("index");}}cotroller中的jsp⽂件appDetail.jsp<html><h1>appDetail</h1></html>启动类:package com.dxz.authdemo2;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.view.InternalResourceViewResolver;@EnableWebMvc@EnableAutoConfiguration@SpringBootApplicationpublic class AuthDemo2Application {public static void main(String[] args) {SpringApplication.run(AuthDemo2Application.class, args);}// 配置JSP视图解析器@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/");resolver.setSuffix(".jsp");return resolver;}}结果:访问:访问:2.2、xml中配置SpringMVC⽰例⾸先在springmvc.xml中加⼊⾃⼰定义的拦截器我的实现逻辑PermissionCheckInterceptor,如下:<!--配置拦截器, 多个拦截器,顺序执⾏ --><mvc:interceptors><mvc:interceptor><!-- 匹配的是url路径,如果不配置或/**,将拦截所有的Controller --><mvc:mapping path="/" /><mvc:mapping path="/user/**" /><mvc:mapping path="/test/**" /><bean class="com.dxz.authdemo2.web.auth.PermissionCheckInterceptor"></bean></mvc:interceptor><!-- 当设置多个拦截器时,先按顺序调⽤preHandle⽅法,然后逆序调⽤每个拦截器的postHandle和afterCompletion⽅法 --> </mvc:interceptors>。
详解SpringMVC
详解SpringMVC HandlerInterceptor拦截器的使⽤与参数⽬录拦截器概念:拦截器VS过滤器⾃定义拦截器开发过程:拦截器配置项:多拦截器配置:拦截器概念:拦截器( Interceptor)是⼀种动态拦截⽅法调⽤的机制,请求处理过程解析核⼼原理: AOP思想拦截器链:多个拦截器按照⼀定的顺序,对原始被调⽤功能进⾏增强作⽤:在指定的⽅法调⽤前后执⾏预先设定后的的代码阻⽌原始⽅法的执⾏拦截器VS过滤器归属不同:过滤器属于Servlet技术,拦截器属于SpringMVC技术拦截内容不同:过滤器对所有访问进⾏增强,拦截器仅针对SpringMVC的访问进⾏增强拦截器执⾏流程:⾃定义拦截器开发过程:实现HandlerInterceptor接⼝//⾃定义拦截器需要实现HandleInterceptor接⼝public class MyInterceptor implements HandlerInterceptor {//前置处理⽅法:原始⽅法之前执⾏@Overridepublic boolean preHandle(HttpServletRequest request, //请求对象HttpServletResponse response, //响应对象Object handler) // 被调⽤的处理器对象,本质是⼀个⽅法对象,对反射中的Method对象进⾏了再包装,对⽅法进⾏封装加强,操作原始对象, throws Exception {System.out.println("前置运⾏");//返回值为false将拦截原始处理器的运⾏,也就是是否放⾏,如果是false后⾯的代码不会运⾏,如果是true就继续执⾏下⾯的代码//如果配置多拦截器,返回值为false将终⽌当前拦截器后⾯配置的拦截器的运⾏return true;}//后置处理⽅法:原始⽅法运⾏后运⾏,如果原始⽅法被拦截,则不执⾏@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) // 如果处理器执⾏完成具有返回结果,可以读取到对应数据与页⾯信息进⾏调整throws Exception {System.out.println("后置运⾏");}// 完成处理⽅法:拦截器最后执⾏的⽅法,⽆论原始⽅法是否执⾏@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) // 如果处理器执⾏过程中出现异常对象,可以针对异常情况进⾏单独处理throws Exception {System.out.println("完成运⾏");}//三个⽅法的运⾏顺序为 preHandle -> postHandle -> afterCompletion//如果preHandle返回值为false,三个⽅法仅运⾏preHandle}拦截器配置项:<mvc:interceptors><!--开启具体的拦截器的使⽤,可以配置多个--><mvc:interceptor><!--设置拦截器的拦截路径,⽀持*通配--><!--/** 表⽰拦截所有映射--><!--/* 表⽰拦截所有/开头的映射--><!--/user/* 表⽰拦截所有/user/开头的映射--><!--/user/add* 表⽰拦截所有/user/开头,且具体映射名称以add开头的映射--><!--/user/*All 表⽰拦截所有/user/开头,且具体映射名称以All结尾的映射--><mvc:mapping path="/*"/><mvc:mapping path="/**"/><mvc:mapping path="/handleRun*"/><!--设置拦截排除的路径,配置/**或/*,达到快速配置的⽬的--><mvc:exclude-mapping path="/b*"/><!--指定具体的拦截器类 bean标签(ref标签)只能配置⼀个ref:引⽤bean的 --><bean class="com.itzhuzhu.interceptor.MyInterceptor"/></mvc:interceptor></mvc:interceptors>多拦截器配置:运⾏顺序:配置在前,则执⾏在前。
详解Spring拦截器流程及多个拦截器的执行顺序
详解Spring拦截器流程及多个拦截器的执⾏顺序⽬录拦截器的定义测试拦截器多个拦截器的执⾏顺序让 preHandle 进⾏拦截总结拦截器是 Spring MVC 中的组件,它可以在进⼊请求⽅法前做⼀些操作,也可以在请求⽅法后和渲染视图后做⼀些事情。
拦截器的定义SpringMVC 的拦截器只需要实现 HandlerInterceptor 接⼝,并进⾏配置即可。
HandlerInterceptor 接⼝的定义如下:public interface HandlerInterceptor {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 {}}在 HandlerInterceptor 中共有三个⽅法,每个⽅法的含义如下:preHandler:进⼊请求⽅法之前执⾏;postHandler:请求⽅法执⾏完成之后执⾏;afterCompletion:视图渲染后执⾏。
拦截器的执⾏流程在 preHandle ⽅法中,它的返回值是 boolean 类型的,它的返回值影响着请求⽅法,以及 postHandle 和 afterCompletion 的执⾏。
详解SpringMVC拦截器配置及使用方法
详解SpringMVC拦截器配置及使⽤⽅法本⽂介绍了SpringMVC拦截器配置及使⽤⽅法,分享给⼤家,具体如下:常见应⽤场景1、⽇志记录:记录请求信息的⽇志,以便进⾏信息监控、信息统计、计算PV(Page View)等。
2、权限检查:如登录检测,进⼊处理器检测检测是否登录,如果没有直接返回到登录页⾯;3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进⼊处理器之前记录开始时间,在处理完后记录结束时间,从⽽得到该请求的处理时间(如果有反向代理,如apache可以⾃动记录);4、通⽤⾏为:读取cookie得到⽤户信息并将⽤户对象放⼊请求,从⽽⽅便后续流程使⽤,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使⽤拦截器实现。
5、OpenSessionInView:如Hibernate,在进⼊处理器打开Session,在完成后关闭Session。
本质也是AOP(⾯向切⾯编程),也就是说符合横切关注点的所有功能都可以放⼊拦截器实现。
配置⽂件定义两个拦截器 HandleInterceptor1 , HandleInterceptor2<!-- 拦截器多个按顺序拦截 --><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.xwx.interceptor.HandleInterceptor1"></bean></mvc:interceptor><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.xwx.interceptor.HandleInterceptor2"></bean></mvc:interceptor></mvc:interceptors>使⽤⽅法preHandle 在Handle执⾏前执⾏return true 继续执⾏ false不继续执⾏在modelAndView 执⾏前执⾏在 Handle 执⾏后执⾏HandleInterceptor1 .javapackage com.xwx.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class HandleInterceptor1 implements HandlerInterceptor {public static Logger log = Logger.getLogger(HandleInterceptor1.class.getName());/*** 在Handle执⾏前执⾏* return true 继续执⾏ false不继续执⾏*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {("HandleInterceptor1 ...... preHandle");return true;}/*** 在modelAndView 执⾏前执⾏*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {("HandleInterceptor1 ...... postHandle");}/*** 在 Handle 执⾏后执⾏*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {("HandleInterceptor1 ...... afterCompletion");}}HandleInterceptor2 .javapackage com.xwx.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class HandleInterceptor2 implements HandlerInterceptor {public static Logger log = Logger.getLogger(HandleInterceptor2.class.getName());/*** 在Handle执⾏前执⾏* return true 继续执⾏ false不继续执⾏*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {("HandleInterceptor2 ...... preHandle");return false;}/*** 在modelAndView 执⾏前执⾏*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {("HandleInterceptor2 ...... postHandle");}/*** 在 Handle 执⾏后执⾏*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {("HandleInterceptor2 ...... afterCompletion");}}拦截器执⾏顺序preHandle 按顺序执⾏, postHandle afterCompletion 则是逆向执⾏16:08:29,187 INFO HandleInterceptor1:20 - HandleInterceptor1 ...... preHandle16:08:29,187 INFO HandleInterceptor2:20 - HandleInterceptor2 ...... preHandle16:08:29,640 INFO HandleInterceptor2:29 - HandleInterceptor2 ...... postHandle16:08:29,640 INFO HandleInterceptor1:29 - HandleInterceptor1 ...... postHandle16:08:29,706 INFO HandleInterceptor2:38 - HandleInterceptor2 ...... afterCompletion16:08:29,706 INFO HandleInterceptor1:38 - HandleInterceptor1 ...... afterCompletion第⼀个拦截器没通过,不会继续执⾏。
springMVC之mvc:interceptors拦截器的用法
springMVC之mvc:interceptors拦截器的⽤法 1.配置拦截器 在springMVC.xml配置⽂件增加:1 <mvc:interceptors>2 <!-- ⽇志拦截器 -->3 <mvc:interceptor>4 <mvc:mapping path="/**" />5 <mvc:exclude-mapping path="/static/**" />6 <bean class="拦截器java代码路径" />7 </mvc:interceptor>8 </mvc:interceptors> 说明: 1)mvc:mapping 拦截器路径配置 2)mvc:exclude-mapping 拦截器不需要拦截的路径 2、样例:1public class LogsInterceptor extends HandlerInterceptorAdapter {23private static final Logger logger = LoggerFactory.getLogger(LogsInterceptor.class);45private NamedThreadLocal<String> logContext = new NamedThreadLocal<String>("log-id");67 @Autowired8private TLogDao logDao;910/**11 * preHandle⽅法是进⾏处理器拦截⽤的,顾名思义,该⽅法将在Controller处理之前进⾏调⽤,12 * SpringMVC中的Interceptor拦截器是链式的,可以同时存在多个Interceptor,13 * 然后SpringMVC会根据声明的前后顺序⼀个接⼀个的执⾏,14 * ⽽且所有的Interceptor中的preHandle⽅法都会在Controller⽅法调⽤之前调⽤。
spring拦截器(interceptor)简介
spring拦截器(interceptor)简介1. 拦截器⽤途 (1)拦截未登录⽤户直接访问某些链接 (2)拦截⽇志信息 (3)拦截⾮法攻击,⽐如sql注⼊2. 涉及jar、类 (1)spring-webmvc.jar (2)HandlerInterceptor(org.springframework.web.servlet:接⼝)、 AsyncHandlerInterceptor(org.springframework.web.servlet:接⼝)、 HandlerInterceptorAdapter(org.springframework.web.servlet.handler.HandlerInterceptorAdapter:抽象类)3.业务类 (1)实现(implements)实现HandlerInterceptor接⼝或者⼦接⼝ (2)继承(extends)继承HandlerInterceptor接⼝⼦类(抽象类) (3)涉及的⽅法 preHandle、postHandle、afterCompletion4.测试代码LoginInterceptor1public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler throws Exception {2 ("--------preHandle-------" + request.getRequestURI());3 HttpSession session = request.getSession();4 String login_account = String.valueOf(session.getAttribute(CommonConstants.SESSION_KEY+session.getId()));5 if(!request.getRequestURI().contains("/baselogin/")){6 if (StringUtils.isBlank(login_account) || "null".equalsIgnoreCase(login_account)) {7 response.sendRedirect("/baselogin/loginPage.htm");8 return false;9 }10 }11 return true;12 }1314public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception { 15 ("--------postHandle-------" + request.getRequestURI());16 }1718public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {19 ("--------afterCompletion-------" + request.getRequestURI());20 }2122public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {23 ("--------afterConcurrentHandlingStarted-------" + request.getRequestURI());24 }执⾏顺序:preHandle -> controller -> postHandle -> afterCompletion配置:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:context="/schema/context"xmlns:xsi="/2001/XMLSchema-instance" xmlns:aop="/schema/aop"xmlns:p="/schema/p" xmlns:mvc="/schema/mvc"xsi:schemaLocation="/schema/context/schema/context/spring-context-3.2.xsd/schema/beans/schema/beans/spring-beans-3.2.xsd/schema/aop/schema/aop/spring-aop-3.2.xsd/schema/mvc/schema/mvc/spring-mvc-3.2.xsd"><!-- 拦截排除<mvc:interceptors><mvc:interceptor> <mvc:exclude-mapping path=""/> <bean class="org.bighead.interceptor.LoginInterceptor" /> </mvc:interceptor></mvc:interceptors>--><!-- 拦截登录 --><mvc:interceptors><mvc:interceptor><mvc:mapping path="/*/*.htm"/><bean class="org.bighead.interceptor.LoginInterceptor"/></mvc:interceptor></mvc:interceptors><beans>。
Spring-mvc的拦截器和异常通知
Spring-mvc的拦截器和异常通知Interceptor(拦截器)springmvc.xml的配置<!-- 包扫描--><context:component-scan base-package="com"/><!-- 配置拦截器 --><mvc:interceptors><!-- 配置其中⼀个拦截器 --><mvc:interceptor><mvc:mapping path="/hello"/><mvc:mapping path="/hello1"/><!-- ⾃定义拦截器 --><bean class="com.interceptor.MyInterceptor"></bean></mvc:interceptor></mvc:interceptors><mvc:annotation-driven></mvc:annotation-driven>MyInterceptor.java//在执⾏⽬标代码之前执⾏的拦截功能@Overridepublic boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("这是Controller执⾏前的拦截器,顺序:1");//return true 不拦截,reture false或者抛出异常时之后的都不执⾏return true;}//在执⾏⽬标代码之后执⾏的拦截功能@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {System.out.println("这是Controller执⾏后页⾯渲染前的拦截器,顺序:3");}//在⽬标代码执⾏完毕后跳转了指定页⾯//只要preHandle return true时,必定会执⾏@Overridepublic void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {System.out.println("这是页⾯渲染完成后的拦截器,顺序:5");}ExceptionAdvice(异常统⼀处理)springmvc.xml的配置<!-- 配置异常映射处理器 --><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><!-- key代表异常要求添加全类名跳转到的页⾯要卸载双标签的中间 --> <prop key="ng.Exception">forward:/error.jsp</prop><prop key="ng.RuntimeException">forward:/error.jsp</prop><prop key="ng.ArithmeticException">forward:/error.jsp</prop> <prop key="ng.NullPointerException">forward:/error.jsp</prop> </props></property></bean><!-- 放⾏静态资源 --><mvc:default-servlet-handler/>ExceptionAdvice.java@ExceptionHandlerpublic ModelAndView exceptionHandler(Exception e) {System.out.println("Exception异常信息:"+e);ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("forward:/error.jsp"); modelAndView.addObject("exception",e);return modelAndView;}@ExceptionHandlerpublic ModelAndView exceptionHandler(RuntimeException e) { System.out.println("Exception异常信息:"+e);ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("forward:/error.jsp"); modelAndView.addObject("exception",e);return modelAndView;}@ExceptionHandlerpublic ModelAndView exceptionHandler(ArithmeticException e) { System.out.println("Exception异常信息:"+e);ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("forward:/error.jsp"); modelAndView.addObject("exception",e);return modelAndView;}。
handlerinterceptoradapter拦截原理
handlerinterceptoradapter拦截原理HandlerInterceptorAdapter是SpringMVC中的一种拦截器。
它可以在请求处理前和处理后进行拦截,包含了很多强大的功能。
在MVC 框架中,拦截机制是非常重要的,它可以实现不同需求的处理,比如:日志记录、权限检测、字符编码转换、请求性能统计等。
接下来,本文着重介绍HandlerInterceptorAdapter的拦截原理。
第一步:SpringMVC的请求拦截流程在介绍HandlerInterceptorAdapter的拦截原理之前,需要先了解SpringMVC的请求拦截流程。
SpringMVC的请求拦截流程如下:请求 -> DispatcherServlet(前置控制器) -> HandlerMapping(请求映射器) -> HandlerInterceptor(处理器拦截器) -> HandlerAdapter(处理器适配器) -> Controller(控制器) -> HandlerAdapter(处理器适配器) -> HandlerInterceptor (处理器拦截器) -> ViewResolver(视图解析器) -> View(视图)-> DispatcherServlet(前置控制器) -> 响应第二步:在SpringMVC中配置HandlerInterceptorAdapter在SpringMVC中配置HandlerInterceptorAdapter的步骤如下:1. 定义HandlerInterceptorAdapter类并继承HandlerInterceptorAdapter类,比如:public class MyHandlerInterceptorAdapter extends HandlerInterceptorAdapter {//重写了preHandle、postHandle、afterCompletion方法}2. 在springmvc.xml中进行配置,添加如下标签:<!-- 配置HandlerInterceptorAdapter类 --><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**" /><beanclass="com.test.interceptor.MyHandlerInterceptorAdapter"></be an></mvc:interceptor></mvc:interceptors>第三步:HandlerInterceptorAdapter的拦截原理我们可以看到,HandlerInterceptorAdapter的拦截是通过实现HandlerInterceptor接口来实现的。
Springmvc拦截器实现原理解析
Springmvc拦截器实现原理解析概述SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,⽤于对处理器进⾏预处理和后处理。
开发者可以⾃⼰定义⼀些拦截器来实现特定的功能。
过滤器与拦截器的区别:拦截器是AOP思想的具体应⽤。
过滤器servlet规范中的⼀部分,任何java web⼯程都可以使⽤在url-pattern中配置了/*之后,可以对所有要访问的资源进⾏拦截拦截器拦截器是SpringMVC框架⾃⼰的,只有使⽤了SpringMVC框架的⼯程才能使⽤拦截器只会拦截访问的控制器⽅法,如果访问的是jsp/html/css/image/js是不会进⾏拦截的⾃定义拦截器那如何实现拦截器呢?想要⾃定义拦截器,必须实现 HandlerInterceptor 接⼝。
新建⼀个Moudule ,添加web⽀持配置web.xml 和 springmvc-servlet.xml ⽂件编写⼀个拦截器package com.xiaohua.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 MyInterceptor implements HandlerInterceptor {//在请求处理的⽅法之前执⾏//如果返回true执⾏下⼀个拦截器//如果返回false就不执⾏下⼀个拦截器public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {System.out.println("------------处理前------------");return true;}//在请求处理⽅法执⾏之后执⾏public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("------------处理后------------");}//在dispatcherServlet处理后执⾏,做清理⼯作.public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println("------------清理------------");}}在springmvc的配置⽂件中配置拦截器<!--关于拦截器的配置--><mvc:interceptors><mvc:interceptor><!--/** 包括路径及其⼦路径--><!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截--><!--/admin/** 拦截的是/admin/下的所有--><mvc:mapping path="/**"/><!--bean配置的就是拦截器--><bean class="com.xiaohua.interceptor.MyInterceptor"/></mvc:interceptor></mvc:interceptors>编写⼀个Controller,接收请求package com.xiaohua.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;//测试拦截器的控制器@Controllerpublic class InterceptorController {@RequestMapping("/interceptor")@ResponseBodypublic String testFunction() {System.out.println("控制器中的⽅法执⾏了");return "hello";}}前端 index.jsp<a href="${pageContext.request.contextPath}/interceptor" rel="external nofollow" >拦截器测试</a>启动tomcat 测试⼀下!验证⽤户是否登陆(认证⽤户)实现思路有⼀个登陆页⾯,需要写⼀个controller访问页⾯。
springmvc-机制(拦截器、aop、异常)
◆Spring-mvc知识➢概念Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC 也是要简化我们日常Web开发的。
图1 Spring Web MVC核心架构图理解这张图之前我们得先知道以下的几个名词:前端控制器(DispatcherServlet)、请求到处理器映射(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)、处理器或页面控制器(Controller)、验证器(Validator)、命令对象(Command 请求参数绑定到的对象就叫命令对象)、表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)步骤解析:核心架构的具体流程步骤如下:1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;2、DispatcherServlet——>HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;3、DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);5、ModelAndView的逻辑视图名——> ViewResolver,ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;6、View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model 实际是一个Map数据结构,因此很容易支持其他视图技术;7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
springmvc拦截器(定义、配置以及执行流程)
springmvc拦截器(定义、配置以及执⾏流程)⼀、拦截器概念springmvc中的拦截器(interceptor)类似于Servlet中的过滤器(Filter),它主要⽤于拦截⽤户请求并做相应的处理。
在实际项⽬中会经常使⽤到拦截器,例如在购物⽹站中通过拦截器可以拦截未登录的⽤户,禁⽌其购买商品,或者使⽤它来验证已登录⽤户是否有相应的操作权限(即权限验证),记录请求信息的⽇志等应⽤。
所谓拦截器,就是能够在进⾏某个操作之前拦截请求,如果请求符合条件就允许在往下执⾏。
⽐如说,海关就是⼀个拦截器,他拦截进出⼝的货物,如果货物满⾜进出⼝条件,则放⾏,否则就拦截,退回处理。
⼆、拦截器定义和配置使⽤在springmvc中要使⽤拦截器,就需要对拦截器类进⾏定义和配置,通常拦截器类可以通过两种⽅式来定义。
第⼀种通过实现HandleInterceptor接⼝,或者继承HandleInterceptor接⼝的实现类HandleInterceptorAdapter来定义;第⼆种通过实现WebRequestInterceptor接⼝,或继承WebRequestInterceptor接⼝的实现类来定义。
1、拦截器的定义:以实现HandleInterceptor接⼝为例public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//做⼀些操作⽅法返回类型为布尔值return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//做⼀些操作}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//做⼀些操作}}从以上可以看出,⾃定义的拦截器类实现了HandlerInterceptor接⼝,并且实现了接⼝中的三个⽅法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
69.log.debug("=====afterCompletion====");
70.}
71.
72.
73.}
部分配置
Xml代码
1.<propertyname="interceptors">
2.<list>
3.<beanclass="monInterceptor"/>
5.Returning handler method name'test'for lookup path: /Demo/test.html
st-Modified value for [/demo/Demo/test.html] is: -1
7.=====preHandle====
8.=====preHandle2====
17.Forwarding to resource [/Demo/test.jsp] in InternalResourceView'/Demo/test'
18.=====afterCompletion2====
19.=====afterCompletion====
20.Successfully completed request
9.Returning handler method name'test'for lookup path: /Demo/test.html
10.进入到demo的test方法
11.==========postHandle2=========
12.view name : /Demo/test
13.==========postHandle=========
mons.logging.LogFactory;
8.importorg.springframework.beans.factory.InitializingBean;
9.importorg.springframework.web.servlet.ModelAndView;
4.<beanclass="monInterceptor2"/>
5.</list>
6.</property>
实际运行结果(控制台DEBUG输出)
Log代码
1.DispatcherServlet with name'springmvc'processing GET request for [/demo/Demo/test.html]
40.HttpServletResponse response, Object handler)throwsException {
41.log.debug("=====preHandle====");
42.//业务逻辑
43.
44.returntrue;
45.}
46.
47.@Override
48.publicvoidpostHandle(HttpServletRequest request,
26.}
27.
28./**
29.*在Controller方法前进行拦截
30.*如果返回false
31.*从当前拦截器往回执行所有拦截器的afterCompletion方法,再退出拦截器链.
32.*如果返回true
33.*执行下一个拦截器,直到所有拦截器都执行完毕.
34.*再运行被拦截的Controller.
35.*然后进入拦截器链,从最后一个拦截器往回运行所有拦截器的postHandle方法.
36.*接着依旧是从最后一个拦截器往回执行所有拦截器的afterCompletion方法.
37.*/
38.@Override
39.publicbooleanpreHandle(HttpServletRequest request,
49.HttpServletResponse response, Object handler,
50.ModelAndView modelAndView)throwsException {
51.log.debug("==========postHandle=========");
52.
53.if(modelAndView !=null){
10.importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter;
11.
12./**
13.* Spring MVC拦截器
14.* @authorgary
15.*
16.*/
17.publicclassCommonInterceptorextendsHandlerInterceptorAdapterimplementsInitializingBean{
54.String viewName = modelAndView.getViewName();
55.log.debug("view name : "+ viewName);
56.}else{
57.log.debug("view is null");
58.}
59.}
60.
61./**
62.*在Controller方法后进行பைடு நூலகம்截
Spring MVC
1.
packagecom.gary.util.spring;
2.
3.importjavax.servlet.http.HttpServletRequest;
4.importjavax.servlet.http.HttpServletResponse;
5.
mons.logging.Log;
2.Matching patterns for request [/Demo/test.html] are [/Demo/*]
3.URI Template variables for request [/Demo/test.html] are {}
4.Mapping [/Demo/test.html] to HandlerExecutionChain with handler [com.gary.test.controller.DemoController@1ed1dbe] and1interceptor
14.view name : /Demo/test
15.Invoking afterPropertiesSet() on bean with name'/Demo/test'
16.Rendering view [org.springframework.web.servlet.view.JstlView: name'/Demo/test'; URL [/Demo/test.jsp]] in DispatcherServlet with name'springmvc'
63.*当有拦截器抛出异常时,会从当前拦截器往回执行所有拦截器的afterCompletion方法
64.*/
65.@Override
66.publicvoidafterCompletion(HttpServletRequest httpservletrequest,
67.HttpServletResponse httpservletresponse, Object obj,
18.
19.staticLog log = LogFactory.getLog(CommonInterceptor.class);
20.
21./**
22.*在系统启动时执行
23.*/
24.publicvoidafterPropertiesSet()throwsException {
25.log.debug("=======初始化CommonInterceptor拦截器=========");