簡體   English   中英

JSR-303 / Spring MVC-使用組有條件地驗證

[英]JSR-303 / Spring MVC - validate conditionally using groups

我提出了一個概念,可以有條件地使用JSR 303組進行驗證。 “有條件地”表示我有一些僅在另一個字段具有特定值的情況下才相關的字段。

示例:有一個選項可以選擇是注冊為個人還是公司。 選擇公司時,用戶必須填寫包含公司名稱的字段。

現在我認為我可以使用組:

  class RegisterForm
  {
     public interface BasicCheck {}
     public interface UserCheck {}
     public interface CompanyCheck {}

     @NotNull(groups = BasicCheck.class)
     private Boolean isCompany

     @NotNull(groups = UserCheck.class)
     private String firstName;

     @NotNull(groups = UserCheck.class)
     private String lastName;

     @NotNull(groups = CompanyCheck.class)
     private String companyName;

     // getters / setters ...
  }

在我的控制器中,我會根據各自的選擇逐步驗證:

  @Autowired
  SmartValidator validator;

  public void onRequest(@ModelAttribute("registerForm") RegisterForm registerForm, BindingResult result)
  {
     validator.validate(registerForm, result, RegisterForm.BasicCheck.class);
     if (result.hasErrors()
        return;
     // basic check successful => we can process fields which are covered by this check
     if (registerForm.getIsCompany())
     {
        validator.validate(registerForm, result, RegisterForm.CompanyCheck.class)
     }
     else
     {
        validator.validate(registerForm, result, RegisterForm.UserCheck.class);
     }
     if (!result.hasErrors())
     {
        // process registration
     }
  }

我只想驗證必須驗證的內容。 如果用戶選擇“公司”,則使用無效內容填充字段,然后切換回“用戶”,驗證程序必須忽略與公司相關的無效內容。 一種解決方案是使用Javascript清除這些字段,但我也希望表單在禁用javascript的情況下工作。 這就是為什么我完全喜歡上面顯示的方法的原因。

但是由於數據綁定,Spring打破了這個想法。 在驗證開始之前,Spring將數據綁定到registerForm。 例如,如果類型不兼容(預期的整數值,但用戶用字母填充表格),則會在result增加錯誤。 這是一個問題,因為這些錯誤在<form:errors />標記在JSP視圖中顯示

現在,我找到了一種方法,可以通過實現自定義BindingErrorProcessor來防止Spring將這些錯誤添加到綁定結果中。 如果字段包含null我知道存在驗證錯誤。 在我的概念null是不允許的-每場得到帶注釋@NotNull加上相應的驗證組。

當我剛接觸Spring和JSR-303時,我想知道自己是否完全走錯了道路。 我必須自己執行幾件事,這使我不確定。 這是一個干凈的解決方案嗎? 我認為這是一個普遍的問題,對於同一問題是否有更好的解決方案?

編輯

如果您對我的解決方案感興趣,請在這里查看我的答案: https : //stackoverflow.com/a/30500985/395879

您是正確的,Spring MVC在這方面有點挑剔,這是一個普遍的問題。 但是有解決方法:

  • 將所有后備字段設置為字符串,並手動進行數字/日期等轉換和空值檢查。
  • 當字段不相關時,使用JavaScript將其設置為null。
  • 輸入字段時,使用JavaScript驗證字段。 這將解決您幾乎所有的問題。

祝好運!

我知道這個問題很舊,但是我遇到了這個問題,正在尋找其他情況的答案。

我認為根據您的情況,您可以對表格使用繼承,然后使用兩種控制器方法:

表格如下所示:

public class RegistrationForm
{
    // Common fields go here.
}

public class UserRegistrationForm
    extends RegistrationForm
{
    @NotNull
    private String firstName;

    @NotNull
    private String lastName;

    // getters / setters ...
}

public class CompanyRegistrationForm
    extends RegistrationForm
{
    @NotNull
    private String companyName;

    // getters / setters ...
}

控制器方法如下所示:

@RequestMapping(method = RequestMethod.POST, params = "isCompany=false")
public void onRequest(
        @ModelAttribute("registerForm") @Valid UserRegistrationForm form,
        BindingResult result)
{
    if (!result.hasErrors())
    {
        // process registration
    }
}
@RequestMapping(method = RequestMethod.POST, params = "isCompany=true")
public void onRequest(
        @ModelAttribute("registerForm") @Valid CompanyRegistrationForm form,
        BindingResult result)
{
    if (!result.hasErrors())
    {
        // process registration
    }
}

注意, @RequestMapping注釋包括一個params屬性所以值isCompany參數確定哪個方法被調用。

還要注意,@ @Valid批注位於form參數上。

最后,在這種情況下,不需要任何組。

暫無
暫無

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

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