簡體   English   中英

使用自定義HandlerMethodArgumentResolver進行Spring MVC @Valid驗證

[英]Spring MVC @Valid Validation with custom HandlerMethodArgumentResolver

我想注冊一個可以處理以下@Controller處理程序方法定義的自定義HandlerMethodArgumentResolver

@RequestMapping(method = RequestMethod.POST)
public String createDomain(@Valid Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {

我可以通過覆蓋來自WebMvcConfigurerAdapter addArgumentResolver()來注冊我的解析器,它只是通過請求參數創建一個Domain對象。 當Spring嘗試解析Domain參數時,它會通過它的HandlerMethodArgumentResolver列表(有很多)並選擇第一個supports()它。

在上面的例子中,雖然我的解析器將被調用,我的Domain說法將得到初始化, @Valid注釋將不會被處理分解BindingResult ,一個ErrorsMethodArgumentResolver會,因為它需要一個失敗@ModelAttribute@RequestBody或處理程序方法中的@RequestPart參數,我沒有。

如果我嘗試通過添加@ModelAttribute來修復它

@RequestMapping(method = RequestMethod.POST)
public String createDomain(@Valid @ModelAttribute Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {

將首先使用supports()檢查HandlerMethodArgumentResolver實現ModelAttributeMethodProcessor ,並在我的自定義解析器之前解析參數(使用@ModelAttribute@Valid )。 BindingResult不會失敗,但我不會在Domain實例上擁有自定義創建行為。

我可以復制粘貼代碼進行驗證並添加到ModelAttributeMethodProcessor模型,但我希望有一種更簡單的方法來解析我的參數並執行驗證而無需向模型添加對象。 有這樣的方式嗎?

很好地描述了您所面臨的問題。

我檢查了你已經概述的代碼並得出了相同的結論 - 沒有內置方法同時應用自定義HandlerMethodArgumentResolver以及@Valid相關驗證,唯一的選擇是執行ModelAttributeMethodProcessor所做的操作,檢查參數是否具有@Valid注釋並調用與驗證邏輯相關的代碼。

你可以從ModelAttributeMethodProcessor派生你的HandlerMethodResolverArgumentResolver並調用super.validateIfApplicable(..)至少以這種方式利用現有代碼。

這可能為時已晚,但您的HandlerMethodArgumentResolverWebDataBinderFactory對象作為最后一個參數獲取,然后,為了掛鈎驗證,只需將其添加到您的解析器實現中:

Object resolvedObject = // your logic 
if(parameter.hasParameterAnnotation(Valid.class){
            binderFactory.createBinder(webRequest,resolvedObject,"resolvedObjectLogicalName").validate ();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM