我想使用JSR-303对表单中的字段执行内联验证。 通过内联(也称为动态)验证,我的意思是每个字段都在用户通过表单进行验证时进行验证(例如,在模糊或按键时), 而不是在按下提交按钮之前推迟验证。 通常,错误消息显示在输入字段附近。
我正在遵循GWT validation dev guide中描述的程序
其中一个示例显示了为name
类中的字段(在本例中只是一个字段Person
)定义的JSR-303约束:
// Copied from http://www.gwtproject.org/doc/latest/DevGuideValidation.html
public class Person implements Serializable {
@NotNull
@Size(min = 4, message = "Name must be at least 4 characters long.")
private String name;
}
要验证的类(在这种情况下只是Person
)如下所示:
// Copied from http://www.gwtproject.org/doc/latest/DevGuideValidation.html
public final class MyValidatorFactory extends AbstractGwtValidatorFactory {
/**
* Validator marker for the Validation Sample project. Only the classes and groups listed
* in the {@link GwtValidation} annotation can be validated.
*/
@GwtValidation(Person.class)
public interface GwtValidator extends Validator {
}
@Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
假设我有TextBox
我想在其上执行内联验证。
我试图定义这样的约束:
// Example of code that does not work!
import com.google.gwt.user.client.ui.TextBox;
import javax.validation.constraints.Pattern;
public class FooWidget extends TextBox {
@Pattern(regexp="^[0-9]+$", message="Foo: expected digits.")
public String getFoo() {
return getValue(); // from TextBox
}
}
使用MyValidatorFactory
中的相应定义:
// Example of code that does not work!
@GwtValidation(FooWidget.class)
public interface GwtValidator extends Validator {
}
但是,这不编译(我正在使用GWT 2.7.0),产生以下错误:
[ERROR] An internal compiler exception occurred
com.google.gwt.dev.jjs.InternalCompilerException: Unexpected error during visit.
at com.google.gwt.dev.jjs.ast.JVisitor.translateException(JVisitor.java:121)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:296)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:285)
at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:128)
at com.google.gwt.dev.jjs.ast.JCastOperation.traverse(JCastOperation.java:67)
at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:381)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:293)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:285)
at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:128)
at com.google.gwt.dev.jjs.ast.JDeclarationStatement.traverse(JDeclarationStatement.java:49)
at com.google.gwt.dev.jjs.ast.JModVisitor$ListContext.traverse(JModVisitor.java:95)
at com.google.gwt.dev.jjs.ast.JModVisitor.acceptWithInsertRemove(JModVisitor.java:351)
at com.google.gwt.dev.jjs.ast.JBlock.traverse(JBlock.java:92)
at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:381)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:293)
at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:149)
at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:145)
at com.google.gwt.dev.jjs.ast.JMethodBody.traverse(JMethodBody.java:83)
at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:381)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:293)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:285)
at com.google.gwt.dev.jjs.ast.JMethod.visitChildren(JMethod.java:600)
at com.google.gwt.dev.jjs.ast.JMethod.traverse(JMethod.java:569)
at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:381)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:293)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:285)
at com.google.gwt.dev.jjs.impl.UnifyAst.mainLoop(UnifyAst.java:1505)
at com.google.gwt.dev.jjs.impl.UnifyAst.exec(UnifyAst.java:870)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler$Precompiler.unifyJavaAst(JavaToJavaScriptCompiler.java:1305)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler$Precompiler.constructJavaAst(JavaToJavaScriptCompiler.java:1038)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler$Precompiler.precompile(JavaToJavaScriptCompiler.java:954)
at com.google.gwt.dev.jjs.MonolithicJavaToJavaScriptCompiler.precompile(MonolithicJavaToJavaScriptCompiler.java:303)
at com.google.gwt.dev.jjs.JavaScriptCompiler.precompile(JavaScriptCompiler.java:38)
at com.google.gwt.dev.Precompile.precompile(Precompile.java:286)
at com.google.gwt.dev.Precompile.precompile(Precompile.java:229)
at com.google.gwt.dev.Precompile.precompile(Precompile.java:145)
at com.google.gwt.dev.Compiler.run(Compiler.java:206)
at com.google.gwt.dev.codeserver.Recompiler.doCompile(Recompiler.java:333)
at com.google.gwt.dev.codeserver.Recompiler.compile(Recompiler.java:161)
at com.google.gwt.dev.codeserver.Recompiler.recompile(Recompiler.java:119)
at com.google.gwt.dev.codeserver.Outbox.recompile(Outbox.java:128)
at com.google.gwt.dev.codeserver.JobRunner.recompile(JobRunner.java:81)
at com.google.gwt.dev.codeserver.JobRunner.access$100(JobRunner.java:34)
at com.google.gwt.dev.codeserver.JobRunner$2.run(JobRunner.java:73)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.myco.myapp.FooWidget
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:260)
at com.google.gwt.validation.rebind.BeanHelperCache.createHelper(BeanHelperCache.java:85)
at com.google.gwt.validation.rebind.ValidatorGenerator.generateGwtSpecificValidator(ValidatorGenerator.java:131)
at com.google.gwt.validation.rebind.ValidatorGenerator.generate(ValidatorGenerator.java:67)
at com.google.gwt.core.ext.IncrementalGenerator.generateNonIncrementally(IncrementalGenerator.java:40)
at com.google.gwt.dev.javac.StandardGeneratorContext.runGeneratorIncrementally(StandardGeneratorContext.java:760)
at com.google.gwt.dev.cfg.RuleGenerateWith.realize(RuleGenerateWith.java:160)
at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.rebind(StandardRebindOracle.java:79)
at com.google.gwt.dev.shell.StandardRebindOracle.rebind(StandardRebindOracle.java:276)
at com.google.gwt.dev.shell.StandardRebindOracle.rebind(StandardRebindOracle.java:265)
at com.google.gwt.dev.DistillerRebindPermutationOracle.getAllPossibleRebindAnswers(DistillerRebindPermutationOracle.java:87)
at com.google.gwt.dev.jjs.impl.UnifyAst$UnifyVisitor.createStaticRebindExpression(UnifyAst.java:485)
at com.google.gwt.dev.jjs.impl.UnifyAst$UnifyVisitor.createRebindExpression(UnifyAst.java:443)
at com.google.gwt.dev.jjs.impl.UnifyAst$UnifyVisitor.handleMagicMethodCall(UnifyAst.java:576)
at com.google.gwt.dev.jjs.impl.UnifyAst$UnifyVisitor.endVisit(UnifyAst.java:306)
at com.google.gwt.dev.jjs.ast.JMethodCall.traverse(JMethodCall.java:248)
at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:381)
at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:293)
... 47 more
[ERROR] at _FooWidgetValidator.java(6): GWT.create(_FooWidgetValidator.class)
com.google.gwt.dev.jjs.ast.JMethodCall
[ERROR] at _FooWidgetValidator.java(6): (_FooWidgetValidator) GWT.create(_FooWidgetValidator.class)
com.google.gwt.dev.jjs.ast.JCastOperation
[ERROR] at _FooWidgetValidator.java(6): final static _FooWidgetValidator INSTANCE = (_FooWidgetValidator) GWT.create(_FooWidgetValidator.class)
com.google.gwt.dev.jjs.ast.JDeclarationStatement
[ERROR] at _FooWidgetValidator.java(5): {
final static _FooWidgetValidator INSTANCE = (_FooWidgetValidator) GWT.create(_FooWidgetValidator.class);
}
com.google.gwt.dev.jjs.ast.JBlock
[ERROR] at _FooWidgetValidator.java(5): {
final static _FooWidgetValidator INSTANCE = (_FooWidgetValidator) GWT.create(_FooWidgetValidator.class);
}
com.google.gwt.dev.jjs.ast.JMethodBody
[ERROR] at _FooWidgetValidator.java(5): private static final void $clinit();
com.google.gwt.dev.jjs.ast.JMethod
[ERROR] Compiler returned false
这里发生了什么,为什么这不起作用?
错误消息是指生成的源代码。 我想知道如何将它们与我的源代码联系起来。 如果不确切地知道什么是坏的,人们就会寻求修复的实验性变化:-(。
其中一项实验性改变产生了似乎有用的东西。 我发布了另一个问题: Inline validation using JSR-303 in GWT, part 2: A good implementation?,所以如果想建议如何进行内联验证,可以查看该问题。 这个问题是关于理解为什么在我的FooWidget中放置约束的方法不起作用。
进一步的细节:我知道要验证的类应该实现Serializable,因为不这样做意味着它不是Java Bean。但网上有很多例子尚未完成。这有关系吗?
答案 0 :(得分:1)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.myco.myapp.FooWidget
在调用GWT编译器之前必须编译(javac
)类(并将它们放在类路径中)。
(注意:GWT验证生成器应该尝试从GWT的内部TypeOracle
而不是从类加载器加载类;还要注意GWT-Validation支持几乎没有维护 - 有人最近自愿加入保持它,但还没有贡献很多)