2010-03-18 70 views
2

我有一個名爲User的對象,我保存了用戶的所有數據。我有一些註釋來執行驗證,它工作正常。Spring:同一對象,不同的驗證

public class User{ 
    @NotEmpty 
    @Email 
    @Size(max=100) 
    @Column(name="username", length=100, nullable=false, unique=true) 
    private String username; 

    @NotEmpty 
    @Size(min=5, max=40) 
    @Column(name="password", length=40, nullable=false) 
    private String password; 

    @Size(min=5, max=40) 
    @Transient 
    private String newPassword; 

    // other attributes ,getters and setters 
} 

我有兩種不同的形式(每個在不同的頁面)。在第一個我要求用戶名和密碼來創建用戶,所以他們都是強制性的。

在第二種形式中,我顯示有關用戶的信息:用戶名,其他數據(將進行驗證)以及密碼和newPassword。如果設置了newPassword並且密碼與用戶的密碼相同,我將更改用戶密碼,但是如果它們留空,這意味着我不應更改密碼。

問題是,我有兩個表單有關相同的對象,其中有一個字段密碼不同的驗證。在第一個中它不能爲空,但在第二個中它可以是空的。

在控制器I驗證對象以這種方式:

public String getUserDetails(@Valid @ModelAttribute("User") User user, BindingResult result, Model model){ 
    if(result.hasErrors()){ 
     //There have been errors 
    } 
    ... 
} 

但是密碼爲空會有錯誤。

是否有任何方法只在對象的某些字段中執行驗證?

我可以在驗證後至少刪除任何驗證錯誤嗎?

這種情況下的最佳做法是什麼?

感謝

回答

3

這與聲明性驗證的問題,這不是很容易做這樣的事情。

最簡單的解決方案是從密碼字段中刪除驗證註釋,並在控制器中手動驗證該字段。 BindingResult類有方法讓你明確地標記字段爲無效。

另一種方法是創建兩個窗體類的子類,每個子類都有自己的密碼字段,一個帶有驗證註釋,另一個沒有,並在適當的位置使用適當的一個。

+0

有一個解決方案(現在?)使用JSR-303 Constraint Groups.http://stackoverflow.com/a/36345405/1030527 – bernie 2016-03-31 23:15:37

0

幾點提示。我不知道他們會是有用的,但:

Spring docs說:

你可以調用內的binder.setValidator(驗證)@控制器的@InitBinder回調。這允許您爲每個@Controller類配置Validator實例

javax.validation有兩個*Context接口。深入瞭解更多細節,以瞭解是否可以在不同情況下實現不同的驗證。

0

而不是使用hasErrors()函數,使用hasFieldErrors(fieldname)並且只驗證表單所需的特定字段。

2

您可以使用JSR-303 constraint groups來實現此目的。

public class User { 

    public interface GroupNewUser {}; 

    @NotEmpty 
    private String username; 

    @NotEmpty(groups = {GroupNewUser.class}); 
    private String password; 

    // ... 
} 
控制器

然後,而不是使用@Valid,使用Spring的@Validated標註其允許指定約束組提出申請。

有關更多信息,請參閱this blog postthis one also

還有這個superb post for Spring usage

相關問題