Spring Boot 教程: 拦截器

【注】本文译自:https://www.tutorialspoint.com/spring_boot/spring_boot_interceptor.htm

        在以下两种情况下,可以在 Spring Boot 中使用拦截器来执行操作:

发送请求到控制器之前

发送响应到客户端之前

       譬如,可以使用拦截器在发送请求到控制器之前添加请求头,并在发送响应到客户端之前添加响应头。

       要用拦截器,你需要创建 @Component 类,并且要实现 HandlerInterceptor 接口。

       下面是使用拦截器要知道的三个方法:

preHandle() 方法:用于在发送请求到控制器之前执行操作。这个方法应当返回 true 以响应客户端。

postHandle() 方法:用于在发送响应到客户端之前执行操作。

afterCompletion() 方法: 用于在请求和响应完成之后执行操作。

       观察以下代码以加深理解:

@Component

public class ProductServiceInterceptor implements HandlerInterceptor {

   @Override

   public boolean preHandle(

      HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {


      return true;

   }

   @Override

   public void postHandle(

      HttpServletRequest request, HttpServletResponse response, Object handler,

      ModelAndView modelAndView) throws Exception {}


   @Override

   public void afterCompletion(HttpServletRequest request, HttpServletResponse response,

      Object handler, Exception exception) throws Exception {}

}

       还要通过 WebMvcConfigurerAdapter 用 InterceptorRegistry 注册这个拦截器:

@Component

public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {

   @Autowired

   ProductServiceInterceptor productServiceInterceptor;

   @Override

   public void addInterceptors(InterceptorRegistry registry) {

      registry.addInterceptor(productServiceInterceptor);

   }

}

       在下面给出的示例中,我们将要使用后面给出的 GET products API:

       Interceptor 类文件 ProductServiceInterceptor.java 如下所示:

package com.tutorialspoint.demo.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

importorg.springframework.stereotype.Component;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

@Component

public class ProductServiceInterceptor implements HandlerInterceptor {

   @Override

   public boolean preHandle

      (HttpServletRequest request, HttpServletResponse response, Object handler)

      throws Exception {


      System.out.println("Pre Handle method is Calling");

      return true;

   }

   @Override

   public void postHandle(HttpServletRequest request, HttpServletResponse response,

      Object handler, ModelAndView modelAndView) throws Exception {


      System.out.println("Post Handle method is Calling");

   }

   @Override

   public void afterCompletion

      (HttpServletRequest request, HttpServletResponse response, Object

      handler, Exception exception) throws Exception {


      System.out.println("Request and Response is completed");

   }

}

        Application Configuration 类文件把拦截器注册到 Interceptor Registry中,ProductServiceInterceptorAppConfig.java 文件如下:

package com.tutorialspoint.demo.interceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Component

public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {

   @Autowired

   ProductServiceInterceptor productServiceInterceptor;

   @Override

   public void addInterceptors(InterceptorRegistry registry) {

      registry.addInterceptor(productServiceInterceptor);

   }

}

     Controller 类文件 ProductServiceController.java 如下:

package com.tutorialspoint.demo.controller;

import java.util.HashMap;

import java.util.Map;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestBody;

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

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RestController;

import com.tutorialspoint.demo.exception.ProductNotfoundException;

import com.tutorialspoint.demo.model.Product;

@RestController

public class ProductServiceController {

   private static Map<String, Product> productRepo = new HashMap<>();   

   static {      

      Product honey = new Product();

      honey.setId("1");

      honey.setName("Honey");

      productRepo.put(honey.getId(), honey);      

      Product almond = new Product();

      almond.setId("2");

      almond.setName("Almond");

      productRepo.put(almond.getId(), almond);      

   }

   @RequestMapping(value = "/products")

   public ResponseEntity<Object> getProduct() {

      return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);

   }

}

       POJO 类文件 Product.java 如下:

package com.tutorialspoint.demo.model;

public class Product {

   private String id;

   private String name;

   public String getId() {

      return id;

   }

   public void setId(String id) {

      this.id = id;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

}

       主 Spring Boot 应用类文件 DemoApplication.java 如下所示:

package com.tutorialspoint.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class DemoApplication {

   public static void main(String[] args) {

      SpringApplication.run(DemoApplication.class, args);   

   }

}

       Maven build – pom.xml 文件在此:

<?xml version = "1.0" encoding = "UTF-8"?>

<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "

   http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0

   http://maven.apache.org/xsd/maven-4.0.0.xsd">


   <modelVersion>4.0.0</modelVersion>

   <groupId>com.tutorialspoint</groupId>

   <artifactId>demo</artifactId>

   <version>0.0.1-SNAPSHOT</version>

   <packaging>jar</packaging>

   <name>demo</name>

   <description>Demo project for Spring Boot</description>

   <parent>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-parent</artifactId>

      <version>1.5.8.RELEASE</version>

      <relativePath/>

   </parent>

   <properties>

      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

      <java.version>1.8</java.version>

   </properties>

   <dependencies>

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-web</artifactId>

      </dependency>

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-test</artifactId>

         <scope>test</scope>

      </dependency>

   </dependencies>

   <build>

      <plugins>

         <plugin>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-maven-plugin</artifactId>

         </plugin>

      </plugins>

   </build>


</project>

     Gradle Build build.gradle 文件在此:

buildscript {

   ext {

      springBootVersion = '1.5.8.RELEASE'

   }

   repositories {

      mavenCentral()

   }

   dependencies {

      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")

   }

}

apply plugin: 'java'

apply plugin: 'eclipse'

apply plugin: 'org.springframework.boot'

group = 'com.tutorialspoint'

version = '0.0.1-SNAPSHOT'

sourceCompatibility = 1.8

repositories {

   mavenCentral()

}

dependencies {

   compile('org.springframework.boot:spring-boot-starter-web')

   testCompile('org.springframework.boot:spring-boot-starter-test')

}

      你可以使用下面的 Maven 或 Gradle 命令创建可执行的 JAR 文件,运行 Spring Boot 应用:

       对于 Maven,使用以下命令:

mvn clean install

       在 “BUILD SUCCESS” 之后,你可以在 target 目录下找到 JAR 文件:

      对于 Gradle,使用以下命令:

gradle clean build

       在 “BUILD SUCCESSFUL” 之后,你可以在build/libs 目录下找到 JAR 文件:

       可以使用以下命令运行 JAR 文件:

java –jar <JARFILE>

       此时,应用已经在 Tomcat8080 端口启动了,如下所示:

       在 POSTMAN 应用中单击以下 URL,你可以看到下面的结果:

GET API: http://localhost:8080/products

       在控制台窗口,你可以看到加在拦截器中的 System.out.println 打印出来的结果,截屏如下:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,861评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,263评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,033评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,999评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,000评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,483评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,850评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,827评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,366评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,404评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,525评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,130评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,853评论 3 338
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,293评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,426评论 1 276
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,082评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,590评论 2 366