在GWT中使用JSR-303进行内联验证,第1部分:对TextBox的验证失败.为什么? [英] Inline validation using JSR-303 in GWT, part 1: Validation on TextBox fails. Why?

查看:74
本文介绍了在GWT中使用JSR-303进行内联验证,第1部分:对TextBox的验证失败.为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用

I want to perform inline validation on the fields in a form, using JSR-303. By inline (aka on-the-fly) validation, I mean that each field is validated as the user works through the form (e.g. on blur or on key press), as opposed to deferring validation until a submit button is pressed. Typically, error messages are displayed near the input field.

我正在按照中描述的步骤进行操作GWT验证开发指南 其中的示例显示了为Person类中的字段(在本例中为一个字段,name)定义了JSR-303约束:

I'm following the procedures described in GWT validation dev guide where an example shows JSR-303 constraints being defined for the fields (in this case just one field, name) in a Person class:

// 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)是这样指定的:

The class(es) (just Person in this case) to be validated are specified like this:

// 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,要在其上执行内联验证. 我试图定义这样的约束:

Suppose I have a TextBox on which I want to perform inline validation. I attempt to define constraints like this:

// 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中具有相应的定义:

with the corresponding definition in MyValidatorFactory:

// Example of code that does not work!
@GwtValidation(FooWidget.class)
public interface GwtValidator extends Validator {
}

但是,它不能编译(我正在使用GWT 2.7.0),从而产生以下错误:

However, this does not compile (I'm using GWT 2.7.0), producing the following errors:

   [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

这是怎么回事,为什么这行不通?

What's going on here and why doesn't this work?

错误消息指的是生成的源代码. 我想知道如何将它们与我的源代码关联. 在不确切了解损坏之处的情况下,人们求助于实验性更改以寻找解决方法:-(.

The error messages refer to generated source code. I'd like to know how to relate them to my source code. Without understanding exactly what is broken, one resorts to experimental changes in search of a fix :-( .

这些实验性变化之一产生了似乎起作用的东西. 我对此发布了另一个问题: 在GWT中使用JSR-303进行内联验证,第2部分:良好的实现?,因此,如果想提出如何进行内联的建议验证,也许看看这个问题. 这个问题是关于理解为什么在FooWidget中放置约束的方法不起作用的原因.

One of those experimental changes has produced something that seems to work. I've posted another question about that: Inline validation using JSR-303 in GWT, part 2: A good implementation?, so if want to suggest how to do inline validation, maybe look at that question. This question is about understanding why the approach of putting constraints inside my FooWidget does not work.

进一步的细节:我知道要验证的类应该实现Serializable,因为不这样做就意味着它不是Java Bean.但是,在网络上有许多尚未完成的示例.有关系吗?

One further detail: I know that the class to be validated should implement Serializable, as not to do so means it isn't a Java Bean. But there are plenty of examples on the web where that hasn't been done. Does it matter?

推荐答案

Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.myco.myapp.FooWidget

您必须在调用GWT编译器之前将类编译(javac)(并将它们放在其类路径中).

You have to compile (javac) your classes before calling the GWT Compiler (and put them in its classpath).

(注意:GWT验证生成器可能应该尝试从GWT内部的TypeOracle而不是从类加载器中加载类;还请注意,几乎没有维护GWT-Validation支持–最近有人自愿维护它,但是没有还没有做出很大贡献)

(note: the GWT validation generator should probably try to load the class from GWT's internal TypeOracle rather than from the classloader; also note that GWT-Validation support is almost unmaintained – someone recently volunteered to maintain it, but hasn't contributed much yet)

这篇关于在GWT中使用JSR-303进行内联验证,第1部分:对TextBox的验证失败.为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆