2012-03-14 69 views
0

在JSR-303中,有什麼方法在驗證時更改值?JSR-303 Bean驗證在驗證時更改值

public class MyEntity { 

    public String getName() { 
     return name; 
    } 

    // is it true that JSF/JAXB/JPA will always use this setter method? 
    public void setName(final String name) { 
     if (name == null) { 
      throw new NullPointerException("null name"); 
     } 
     final String collapsed = new CollapsedStringAdapter().unmarshal(name); 
     if (collapsed.length() < NAME_SIZE_MIN) { 
      throw new IllegalArgumentException("too short"); 
     } 
     if (collapsed.length() > NAME_SIZE_MAX) { 
      throw new IllegalArgumentException("too long"); 
     } 
     this.name = collapsed; 
    } 

    @NotNull 
    @Size(min = 1, max = 40) 
    @CollapsedStringSize(min = 1, max = 40) // xs:token 
    private String name; 

    @NotNull 
    @Size(min = 0, max = 255) 
    @NormalizedStringSize(min = 0, max = 255) // xs:normalizedString 
    private String description; 
} 

說,我要做一個自定義驗證的東西看起來像

@Constraint(validatedBy = CollapsedStringSizeValidator.class) 
public @interface CollapsedStringSize { 
    int min() default 0; 
    int max() default Integer.MAX_VALUE; 
} 

public class CollapsedStringSizeValidator 
    implements ConstraintValidator<CollapsedStringSize, String> { 

    @Override 
    public boolean isValid(String object, 
          ConstraintValidatorContext constraintContext) { 

     if (object == null) { 
      return true; 
     } 

     final String collapsed = new CollapsedStringAdapter().unmarshal(object); 

     // how can I get the min/mix anyway? 

     return collapsed.length() >= min && collapsed.length() <= max; 
    } 
} 

有什麼辦法/前或同時驗證驗證更改值驗證?
我是否必須堅持使用setter?

+0

請問爲什麼要在引擎驗證時更改值?你能否描述你的案例的更多信息? – 2012-03-14 09:14:23

+0

實際上,我最初的擔心是在編組爲XML之前或在保存到數據庫之前將值保留爲有效表單(摺疊/標準化)。 – 2012-03-14 10:48:34

+1

那麼,如果你可以自動計算輸入數據的「有效形式」,那麼在數據被保存到數據庫之前可以使用setter。驗證框架的主要用途是驗證無法自動糾正的數據,而不會使業務邏輯代碼複雜化。此外,驗證框架讓您只需在可測試單元中編寫驗證邏輯即可。 – 2012-03-15 02:18:50

回答

1

在您的例子中,setName()應該是:

public void setName(final String name) { 
    if (name == null) { 
     this.name = null; 
     return; 
    } 
    this.name = new CollapsedStringAdapter().unmarshal(name); 
} 

如上修改,你不必使用@CollapsedStringSize了。 @Size已足夠您的驗證。

在JPA中,如果要在JPA引擎將數據加載到實體對象後處理數據,則可以嘗試@PostLoad

+0

你說得對。我甚至不需要'null'檢查,因爲也有'@NotNull'。 JPA/JSF是否真的可以通過反射或直接將數據從DB/Facelet設置到字段中,而無需使用現有的setter方法?所以我應該考慮'@ PostLoad'除了setter? – 2012-03-15 06:36:20

+0

我對JSF不熟悉。對於JPA,請查看[此問題](http://stackoverflow.com/questions/3976469/is-hibernate-jpa-taking-in-consideration-the-transiant-modifier-not-the-anno)以獲取詳細信息 – 2012-03-15 06:49:14