Spring Boot – Exception Handling
NỘI DUNG BÀI VIẾT
Xử lý exceptions và errors trong APIs và gửi response cho client là điều tốt cho các ứng dụng của doanh nghiệp. Trong bài viết hôm nay, chúng ta sẽ học cách handle exceptions(xử lý ngoại lệ) trong Spring Boot.
Trước hết, chúng ta nên hiểu về các annotations sau.
Controller Advice
@ControllerAdvice là 1 annotation, dùng để xử lý exceptions globally.
Exception Handler
@ExceptionHandler là 1 annotation dùng để xử lý các specific exceptions và gửi responses cho client.
Bạn có thể sử dụng đoạn code sau để tạo class @ControllerAdvice để xử lý exceptions globally.
package com.tutorialspoint.demo.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
@ControllerAdvice
public class ProductExceptionController {
}
Code language: CSS (css)
Class này được extends class RuntimeException.
package com.tutorialspoint.demo.exception;
public class ProductNotfoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
Code language: PHP (php)
Bạn có thể định nghĩa phương thức @ExceptionHandler để xử lý các exceptions như được hiển thị bên dưới. Phương thức này nên được sử dụng để viết file class Controller Advice.
@ExceptionHandler(value = ProductNotfoundException.class)
public ResponseEntity<Object> exception(ProductNotfoundException exception) {
}
Code language: CSS (css)
Bây giờ, sử dụng code dưới đây để loại bỏ exception khỏi API.
@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
public ResponseEntity<Object> updateProduct() {
throw new ProductNotfoundException();
}
Code language: JavaScript (javascript)
Trong ví dụ này, chúng ta đã sử dụng PUT API để cập nhật sản phẩm. Tại đây, khi update sản phẩm, nếu không tìm thấy sản phẩm, sau đó trả về thông báo lỗi với message là: “Product not found”. Lưu ý rằng ProductNotFoundException phải được extend class RuntimeException.
package com.tutorialspoint.demo.exception;
public class ProductNotfoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
Code language: PHP (php)
Class Controller Advice để xử lý exception globally. Chúng ta cần định nghĩa nhiều method Exception Handler trong class này.
package com.tutorialspoint.demo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class ProductExceptionController {
@ExceptionHandler(value = ProductNotfoundException.class)
public ResponseEntity<Object> exception(ProductNotfoundException exception) {
return new ResponseEntity<>("Product not found", HttpStatus.NOT_FOUND);
}
}
Code language: CSS (css)
Class ProductServiceController được viết dưới đây để cập nhật Product. Nếu Product không tìm thấy, thì nó sẽ throws ném vào class ProductNotFoundException.
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/{id}", method = RequestMethod.PUT)
public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
if(!productRepo.containsKey(id))throw new ProductNotfoundException();
productRepo.remove(id);
product.setId(id);
productRepo.put(id, product);
return new ResponseEntity<>("Product is updated successfully", HttpStatus.OK);
}
}
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)
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)
File 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)
File 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.
Paste link http://localhost:8080/products/3 vào POSTMAN, chọn PUT rồi gửi request.
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_exception_handling.htm
Link GitHub bạn có thể tham khảo nhé: GitHub
Leave a Reply