SpringBoot2.X Kotlin系列之数据校验和异常处理详解
概述
本文主要介绍在使用SpringBoot2.x和Kotlin进行Web开发时,如何实现数据校验和异常处理。我们将会使用@Valid
注解进行数据校验,并使用ExceptionHandler
来捕获异常并统一处理。
数据校验
SpringBoot2.x 数据校验注解
SpringBoot2.x在javax.validation.constraints
包中提供了许多常用的数据校验注解,包括:
@NotNull
— 检查是否为null;@AssertTrue
— 检查Boolean类型是否为true;@Min
— 检查数字是否大于等于指定的值;@Max
— 检查数字是否小于等于指定的值;@Size
— 检查字符串或数组长度是否在指定范围内。
使用方法如下:
data class User(
@NotNull
var name: String? = null,
@Size(min = 6, max = 20)
var password: String? = null,
@Max(100)
var age: Int? = null
)
在Controller层进行数据校验
我们可以在Controller层使用@Valid
注解标记需要校验的参数,如果校验失败,则会抛出MethodArgumentNotValidException
异常,并返回给前端错误信息。例如:
@RestController
@RequestMapping("/users")
class UserController {
@PostMapping
fun createUser(@Valid @RequestBody user: User) {
// TODO: 保存用户信息
}
}
如上所述,我们使用了@Valid
注解来标记需要校验的参数,并添加了@RequestBody
注解来接收JSON格式的RequestBody。
自定义异常处理
由于前端返回的错误信息一般都是英文,因此我们需要对其进行国际化处理。除此之外,我们还需要对异常进行统一处理并返回具有良好可读性的错误信息。SpringBoot2.x为我们提供了ExceptionHandler
注解来实现统一的异常处理。
首先,我们创建一个UserException
类:
class UserException: RuntimeException {
constructor(message: String) : super(message)
constructor(throwable: Throwable) : super(throwable)
}
接下来,在Controller层中添加@ExceptionHandler
注解:
@RestControllerAdvice
class GlobalExceptionHandler {
@ExceptionHandler(UserException::class)
fun handleUserException(e: UserException): ApiResponse {
return ApiResponse(error = e.message ?: "unknown error")
}
@ExceptionHandler(MethodArgumentNotValidException::class)
fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ApiResponse {
val errorMessages = e.bindingResult.allErrors.map { it.defaultMessage }.joinToString()
return ApiResponse(error = errorMessages)
}
}
如上所述,我们使用@ExceptionHandler
注解来标记需要处理的异常。对于UserException
,我们返回其message属性;对于MethodArgumentNotValidException
,我们使用bindingResult.allErrors
来获取所有的错误信息,并将其拼接成一个字符串返回。
示例
前提条件
在开始下面的示例前,请确保您已经按照以下步骤创建了一个简单的SpringBoot应用程序:
- 在IntelliJ IDEA中创建一个新项目;
- 选择“Spring Boot”;
- 选择“Kotlin”;
- 添加Web依赖项;
- 单击“Finish”。
示例1:校验用户信息
我们创建一个UserController
类,用于实现用户注册:
@RestController
@RequestMapping("/users")
class UserController {
@PostMapping
fun createUser(@Valid @RequestBody user: User) {
// TODO: 保存用户信息
}
}
User
类定义如下:
data class User(
@NotNull(message = "姓名不能为空")
var name: String? = null,
@Size(min = 6, max = 20, message = "密码长度在6~20之间")
var password: String? = null,
@Max(value = 100, message = "年龄不能大于100岁")
var age: Int? = null
)
请注意,我们使用了@NotNull
注解来检查姓名是否为空,使用@Size
注解来检查密码长度是否在6~20之间,使用@Max
注解来检查年龄是否小于等于100。
当我们向/users
发起POST请求时,JSON请求体必须包含name
, password
以及age
三个属性。
如果JSON请求体中某项属性为空,或者密码长度不在6~20之间,或者年龄大于100,会抛出MethodArgumentNotValidException
,其错误信息为:
{
"error": "姓名不能为空, 密码长度在6~20之间"
}
示例2:自定义异常处理
创建一个UserServiceImpl
类,模拟用户注册操作,并在该操作未通过校验时抛出一个UserException
:
@Service
class UserServiceImpl {
fun createUser(user: User) {
val errorMessages = mutableListOf<String?>()
if (user.name == null) {
errorMessages.add("姓名不能为空")
}
if (user.password == null || user.password!!.length !in 6..20) {
errorMessages.add("密码长度在6~20之间")
}
if (user.age != null && user.age!! > 100) {
errorMessages.add("年龄不能大于100岁")
}
if (errorMessages.isNotEmpty()) {
throw UserException(errorMessages.joinToString())
}
// TODO: 保存用户信息
}
}
我们将UserServiceImpl.createUser()
方法抛出的错误信息封装到了一个UserException
中。接下来,需要在GlobalExceptionHandler
类中对该异常进行处理:
@RestControllerAdvice
class GlobalExceptionHandler {
// 省略其他异常处理逻辑
@ExceptionHandler(UserException::class)
fun handleUserException(e: UserException): ApiResponse {
return ApiResponse(error = e.message ?: "unknown error")
}
}
当调用createUser()
方法失败时,会抛出一个UserException
。此时,GlobalExceptionHandler.handleUserException()
方法会捕获该异常并返回一个JSON格式的错误响应。
例如,当我们向/users
发起POST请求时,JSON请求体为空,会抛出UserException
,其错误信息为:
{
"error": "姓名不能为空, 密码长度在6~20之间"
}
总结
本文介绍了在使用SpringBoot2.x和Kotlin进行Web开发时,如何实现数据校验和异常处理。我们使用了@Valid
注解进行数据校验,并使用ExceptionHandler
来捕获异常并统一处理。同时也提供了两个示例,帮助读者更好地理解本文所述内容。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot2.X Kotlin系列之数据校验和异常处理详解 - Python技术站