欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解

 更新時(shí)間:2019年04月30日 14:10:23   作者:惜魚  
這篇文章主要介紹了SpringBoot 2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

在開發(fā)項(xiàng)目時(shí),我們經(jīng)常需要在前后端都校驗(yàn)用戶提交的數(shù)據(jù),判斷提交的數(shù)據(jù)是否符合我們的標(biāo)準(zhǔn),包括字符串長(zhǎng)度,是否為數(shù)字,或者是否為手機(jī)號(hào)碼等;這樣做的目的主要是為了減少SQL注入攻擊的風(fēng)險(xiǎn)以及臟數(shù)據(jù)的插入。提到數(shù)據(jù)校驗(yàn)我們通常還會(huì)提到異常處理,因?yàn)闉榱税踩鹨姡蠖顺霈F(xiàn)的異常我們通常不希望直接拋到客戶端,而是經(jīng)過我們的處理之后再返回給客戶端,這樣做主要是提升系統(tǒng)安全性,另外就是給予用戶友好的提示。

定義實(shí)體并加上校驗(yàn)注解

class StudentForm() {
 
 @NotBank(message = '生日不能為空')
 var birthday: String = ""

 @NotBlank(message = "Id不能為空")
 var id:String = ""

 @NotBlank(message = "年齡不能為空")
 var age:String = ""

 @NotEmpty(message = "興趣愛好不能為空")
 var Interests:List<String> = Collections.emptyList()

 @NotBlank(message = "學(xué)校不能為空")
 var school: String = ""
 override fun toString(): String {
  return ObjectMapper().writeValueAsString(this)
 }
}

這里首先使用的是基礎(chǔ)校驗(yàn)注解,位于javax.validation.constraints下,常見注解有@NotNull、@NotEmpty、@Max、@Email、@NotBank、@Size、@Pattern,當(dāng)然出了這些還有很多注解,這里就不在一一講解,想了解更多的可以咨詢查看jar包。

這里簡(jiǎn)單講解一下注解的常見用法:

  • @NotNull: 校驗(yàn)一個(gè)對(duì)象是否為Null
  • @NotBank: 校驗(yàn)字符串是否為空串
  • @NotEmpty: 校驗(yàn)List、Map、Set是否為空
  • @Email: 校驗(yàn)是否為郵箱格式
  • @Max @Min: 校驗(yàn)Number或String是否在指定范圍內(nèi)
  • @Size: 通常需要配合@Max @Min一期使用
  • @Pattern: 配合自定義正則表達(dá)式校驗(yàn)

定義返回狀態(tài)枚舉

enum class ResultEnums(var code:Int, var msg:String) {
 SUCCESS(200, "成功"),
 SYSTEM_ERROR(500, "系統(tǒng)繁忙,請(qǐng)稍后再試"),

}

自定義異常

這里主要是參數(shù)校驗(yàn),所以定義一個(gè)運(yùn)行時(shí)異常,代碼如下:

class ParamException(message: String?) : RuntimeException(message) {
 var code:Int = ResultEnums.SUCCESS.code

 constructor(code:Int, message: String?):this(message) {
  this.code = code
 }
}

統(tǒng)一返回結(jié)構(gòu)體定義

class ResultVo<T> {

 var status:Int = ResultEnums.SUCCESS.code

 var msg:String = ""

 var data:T? = null

 constructor()

 constructor(status:Int, msg:String, data:T) {
  this.status = status
  this.data = data
  this.msg = msg
 }

 override fun toString(): String {
  return ObjectMapper().writeValueAsString(this)
 }
}

全局異常處理

這里的全局異常處理,是指請(qǐng)求到達(dá)Controller層之后發(fā)生異常處理。代碼如下:

@RestControllerAdvice
class RestExceptionHandler {

 private val logger:Logger = LoggerFactory.getLogger(this.javaClass)

 @ExceptionHandler(Exception::class)
 @ResponseBody
 fun handler(exception: Exception): ResultVo<String> {
  logger.error("全局異常:{}", exception)
  return ResultVo(500, "系統(tǒng)異常", "")
 }

 @ExceptionHandler(ParamException::class)
 @ResponseBody
 fun handler(exception: ParamException): ResultVo<String> {
  logger.error("參數(shù)異常:{}", exception.localizedMessage)
  return ResultVo(exception.code, exception.localizedMessage, "")
 }

}

這里得和Java處理的方式大同小異,無疑就是更加簡(jiǎn)潔了而已。

編寫校驗(yàn)工具

object ValidatorUtils {

 private val validator = Validation.buildDefaultValidatorFactory().validator

 /**
  * 校驗(yàn)對(duì)象屬性
  * @param obj 被校驗(yàn)對(duì)象
  * @param <T> 泛型
  * @return Map
 </T> */
 fun validate(obj: Any): Map<String, String> {
  var errorMap: Map<String, String>? = null
  val set = validator.validate(obj, Default::class.java)
  if (CollectionUtils.isEmpty(set)) {
   return emptyMap()
  }
  errorMap = set.map { it.propertyPath.toString() to it.message }.toMap()
  return errorMap
 }

 /**
  * 校驗(yàn)對(duì)象屬性
  * @param obj 被校驗(yàn)對(duì)象
  * @param <T> 泛型
  * @return List
 </T> */
 fun validata(obj: Any): List<String> {
  val set = validator.validate(obj, Default::class.java)
  return if (CollectionUtils.isEmpty(set)) {
   emptyList()
  } else set.stream()
    .filter {Objects.nonNull(it)}
    .map { it.message }
    .toList()
 }
}

抽象校驗(yàn)方法

因?yàn)樾r?yàn)是通用的,幾乎大部分接口都需要檢驗(yàn)傳入?yún)?shù),所以我們把校驗(yàn)方法抽出來放在通用Controller層里,通用層這里不建議使用Class或者是抽象類,而是使用interface,定義如下:

@Throws(ParamException::class)
fun validate(t:Any) {
 val errorMap = ValidatorUtils.validate(t).toMutableMap()
 if (errorMap.isNotEmpty()) {
  throw ParamException(ResultEnums.SYSTEM_ERROR.code, errorMap.toString())
 }
}

這里如果有參數(shù)錯(cuò)誤就直接拋出參數(shù)異常,然后交給全局異常處理器來捕獲。

Controller層編寫

@PostMapping("/student")
fun create(@RequestBody studentForm: StudentForm): ResultVo<StudentDTO> {
 this.validate(studentForm)
 val studentDTO = StudentDTO()
 BeanUtils.copyProperties(studentForm, studentDTO)
 return ResultVo(200, "", studentDTO)
}

1.傳入一個(gè)空對(duì)象: 返回結(jié)果:

{
 "status": 500,
 "msg": "{school=學(xué)校不能為空, id=Id不能為空, age=年齡不能為空, Interests=興趣愛好不能為空}",
 "data": ""
}

自定義校驗(yàn)規(guī)則

本篇文章開始之前我們提到過@Pattern,這個(gè)注解主要是方便我們定義自己的校驗(yàn)規(guī)則,假如我這里需要校驗(yàn)前端傳入的生日,是否符合我所需要的格式,如下所示:

@NotBlank(message = "生日不能為空")
@Pattern(regexp="^(19|20)\\d{2}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2][0-9]|3[0-1])$", message="不是生日格式")
var birthday: String = ""

這里的校驗(yàn)邏輯可能不完善,大家使用的時(shí)候需要注意。

修改完成后我再次請(qǐng)求

請(qǐng)求示例

空值

入?yún)ⅲ?

{
 "age": "10",
 "id": "1",
 "school": "學(xué)校",
 "interests": ["戶外運(yùn)動(dòng)"],
 "birthday": ""
}

出參:

{
 "status": 500,
 "msg": "{birthday=生日不能為空}",
 "data": ""
}

錯(cuò)誤參數(shù)

入?yún)ⅲ?

{
 "age": "10",
 "id": "1",
 "school": "學(xué)校",
 "interests": ["戶外運(yùn)動(dòng)"],
 "birthday": "1989-20-20"
}

出參:

{
 "status": 500,
 "msg": "{birthday=不是生日格式}",
 "data": ""
}

正確示例

入?yún)ⅲ?

{
 "age": "10",
 "id": "1",
 "school": "學(xué)校",
 "interests": ["戶外運(yùn)動(dòng)"],
 "birthday": "1999-01-01"
}

出參:

{
 "status": 200,
 "msg": "",
 "data": {
  "id": "1",
  "birthday": "1999-01-01",
  "age": "10",
  "school": "學(xué)校"
 }
}

本章內(nèi)容就到此結(jié)束了,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java獲取環(huán)境變量及系統(tǒng)屬性的方法

    詳解Java獲取環(huán)境變量及系統(tǒng)屬性的方法

    這篇文章主要介紹了詳解Java獲取環(huán)境變量及系統(tǒng)屬性的方法,講解了System.getEnv()和System.getProperties()這兩個(gè)核心方法的使用,需要的朋友可以參考下
    2016-05-05
  • 合并有序數(shù)組的實(shí)現(xiàn)(java與C語言)

    合并有序數(shù)組的實(shí)現(xiàn)(java與C語言)

    這篇文章主要介紹了合并有序數(shù)組的實(shí)現(xiàn)(java與C語言)的相關(guān)資料,這里對(duì)有序數(shù)組的合并分享了java版本和C語言版本的示例,需要的朋友可以參考下
    2017-08-08
  • Spring實(shí)戰(zhàn)之使用注解實(shí)現(xiàn)聲明式事務(wù)操作示例

    Spring實(shí)戰(zhàn)之使用注解實(shí)現(xiàn)聲明式事務(wù)操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用注解實(shí)現(xiàn)聲明式事務(wù)操作,結(jié)合實(shí)例形式詳細(xì)分析了spring使用注解實(shí)現(xiàn)聲明式事務(wù)相關(guān)配置、接口實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2020-01-01
  • Java使用FTP上傳文件并模擬接受的方法

    Java使用FTP上傳文件并模擬接受的方法

    這篇文章主要介紹了Java使用FTP上傳文件并模擬接受的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • SpringBoot FailureAnalyzer實(shí)例使用教程

    SpringBoot FailureAnalyzer實(shí)例使用教程

    FailureAnalyzer是一種在啟動(dòng)時(shí)攔截exception并將其轉(zhuǎn)換為human-readable消息的好方法,包含在故障分析中。SpringBoot為application context相關(guān)的exceptions,JSR-303驗(yàn)證等提供了這樣的分析器,實(shí)際上很容易創(chuàng)建自己的
    2022-12-12
  • java中重載、覆蓋和隱藏三者的區(qū)別分析

    java中重載、覆蓋和隱藏三者的區(qū)別分析

    本篇文章介紹了,在java中重載、覆蓋和隱藏它們?nèi)叩膮^(qū)別分析。需要的朋友參考下
    2013-04-04
  • Maven安裝與配置及Idea配置Maven的全過程

    Maven安裝與配置及Idea配置Maven的全過程

    Maven是一個(gè)項(xiàng)目管理工具,可以對(duì)Java項(xiàng)目進(jìn)行自動(dòng)化的構(gòu)建和依賴管理,下面這篇文章主要給大家介紹了關(guān)于Maven安裝與配置及Idea配置Maven的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • SpringBoot對(duì)靜態(tài)資源的映射規(guī)則詳解解讀

    SpringBoot對(duì)靜態(tài)資源的映射規(guī)則詳解解讀

    這篇文章主要介紹了SpringBoot對(duì)靜態(tài)資源的映射規(guī)則詳解解讀,在Spring Boot中,映射規(guī)則是用來定義URL與控制器方法之間的映射關(guān)系的,通過映射規(guī)則,可以將特定的URL請(qǐng)求映射到相應(yīng)的控制器方法上,從而實(shí)現(xiàn)請(qǐng)求的處理和響應(yīng)的返回,需要的朋友可以參考下
    2023-10-10
  • MybatisPlus3.3.0沒有MybatisPlusInterceptor類問題的解決方法

    MybatisPlus3.3.0沒有MybatisPlusInterceptor類問題的解決方法

    項(xiàng)目使用的是mybatis-plus-extension3.3.0依賴,然后在我使用分頁插件的時(shí)候,發(fā)現(xiàn)無法導(dǎo)入MybatisPlusInterceptor類所以本文給大家介紹了MybatisPlus3.3.0沒有MybatisPlusInterceptor類問題的解決方法,需要的朋友可以參考下
    2023-12-12
  • Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心詳解

    Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心詳解

    Zookeeper在實(shí)際使用場(chǎng)景很多,比如配置中心,分布式鎖,注冊(cè)中心等,下面這篇文章主要給大家介紹了關(guān)于Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心的相關(guān)資料,需要的朋友可以參考下
    2021-11-11

最新評(píng)論