post-image

Spring Boot – Interceptor

REST API Spring Boot Starters & Common Configurations

Khi bạn tới công ty và muốn gặp sếp của công ty đó. Bạn cần phải đi qua các chốt chặn (Interceptor), các chốt chặn ở đây có thể là người bảo vệ cổng, nhân viên lễ tân,..

Trong Spring, khi một request được gửi đến controller, trước khi request được xử lý bởi Controller, nó phải vượt qua các Interceptor (0 hoặc nhiều).

Spring Interceptor là một khái niệm khá giống với Servlet Filter.

Spring Interceptor chỉ áp dụng đối với các request đang được gửi đến một Controller.

Bạn có thể sử dụng Interceptor trong Spring Boot để làm một số việc như:

  • Trước khi gửi request tới Controller.
  • Trước khi gửi response tới Client.
  • Ghi lại Log.

Lớp Interceptor của bạn cần phải thực hiện interface org.springframework.web.servlet.HandlerInterceptor hoặc mở rộng từ lớp org.springframework.web.servlet.handler.HandlerInterceptorAdapter.

Với ví dụ này, bạn có thể sử dụng 1 interceptor để thêm request header trước khi gửi request tới Controller và thêm response header trước khi gửi tới Client.

Để làm việc với Interceptor, bạn cần tạo class @Component và được implement từ interface HandlerInterceptor.

Sau đây là 3 method bạn nên biết khi làm việc với Interceptor:

  • preHandle() method: method này sử dụng để thực hiện các operations trước khi gửi request tới Controller. Method này trả về true rồi trả response cho Client.
  • postHandle() method: method này sử dụng để thực hiện các operations trước khi gửi request tới Client.
  • afterCompletion() method: method này được sử dụng để thực hiện các operations sau khi hoàn thành việc gửi request và response.

Quan sát đoạn code dưới đây để hiểu rõ hơn.

@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 {}
}Code language: PHP (php)

Bạn sẽ phải đăng ký Interceptor này với InterceptorRegistry bằng cách sử dụng WebMvcConfigurerAdapter như hình dưới đây.

@Component
public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {
   @Autowired
   ProductServiceInterceptor productServiceInterceptor;

   @Override
   public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(productServiceInterceptor);
   }
}Code language: CSS (css)

Trong ví dụ dưới đây, chúng ta sẽ GET ra API của product.

Class ProductServiceInterceptor.java.

package com.tutorialspoint.demo.interceptor;

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

import org.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");
   }
}Code language: CSS (css)

File class Application Configuration để đăng ký Interceptor vào Interceptor Register – 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);
   }
}Code language: CSS (css)

File class 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);
   }
}Code language: JavaScript (javascript)

Model Product.

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;
   }
}Code language: JavaScript (javascript)

Hàm main Spring Boot.

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);   
   }
}Code language: JavaScript (javascript)

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>Code language: HTML, XML (xml)

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')
}Code language: JavaScript (javascript)

Bạn có thể tạo file JAR và run Spring Boot bằng cách sử dụng lệnh của Maven hoặc Gradle.

Đối với Maven:

mvn clean install

Sau khi “BUILD SUCCESS”, bạn có thể tìm thấy file JAR trong thư mục đích.

Còn đối với Gradle:

Sau khi “BUILD SUCCESS”, bạn có thể tìm thấy file JAR trong thư mục build/libs.

Run file JAR:

java –jar <JARFILE>Code language: HTML, XML (xml)

Thao tác này sẽ khởi động cổng ứng dụng Tomcat 8080 như hình dưới.

Started Application on Tomcat Port 8080

Paste link http://localhost:8080/products vào POSTMAN, chọn GET rồi gửi request.

POSTMAN Application Get API URL

Trong Console window, bạn có thể thêm các câu lệnh System.out.println trong Interceptor để được hiển thị như hình dưới nhé.

Interceptor Output Console Window

Chúc bạn thành công 😄!

Bài viết được tham khảo từ nguồn:

https://www.tutorialspoint.com/spring_boot/spring_boot_interceptor.htm

Leave a Reply

Your email address will not be published. Required fields are marked *