当前位置:网站首页>【无标题】
【无标题】
2022-07-23 01:44:00 【巷口暖风】
拦截器
在系统中,经常需要在处理用户请求之前和之后执行一些行为,例如检测用户的权限,或者将请求的信息记录到日志中,即平时所说的“权限检测”及“日志记录”。当然不仅仅这些,所以需要一种机制,拦截用户的请求,在请求的前后添加处理逻辑。
Spring MVC 提供了 Interceptor 拦截器机制,用于请求的预处理和后处理。
在开发一个网站时可能有这样的需求:某些页面只希望几个特定的用户浏览。对于这样的访问权限控制,应该如何实现呢?拦截器就可以实现上述需求。在 Struts2 框架中,拦截器是其重要的组成部分,Spring MVC 框架也提供了拦截器功能。
Spring MVC 的拦截器(Interceptor)与 Java Servlet 的过滤器(Filter)类似,它主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。
拦截器的定义
在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,主要有以下 2 种方式。
通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类(例如 HandlerInterceptorAdapter)来定义;
通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。
本节以实现 HandlerInterceptor 接口的定义方式为例讲解自定义拦截器的使用方法。示例代码如下。
package net.biancheng.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 {
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle方法在控制器的处理请求方法调用之前执行");
return false;
}
}
上述拦截器的定义中实现了 HandlerInterceptor 接口,并实现了接口中的 3 个方法,说明如下。
preHandle( ):该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。
postHandle( ):该方法在控制器的处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。
afterCompletion( ):该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,可以通过此方法实现一些资源清理、记录日志信息等工作。
拦截器的配置
让自定义的拦截器生效需要在 Spring MVC 的配置文件中进行配置,配置示例代码如下:
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置一个全局拦截器,拦截所有请求 -->
<bean class="net.biancheng.interceptor.TestInterceptor" />
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/**" />
<!-- 配置不需要拦截作用的路径 -->
<mvc:exclude-mapping path="" />
<!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="net.biancheng.interceptor.Interceptor1" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/gotoTest" />
<!-- 定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="net.biancheng.interceptor.Interceptor2" />
</mvc:interceptor>
</mvc:interceptors>
在上述示例代码中,元素说明如下。
<mvc:interceptors>:
该元素用于配置一组拦截器。
:该元素是 mvc:interceptors 的子元素,用于定义全局拦截器,即拦截所有的请求。
mvc:interceptor:该元素用于定义指定路径的拦截器。
mvc:mapping:该元素是 mvc:interceptor 的子元素,用于配置拦截器作用的路径,该路径在其属性 path 中定义。path 的属性值为/**时,表示拦截所有路径,值为/gotoTest时,表示拦截所有以/gotoTest结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 mvc:exclude-mapping 子元素进行配置。
需要注意的是,mvc:interceptor 元素的子元素必须按照 mvc:mapping.../、mvc:exclude-mapping.../、<bean…/> 的顺序配置。
自定义注解
1 注解的概念
1.1 注解的官方定义
首先看看官方对注解的描述:
An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Annotations have no direct effect on the operation of the code they annotate.
翻译:
注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。
通过官方描述得出以下结论:
注解是一种元数据形式。即注解是属于java的一种数据类型,和类、接口、数组、枚举类似。
注解用来修饰,类、方法、变量、参数、包。
注解不会对所修饰的代码产生直接的影响。
1.2 注解的使用范围
继续看看官方对它的使用范围的描述:
Annotations have a number of uses, among them:Information for the complier - Annotations can be used by the compiler to detect errors or suppress warnings.Compiler-time and deployment-time processing - Software tools can process annotation information to generate code, XML files, and so forth.Runtime processing - Some annotations are available to be examined at runtime.
翻译:
注解又许多用法,其中有:为编译器提供信息 - 注解能被编译器检测到错误或抑制警告。编译时和部署时的处理 - 软件工具能处理注解信息从而生成代码,XML文件等等。运行时的处理 - 有些注解在运行时能被检测到。
2 如何自定义注解
基于上一节,已对注解有了一个基本的认识:注解其实就是一种标记,可以在程序代码中的关键节点(类、方法、变量、参数、包)上打上这些标记,然后程序在编译时或运行时可以检测到这些标记从而执行一些特殊操作。因此可以得出自定义注解使用的基本流程:
第一步,定义注解——相当于定义标记;
第二步,配置注解——把标记打在需要用到的程序代码中;
第三步,解析注解——在编译期或运行时检测到标记,并进行特殊操作。
2.1 基本语法
注解类型的声明部分:
注解在Java中,与类、接口、枚举类似,因此其声明语法基本一致,只是所使用的关键字有所不同@interface。在底层实现上,所有定义的注解都会自动继承java.lang.annotation.Annotation接口。
public @interface CherryAnnotation {
}
注解类型的实现部分:
根据我们在自定义类的经验,在类的实现部分无非就是书写构造、属性或方法。但是,在自定义注解中,其实现部分只能定义一个东西:注解类型元素(annotation type element)。咱们来看看其语法:
public @interface CherryAnnotation {
public String name();
int age();
int[] array();
}
也许你会认为这不就是接口中定义抽象方法的语法嘛?别着急,咱们看看下面这个:
public @interface CherryAnnotation {
public String name();
int age() default 18;
int[] array();
}
看到关键字default了吗?还觉得是抽象方法吗?
注解里面定义的是:注解类型元素!
定义注解类型元素时需要注意如下几点:
访问修饰符必须为public,不写默认为public;
该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组;
该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作);
()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
default代表默认值,值必须和第2点定义的类型一致;
如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
可以看出,注解类型元素的语法非常奇怪,即又有属性的特征(可以赋值),又有方法的特征(打上了一对括号)。但是这么设计是有道理的,我们在后面的章节中可以看到:注解在定义好了以后,使用的时候操作元素类型像在操作属性,解析的时候操作元素类型像在操作方法。
边栏推荐
- Leetcode 110. 平衡二叉树
- PNA肽核酸修饰多肽Suc-Ala-Ala-pNA|2-Ala-Ala-LeupNA|Ac-Phe-Gly-PNA
- operator=中自我赋值和异常安全问题
- 【Jailhouse 文章】Virtualization over Multiprocessor System-on-Chip an Enabling Paradigm for...
- 服务器内存性能调优
- PNA肽核酸修饰多肽Z-Gly-Pro-pNA|D-Phe-Pip-Arg-pNA|Tos-Gly-Pro-Arg-pNA
- Understand the box model, and the basic methods of box model's frame, internal and external margins, horizontal layout, vertical layout, setting floating, and dealing with height collapse
- IBM:到2030年实现容错量子优势
- ADAS测试方案
- 申请炒股账户在手机开户安全吗?
猜你喜欢
![[ssm] exception handling](/img/bb/2669d2a3ee725aa4ab8443aed0a8be.png)
[ssm] exception handling

【bug秘史】UINT8数据超出类型范围输出0x0102

IBM:到2030年实现容错量子优势

【C语言】预处理详解

La fosse Piétinée par l'homme vous dit d'éviter les 10 erreurs courantes dans les tests automatisés

MongoDB的CRUD操作(2)

The pit trodden by real people tells you to avoid the 10 mistakes often made in automated testing

xmpp 服务研究(一)

肽核酸PNA规格信息|大豆过氧化酶标记肽核酸(Peptide nucleic acid,PNA)

Cbcgpcolordialog control used by BCG
随机推荐
Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案
肽核酸如何保存|包含偶氮苯单元的肽核酸(N-PNA)|99Tcm标记c-myc mRNA
1057 Stack
肽核酸(PNA)偶联穿膜肽(CCPs)(KFF)3K形成CCPs-PNA|肽核酸的使用方法
【bug 简单处理】
Selenium.webdriver gets the result and converts it to JSON format
Canal Chapter 6
35岁程序员,早到的中年危机
LEADTOOLS 20-22 Crack-DotNetCore!!!
TFW6524完美替代进口PT6524芯片方案简介
我是新手,听说开户有保本的理财产品,是什么?
【HLS】流水线仿真之排队函数的调用
【无标题】
Wallys/DR4019S/IPQ4019/11ABGN/802.11AC/high power
Canal Chapter 5
向后量子密码学迁移!美国NIST公布12家合作伙伴
网络安全基础之DNS与DHCP
[ssm] exception handling
Program environment and pretreatment
AIRIOT答疑第5期|如何使用低代码业务流引擎?