2012-03-14 36 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