跳到主要内容 Spring Boot 数据验证与异常处理 | 极客日志
Java java
Spring Boot 数据验证与异常处理 Spring Boot 中的数据验证与异常处理。首先阐述了数据验证和异常处理的定义及作用,随后详细讲解了集成 Spring Validation 的步骤,包括依赖配置、实体类注解及控制器测试。接着介绍了异常处理集成,涵盖自定义异常类、全局异常处理器 ControllerAdvice 的使用及测试。最后列举了实际应用场景如用户注册、登录等,并提供了完整的代码示例。
DotNetGuy 发布于 2026/3/30 更新于 2026/4/13 1 浏览学习目标与重点提示
学习目标 :掌握 Spring Boot 数据验证与异常处理的核心概念与使用方法,包括数据验证的定义与特点、异常处理的定义与特点、Spring Boot 与数据验证的集成、Spring Boot 与异常处理的集成、Spring Boot 的实际应用场景,学会在实际开发中处理数据验证与异常处理问题。
重点 :数据验证的定义与特点、异常处理的定义与特点、Spring Boot 与数据验证的集成、Spring Boot 与异常处理的集成、Spring Boot 的实际应用场景。
数据验证与异常处理概述
数据验证与异常处理是 Java 开发中的重要组件,用于确保数据的正确性和处理系统的异常。
数据验证的定义
定义 :数据验证是指对输入数据进行验证,确保数据的正确性和完整性。
作用 :
确保输入数据的正确性。
防止恶意数据的输入。
提高系统的可靠性。
常见的数据验证 :
结论 :数据验证是指对输入数据进行验证,作用是确保输入数据的正确性、防止恶意数据的输入、提高系统的可靠性。
异常处理的定义
定义 :异常处理是指对系统运行过程中出现的异常进行处理,确保系统的正常运行。
作用 :
提高系统的可靠性。
提高用户体验。
便于系统的维护。
常见的异常处理 :
结论 :异常处理是指对系统运行过程中出现的异常进行处理,作用是提高系统的可靠性、提高用户体验、便于系统的维护。
Spring Boot 与数据验证的集成
Spring Boot 与数据验证的集成是 Java 开发中的重要内容。
集成 Spring Validation 的步骤
步骤 :
创建 Spring Boot 项目。
添加所需的依赖。
配置数据验证。
创建实体类。
创建业务层。
创建控制器类。
测试应用。
示例 :
pom.xml 文件中的依赖:
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</ >
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-starter-test
test
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
artifactId
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<scope >
</scope >
</dependency >
</dependencies >
application.properties 文件中的配置:
import javax.validation.constraints.*;
public class Product {
private Long id;
@NotBlank(message = "产品 ID 不能为空")
@Size(min = 3, max = 10, message = "产品 ID 长度必须在 3 到 10 个字符之间")
private String productId;
@NotBlank(message = "产品名称不能为空")
@Size(min = 2, max = 50, message = "产品名称长度必须在 2 到 50 个字符之间")
private String productName;
@Min(value = 0, message = "价格必须大于等于 0")
@Max(value = 10000, message = "价格必须小于等于 10000")
private double price;
@Min(value = 0, message = "库存必须大于等于 0")
private int stock;
public Product () {}
public Product (Long id, String productId, String productName, double price, int stock) {
this .id = id;
this .productId = productId;
this .productName = productName;
this .price = price;
this .stock = stock;
}
public Long getId () { return id; }
public void setId (Long id) { this .id = id; }
public String getProductId () { return productId; }
public void setProductId (String productId) { this .productId = productId; }
public String getProductName () { return productName; }
public void setProductName (String productName) { this .productName = productName; }
public double getPrice () { return price; }
public void setPrice (double price) { this .price = price; }
public int getStock () { return stock; }
public void setStock (int stock) { this .stock = stock; }
@Override
public String toString () {
return "Product{" +
"id=" + id +
", productId='" + productId + '\'' +
", productName='" + productName + '\'' +
", price=" + price +
", stock=" + stock +
'}' ;
}
}
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class ProductRepository {
private List<Product> products = new ArrayList <>();
public ProductRepository () {
products.add(new Product (1L , "P001" , "手机" , 1000.0 , 100 ));
products.add(new Product (2L , "P002" , "电脑" , 5000.0 , 50 ));
products.add(new Product (3L , "P003" , "电视" , 3000.0 , 80 ));
products.add(new Product (4L , "P004" , "手表" , 500.0 , 200 ));
products.add(new Product (5L , "P005" , "耳机" , 300.0 , 150 ));
}
public List<Product> getAllProducts () { return products; }
public Product getProductById (Long id) {
return products.stream().filter(product -> product.getId().equals(id)).findFirst().orElse(null );
}
public void addProduct (Product product) {
product.setId((long ) (products.size() + 1 ));
products.add(product);
}
public void updateProduct (Product product) {
Product existingProduct = getProductById(product.getId());
if (existingProduct != null ) {
existingProduct.setProductId(product.getProductId());
existingProduct.setProductName(product.getProductName());
existingProduct.setPrice(product.getPrice());
existingProduct.setStock(product.getStock());
}
}
public void deleteProduct (Long id) {
products.removeIf(product -> product.getId().equals(id));
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public List<Product> getAllProducts () { return productRepository.getAllProducts(); }
public Product getProductById (Long id) { return productRepository.getProductById(id); }
public void addProduct (Product product) { productRepository.addProduct(product); }
public void updateProduct (Product product) { productRepository.updateProduct(product); }
public void deleteProduct (Long id) { productRepository.deleteProduct(id); }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/")
public List<Product> getAllProducts () {
return productService.getAllProducts();
}
@GetMapping("/{id}")
public Product getProductById (@PathVariable Long id) {
return productService.getProductById(id);
}
@PostMapping("/add")
public Map<String, Object> addProduct (@Valid @RequestBody Product product, BindingResult bindingResult) {
Map<String, Object> result = new HashMap <>();
if (bindingResult.hasErrors()) {
Map<String, String> errors = new HashMap <>();
for (FieldError error : bindingResult.getFieldErrors()) {
errors.put(error.getField(), error.getDefaultMessage());
}
result.put("success" , false );
result.put("errors" , errors);
return result;
}
productService.addProduct(product);
result.put("success" , true );
result.put("message" , "产品添加成功" );
return result;
}
@PutMapping("/edit/{id}")
public Map<String, Object> editProduct (@PathVariable Long id, @Valid @RequestBody Product product, BindingResult bindingResult) {
Map<String, Object> result = new HashMap <>();
if (bindingResult.hasErrors()) {
Map<String, String> errors = new HashMap <>();
for (FieldError error : bindingResult.getFieldErrors()) {
errors.put(error.getField(), error.getDefaultMessage());
}
result.put("success" , false );
result.put("errors" , errors);
return result;
}
product.setId(id);
productService.updateProduct(product);
result.put("success" , true );
result.put("message" , "产品更新成功" );
return result;
}
@DeleteMapping("/delete/{id}")
public Map<String, Object> deleteProduct (@PathVariable Long id) {
Map<String, Object> result = new HashMap <>();
productService.deleteProduct(id);
result.put("success" , true );
result.put("message" , "产品删除成功" );
return result;
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ValidationApplication {
public static void main (String[] args) {
SpringApplication.run(ValidationApplication.class, args);
}
}
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.*;
import java.util.HashMap;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ValidationApplicationTests {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void contextLoads () {}
@Test
void testAddProduct () {
Map<String, Object> product = new HashMap <>();
product.put("productId" , "P006" );
product.put("productName" , "耳机" );
product.put("price" , 300.0 );
product.put("stock" , 150 );
HttpHeaders headers = new HttpHeaders ();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> request = new HttpEntity <>(product, headers);
ResponseEntity<Map> response = restTemplate.exchange("http://localhost:" + port + "/api/products/add" , HttpMethod.POST, request, Map.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody().get("success" )).isEqualTo(true );
}
@Test
void testAddProductWithInvalidData () {
Map<String, Object> product = new HashMap <>();
product.put("productId" , "P" );
product.put("productName" , "" );
product.put("price" , -100.0 );
product.put("stock" , -10 );
HttpHeaders headers = new HttpHeaders ();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> request = new HttpEntity <>(product, headers);
ResponseEntity<Map> response = restTemplate.exchange("http://localhost:" + port + "/api/products/add" , HttpMethod.POST, request, Map.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody().get("success" )).isEqualTo(false );
assertThat(response.getBody().get("errors" )).isNotNull();
}
}
结论 :集成 Spring Validation 的步骤包括创建 Spring Boot 项目、添加所需的依赖、配置数据验证、创建实体类、创建业务层、创建控制器类、测试应用。
Spring Boot 与异常处理的集成 Spring Boot 与异常处理的集成是 Java 开发中的重要内容。
集成 Spring Boot 异常处理的步骤
创建 Spring Boot 项目。
添加所需的依赖。
配置异常处理。
创建异常类。
创建异常处理器类。
测试应用。
application.properties 文件中的配置(同前)。
实体类、Repository、Service(同上)。
public class ProductNotFoundException extends RuntimeException {
public ProductNotFoundException (String message) {
super (message);
}
public ProductNotFoundException (String message, Throwable cause) {
super (message, cause);
}
}
public class ProductExistsException extends RuntimeException {
public ProductExistsException (String message) {
super (message);
}
public ProductExistsException (String message, Throwable cause) {
super (message, cause);
}
}
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class ProductExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleValidationExceptions (MethodArgumentNotValidException ex) {
Map<String, Object> result = new HashMap <>();
Map<String, String> errors = new HashMap <>();
ex.getBindingResult().getFieldErrors().forEach(error -> {
errors.put(error.getField(), error.getDefaultMessage());
});
result.put("success" , false );
result.put("errors" , errors);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<Map<String, Object>> handleProductNotFoundException (ProductNotFoundException ex) {
Map<String, Object> result = new HashMap <>();
result.put("success" , false );
result.put("message" , ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(result);
}
@ExceptionHandler(ProductExistsException.class)
public ResponseEntity<Map<String, Object>> handleProductExistsException (ProductExistsException ex) {
Map<String, Object> result = new HashMap <>();
result.put("success" , false );
result.put("message" , ex.getMessage());
return ResponseEntity.status(HttpStatus.CONFLICT).body(result);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Map<String, Object>> handleAllExceptions (Exception ex) {
Map<String, Object> result = new HashMap <>();
result.put("success" , false );
result.put("message" , "系统错误:" + ex.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping("/{id}")
public Product getProductById (@PathVariable Long id) {
Product product = productService.getProductById(id);
if (product == null ) {
throw new ProductNotFoundException ("产品不存在:" + id);
}
return product;
}
}
@SpringBootApplication
public class ValidationAndExceptionApplication {
public static void main (String[] args) {
SpringApplication.run(ValidationAndExceptionApplication.class, args);
}
}
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ValidationAndExceptionApplicationTests {
@Test
void testGetProductByIdNotFound () {
ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:" + port + "/api/products/10" , Map.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
assertThat(response.getBody().get("success" )).isEqualTo(false );
assertThat(response.getBody().get("message" )).isNotNull();
}
}
结论 :集成 Spring Boot 异常处理的步骤包括创建 Spring Boot 项目、添加所需的依赖、配置异常处理、创建异常类、创建异常处理器类、测试应用。
Spring Boot 的实际应用场景 在实际开发中,Spring Boot 数据验证与异常处理的应用场景非常广泛,如:
实现用户注册的数据验证。
实现用户登录的数据验证。
实现产品信息的数据验证。
实现订单信息的数据验证。
结论 :在实际开发中,Spring Boot 数据验证与异常处理的应用场景非常广泛,需要根据实际问题选择合适的数据验证和异常处理方法。
总结 本章我们学习了 Spring Boot 数据验证与异常处理,包括数据验证的定义与特点、异常处理的定义与特点、Spring Boot 与数据验证的集成、Spring Boot 与异常处理的集成、Spring Boot 的实际应用场景,学会了在实际开发中处理数据验证与异常处理问题。其中,数据验证的定义与特点、异常处理的定义与特点、Spring Boot 与数据验证的集成、Spring Boot 与异常处理的集成、Spring Boot 的实际应用场景是本章的重点内容。从下一章开始,我们将学习 Spring Boot 的其他组件、微服务等内容。