日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

rest api_摆脱困境:向REST API添加验证

發布時間:2023/12/3 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rest api_摆脱困境:向REST API添加验证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

rest api

我對此感到有些ham愧,但是直到昨天,我才知道我可以通過使用@Valid和@RequestBody批注將驗證添加到REST API中。 這在Spring MVC 3.0中不起作用,由于某種原因,我沒有注意到在Spring MVC 3.1中添加了對此功能的支持 。 我從不喜歡舊的方法,因為我不得不

  • 將Validator和MessageSource bean注入我的控制器,以便我可以驗證請求并在驗證失敗時獲取本地化的錯誤消息。
  • 在每個必須驗證輸入的控制器方法中調用驗證方法。
  • 將驗證邏輯移到由控制器類擴展的公共基類中。
  • 當我發現不必再做這些事情時,我決定寫這篇博客文章,并與大家分享我的發現。

    注意:如果我們想在Spring Framework中使用JSR-303支持的驗證,則必須向我們的類路徑添加JSR-303提供程序。 本博客文章的示例應用程序使用Hibernate Validator 4.2.0,它是Bean驗證API(JSR-303)的參考實現。

    讓我們首先看一下本博客文章中使用的DTO類。 CommentDTO類的源代碼如下所示:

    import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotEmpty;public class CommentDTO {@NotEmpty@Length(max = 140)private String text;//Methods are omitted. }

    讓我們繼續前進,了解如何使用Spring MVC 3.1將驗證添加到REST API。

    Spring MVC 3.1是一個好的開始

    我們可以按照以下步驟將驗證添加到REST API:

  • 實施控制器方法,并確保其輸入經過驗證。
  • 實現處理驗證錯誤的邏輯。
  • 以下小節將介紹這兩個步驟。

    實施控制器

    我們可以通過執行以下步驟來實現我們的控制器:

  • 創建一個名為CommentController的類,并使用@Controller注釋對該類進行注釋。
  • 將一個add()方法添加到CommentController類,該方法將添加的注釋作為方法參數。
  • 使用@RequestMapping和@ResponseBody注釋對方法進行注釋。
  • 將@Valid和@RequestBody批注應用到方法參數。
  • 返回添加的評論。
  • CommentController類的源代碼如下所示:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;import javax.validation.Valid;@Controller public class CommentController {@RequestMapping(value = "/api/comment", method = RequestMethod.POST)@ResponseBodypublic CommentDTO add(@Valid @RequestBody CommentDTO comment) {return comment;} }

    現在,我們向控制器添加了新方法,并對其進行了驗證。 驗證失敗時,將引發MethodArgumentNotValidException 。 讓我們找出驗證失敗時如何向API用戶返回有意義的響應。

    處理驗證錯誤

    通過執行以下步驟,我們可以實現處理驗證錯誤的邏輯:

  • 實現數據傳輸對象,其中包含返回給我們REST API用戶的信息。
  • 實現異常處理程序方法。
  • 下面將更詳細地描述這些步驟。

    創建數據傳輸對象

    首先,我們必須創建數據傳輸對象,其中包含返回給REST API用戶的信息。 我們可以按照以下步驟進行操作:

  • 創建一個DTO,其中包含單個驗證錯誤的信息。
  • 創建一個DTO,將這些驗證錯誤包裝在一起。
  • 讓我們開始吧。

    第一個DTO的源代碼如下所示:

    public class FieldErrorDTO {private String field;private String message;public FieldErrorDTO(String field, String message) {this.field = field;this.message = message;}//Getters are omitted. }

    第二個DTO的實現非常簡單。 它包含一個FieldErrorDTO對象列表和一個用于向列表中添加新字段錯誤的方法。 ValidationErrorDTO的源代碼如下所示:

    import java.util.ArrayList; import java.util.List;public class ValidationErrorDTO {private List<FieldErrorDTO> fieldErrors = new ArrayList<>();public ValidationErrorDTO() {}public void addFieldError(String path, String message) {FieldErrorDTO error = new FieldErrorDTO(path, message);fieldErrors.add(error);}//Getter is omitted. }

    以下清單提供了一個示例Json文檔,當驗證失敗時,該文檔將發回給我們的API用戶:

    {"fieldErrors":[{"field":"text","message":"error message"}] }

    讓我們看看如何實現異常處理程序方法,該方法創建一個新的ValidationErrorDTO對象并返回創建的對象。

    實現異常處理程序方法

    我們可以按照以下步驟將異常處理程序方法添加到我們的控制器中:

  • 將一個MessageSource字段添加到CommentController類。 消息源用于獲取驗證錯誤的本地化錯誤消息。
  • 通過使用構造函數注入來注入MessageSource bean。
  • 將一個processValidationError()方法添加到CommentController類。 此方法返回ValidationErrorDTO對象,并將MethodArgumentNotValidException對象作為方法參數。
  • 使用@ExceptionHandler注釋對方法進行注釋,并確保在引發MethodArgumentNotValidException時調用該方法。
  • 使用@ResponseStatus注釋對方法進行注釋,并確保返回HTTP狀態代碼400(錯誤請求)。
  • 使用@ResponseBody注釋對方法進行注釋。
  • 實現該方法。
  • 讓我們仔細看看processValidationError()方法的實現。 我們可以通過執行以下步驟來實現此方法:

  • 獲取FieldError對象的列表并進行處理。
  • 一次處理一場錯誤。
  • 嘗試使用MessageSource對象,當前語言環境和已處理字段錯誤的錯誤代碼來解決本地化的錯誤消息。
  • 返回已解決的錯誤消息。 如果從屬性文件中找不到錯誤消息,請返回最準確的字段錯誤代碼。
  • 通過調用ValidationErrorDTO類的addFieldError()方法來添加新的字段錯誤。 將字段名稱和已解決的錯誤消息作為方法參數傳遞。
  • 處理完每個字段錯誤后,返回創建的ValidationErrorDTO對象。
  • CommentController類的源代碼如下所示:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.*;import javax.validation.Valid; import java.util.List; import java.util.Locale;@Controller public class CommentController {private MessageSource messageSource;@Autowiredpublic CommentController(MessageSource messageSource) {this.messageSource = messageSource;}//The add() method is omitted.@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic ValidationErrorDTO processValidationError(MethodArgumentNotValidException ex) {BindingResult result = ex.getBindingResult();List<FieldError> fieldErrors = result.getFieldErrors();return processFieldErrors(fieldErrors);}private ValidationErrorDTO processFieldErrors(List<FieldError> fieldErrors) {ValidationErrorDTO dto = new ValidationErrorDTO();for (FieldError fieldError: fieldErrors) {String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError);dto.addFieldError(fieldError.getField(), localizedErrorMessage);}return dto;}private String resolveLocalizedErrorMessage(FieldError fieldError) {Locale currentLocale = LocaleContextHolder.getLocale();String localizedErrorMessage = messageSource.getMessage(fieldError, currentLocale);//If the message was not found, return the most accurate field error code instead.//You can remove this check if you prefer to get the default error message.if (localizedErrorMessage.equals(fieldError.getDefaultMessage())) {String[] fieldErrorCodes = fieldError.getCodes();localizedErrorMessage = fieldErrorCodes[0];}return localizedErrorMessage;} }

    這就對了。 讓我們花點時間評估我們剛剛完成的工作。

    我們就快到了

    現在,我們已使用Spring MVC 3.1將驗證添加到REST API中。 與舊方法相比,此實現有一個主要好處:

    我們可以使用@Valid批注來觸??發驗證過程。

    但是,僅當從包含異常處理程序方法的控制器類中拋出配置的異常時,才會觸發使用@ExceptionHandler注釋進行注釋的方法。 這意味著如果我們的應用程序具有多個控制器,則必須為控制器創建一個公共基類,并將處理驗證錯誤的邏輯移到該類。 這聽起來似乎沒什么大不了,但是我們應該更喜歡組合而不是繼承 。

    Spring MVC 3.2提供了可用于從控制器中消除繼承需求的工具。 讓我們繼續前進,找出實現方法。

    Spring MVC 3.2搶救

    Spring MVC 3.2引入了一個新的@ControllerAdvice批注 ,我們可以使用該批注實現一個異常處理程序組件,該組件處理控制器拋出的異常。 我們可以通過執行以下步驟來實現此組件:

  • 從CommentController類中刪除處理驗證錯誤的邏輯。
  • 創建一個新的異常處理程序類,并將處理驗證錯誤的邏輯移至創建的類。
  • 在以下小節中將更詳細地說明這些步驟。

    從我們的控制器中刪除異常處理邏輯

    我們可以按照以下步驟從控制器中刪除異常處理邏輯:

  • 從CommentController類中刪除MessageSource字段。
  • 從我們的控制器類中刪除構造函數。
  • 從我們的控制器類中刪除processValidationError()方法和私有方法。
  • CommentController類的源代碼如下所示:

    import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;import javax.validation.Valid;@Controller public class CommentController {@RequestMapping(value = "/api/comment", method = RequestMethod.POST)@ResponseBodypublic CommentDTO add(@Valid @RequestBody CommentDTO comment) {return comment;} }

    下一步是創建異常處理程序組件。 讓我們看看這是如何完成的。

    創建異常處理程序組件

    我們可以按照以下步驟創建異常處理程序組件:

  • 創建一個名為RestErrorHandler的類,并使用@ControllerAdvice批注對其進行批注。
  • 將一個MessageSource字段添加到RestErrorHandler類。
  • 通過使用構造函數注入來注入MessageSource bean。
  • 將processValidationError()方法和所需的私有方法添加到RestErrorHandler類。
  • RestErrorHandler類的源代碼如下所示:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus;import java.util.List; import java.util.Locale;@ControllerAdvice public class RestErrorHandler {private MessageSource messageSource;@Autowiredpublic RestErrorHandler(MessageSource messageSource) {this.messageSource = messageSource;}@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic ValidationErrorDTO processValidationError(MethodArgumentNotValidException ex) {BindingResult result = ex.getBindingResult();List<FieldError> fieldErrors = result.getFieldErrors();return processFieldErrors(fieldErrors);}private ValidationErrorDTO processFieldErrors(List<FieldError> fieldErrors) {ValidationErrorDTO dto = new ValidationErrorDTO();for (FieldError fieldError: fieldErrors) {String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError);dto.addFieldError(fieldError.getField(), localizedErrorMessage);}return dto;}private String resolveLocalizedErrorMessage(FieldError fieldError) {Locale currentLocale = LocaleContextHolder.getLocale();String localizedErrorMessage = messageSource.getMessage(fieldError, currentLocale);//If the message was not found, return the most accurate field error code instead.//You can remove this check if you prefer to get the default error message.if (localizedErrorMessage.equals(fieldError.getDefaultMessage())) {String[] fieldErrorCodes = fieldError.getCodes();localizedErrorMessage = fieldErrorCodes[0];}return localizedErrorMessage;} }

    我們終于到了

    感謝Spring MVC 3.2,我們現在實現了一種優雅的解決方案,其中驗證由@Valid批注觸發,并且異常處理邏輯移至單獨的類。 我認為我們可以稱之為一天,享受工作成果。

    摘要

    這篇博客文章告訴我們

    • 如果要在使用Spring 3.0時向REST API添加驗證,則必須自己實現驗證邏輯。
    • Spring 3.1通過使用@Valid批注將驗證添加到REST API成為可能。 但是,我們必須創建一個包含異常處理邏輯的公共基類。 每個需要驗證的控制器都必須擴展此基類。
    • 當使用Spring 3.2時,我們可以使用@Valid批注來觸??發驗證過程,并將異常處理邏輯提取到單獨的類中。

    Github上提供了此博客的示例應用程序( Spring 3.1和Spring 3.2 )

    參考資料: 從槽中汲取經驗: Petri Kainulainen博客上的JCG合作伙伴 Petri Kainulainen 向REST API添加了驗證 。

    翻譯自: https://www.javacodegeeks.com/2013/05/spring-from-the-trenches-adding-validation-to-a-rest-api.html

    rest api

    總結

    以上是生活随笔為你收集整理的rest api_摆脱困境:向REST API添加验证的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。