在gwt开发模式下运行时,客户端bean验证的行为与编译模式不同。我一直在试图调试和解决这个问题几个小时(实际上几天),但是,虽然进一步仍然没有找到根本原因,我目前卡住了。因此我请求帮助。
总的来说,我一直遵循这里提倡的方法http://www.gwtproject.org/doc/latest/DevGuideValidation.html并且从StackOverlow上的各种文章和问题中得到了更多的启发。我让用户在客户端输入一个对象。然后在客户端通过调用验证器工厂创建的验证器来验证它。
我遇到的问题是,当一个以上的约束被验证(即用户输入2或更多的"错误")验证器不(总是)返回所有约束违规时运行在编译模式,而它确实返回所有时运行在gwt开发模式。
我尝试验证的对象属于类EnvyMonUser
@Entity
public class EnvyMonUser implements Serializable, Obj<EnvyMonUser> {
private static final long serialVersionUID = 3L;
private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@"
+ "[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$";
@Id
private Long id;
@NotNull(message = "company must be selected")
@Index
private Key<Company> companyKey;
@Index
private String googleUserId;
@NotNull(message = "email address must be set")
@Pattern(regexp = EMAIL_PATTERN, message = "invalid email address")
@Index
private String email;
@NotNull(message = "name must be set")
@Size(min = 3, message = "must have a name of minimal 3 characters")
@Index
private String nickName;
@NotNull(message = "location must be selected")
@Index
private Key<SampleLocation> sampleLocationKey;
@NotNull(message = "result must be set")
@Index
private Long value;
...
其中Company
和SampleLocation
是另外两个类。(注释@Entity, @Index, @Id和类Key属于Objectify。我使用相同的实体类客户端和服务器端(gae)。
一旦用户输入了一个EnvyMonUser对象,我将通过验证器验证它,即
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
...
EnvyMonUser obj = getView().getEditorDriver().flush();
Set<ConstraintViolation<O>> validate = validator.validate(obj);
,我的验证工厂是
public final class AppValidatorFactory extends AbstractGwtValidatorFactory {
@GwtValidation(value = { MonitorType.class, Measurement.class,
ProgramMeasurement.class, EnvyMonUser.class, Company.class,
SampleLocation.class })
public interface GwtValidator extends Validator {
}
@Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
我做错了什么吗?
绝望,我试图删除和添加几个字段,但没有发现任何逻辑模式。根据我遗漏的字段以及用户正确填充的字段,编译模式中的(缺失的)约束会发生变化。
我已经尝试了多种路线,但迄今为止还没有成功。例如,在某些时候,我认为这是由使用物化引起的。但是,当我删除sampleLocationKey
成员时,它对companyKey成员工作得很好。我也试过删除objectify属性,但这似乎也没有什么不同。
我观察到的一个有趣的事情(偶然)是,当我从hashCode
和equals
方法中删除(注释)一些成员时,行为发生了变化。不知道为什么会这样。也许这与验证器生成器的实现方式有关。
有人知道吗?
还需要正确方向的指针。例如,有人知道我在哪里可以找到生成的验证器吗?或者验证器生成器的源?
我使用的库的一些版本:
- gwt 2.6.0
- hibernate-validator-4.1.0.Final.jar
- hibernate-validator-4.1.0.Final-sources.jar
- slf4j-api-1.6.1.jar
- slf4j-log4j12-1.6.1.jar
- log4j-1.2.16.jar
- objectify 4.0.1
问题不在我的代码中,而是com.google.gwt.validation.client.impl.ConstraintViolationImpl
的gwt源代码中的错误。见https://groups.google.com/forum/# !
我也有同样的问题。在开发模式下,验证工作正常,所有的错误信息都显示在UI上,但在prod模式下,我们一次只能看到一个错误信息。后来在调试时发现我的DTO实现了equals和hashcode方法,这就是导致这个问题的原因。从我的DTO中删除这两个实现的那一刻起,一切都工作得很好。
我使用的是GWT 2.6.1