【问题标题】:How to use the GWT editor framework for validation?如何使用 GWT 编辑器框架进行验证?
【发布时间】:2011-05-05 03:46:01
【问题描述】:

我正在尝试与 GWT 2.1.0 的新 GWT 编辑器框架集成。我还想将我的验证检查添加到框架中。但是,我正在努力寻找如何做到这一点的体面示例。

目前我有以下代码:

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:e="urn:import:com.google.gwt.editor.ui.client">
    <ui:with type="be.credoc.iov.webapp.client.MessageConstants"
        field="msg" />
    <g:HTMLPanel>
        <e:ValueBoxEditorDecorator ui:field="personalReference">
            <e:valuebox>
                <g:TextBox />
            </e:valuebox>
        </e:ValueBoxEditorDecorator>
    </g:HTMLPanel>
</ui:UiBinder> 

对于我的编辑:

public class GarageEditor extends Composite implements Editor<Garage> {

    @UiField
    ValueBoxEditorDecorator<String> personalReference;

    interface GarageEditorUiBinder extends UiBinder<Widget, GarageEditor> {
    }

    private static GarageEditorUiBinder uiBinder = GWT.create(GarageEditorUiBinder.class);

    public GarageEditor() {
        initWidget(uiBinder.createAndBindUi(this));
    }

}

我必须在什么时候调用我的验证器以及如何与它集成?

更新:

我实际上正在寻找一种方法来检索以属性路径为键并以编辑器为值的地图。委托上有一个路径字段,但这不是编辑对象内的路径,而是编辑器类中的路径。

有人知道是否可以做这样的事情吗?

【问题讨论】:

    标签: java gwt editor uibinder gwt2


    【解决方案1】:

    用 contstrants 注释你的 bean(见 Person.java)

    public class Person {
      @Size(min = 4)
      private String name;
    }
    

    使用标准验证引导程序在客户端获取验证器并验证您的对象(请参阅ValidationView.java)

    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    Set<ConstraintViolation<Person>> violations = validator.validate(person);
    

    按照此模式为要在客户端验证的对象创建验证器。 (见SampleValidatorFactory.java)

    public final class SampleValidatorFactory extends AbstractGwtValidatorFactory {
    
      /**
       * Validator marker for the Validation Sample project. Only the classes listed
       * in the {@link GwtValidation} annotation can be validated.
       */
      @GwtValidation(value = Person.class,
          groups = {Default.class, ClientGroup.class})
      public interface GwtValidator extends Validator {
      }
    
      @Override
      public AbstractGwtValidator createValidator() {
        return GWT.create(GwtValidator.class);
      }
    }
    

    包括您的验证提供程序的模块。在您的 gwt 模型文件中添加替换标记,告诉 GWT 使用您刚刚定义的验证器(请参阅Validation.gwt.xml)

    <inherits name="org.hibernate.validator.HibernateValidator" />
    <replace-with
        class="com.google.gwt.sample.validation.client.SampleValidatorFactory">
        <when-type-is class="javax.validation.ValidatorFactory" />
    </replace-with>
    

    Source

    【讨论】:

    • 太糟糕了,这还没有绑定到编辑器框架,在输入字段旁边提供验证消息。
    • 从 gwt-2.4.0-rc1 开始,已经进行了尝试:请参阅 com.google.gwt.editor.client.impl.BaseEditorDriver.setConstraintViolations(...) 无法在客户端使用一方面由于方法参数中的怪异泛型。
    【解决方案2】:

    我通过添加一个额外的 DriverWrapper 类来完成类似的操作,该类采用现有的 Driver 和 Validator 并添加一个 flush 方法,该方法首先委托给底层 Driver flush 然后调用 Validator。然后使用新访问者将返回的任何错误添加到编辑器,类似于现有 Flusher 的工作方式。这意味着在字段旁边显示错误的现有装饰器继续工作。

    /**
     * Wraps a Driver and provides validation using gwt-validation (JSR 303).
     * When calling flush, this will use the provided IValidator to validate the data
     * and use the InvalidConstraintValidationVisitor to add the errors to the delegates.
     * @see InvalidConstraintValidationVisitor
     * @param <T> the data type for the editor
     * @param <D> the driver type
     */
    public class ValidationDriverWrapper<T extends IsValidatable<T>, D extends EditorDriver<T>> {
    private IValidator<T> validator;
    private D driver;
    
    /**
     * Constructor, both parameters are required.
     * @param driver The driver to use to flush the underlying data.
     * @param validator The validator to use to validate the data.
     */
    public ValidationDriverWrapper(D driver, IValidator<T> validator) {
        this.validator = validator;
        this.driver = driver;
    }
    
    /**
     * Flushes the underlying Driver and then calls the validation on the underlying Validator, cascading errors as EditorErrors
     * onto the delegates, using InvalidContraintValidationVisitor.
     */
    public void flush()
    {
        T data = driver.flush();
        Set<InvalidConstraint<T>> errors = validator.validate(data);
        Set<InvalidConstraint<T>> extraErrors = data.validate();
        if(extraErrors != null && !extraErrors.isEmpty())
        {
            errors.addAll(extraErrors);
        }
        driver.accept(new InvalidConstraintValidationVisitor<T>(errors));
    }
    

    【讨论】:

    • 做了类似的事情来提供动态验证。得益于编辑器访问者模式,效果非常好。
    • @logan,您能否展示一下您是如何实现动态验证的?在嵌套编辑器的情况下,我很难以简洁的方式做到这一点。
    • @ruslan - 我一直在考虑将其开源,但我还没有找到时间。你还有兴趣吗?
    • @logan,当然。如果您创建 Google Code 项目,我可以从中获利。
    【解决方案3】:

    我也有同样的问题。

    文档并不清楚。

    我目前正在做的是通过使用我想要复制的小部件扩展它们来重新创建一些小部件。之后我实现 LeafValueEditor 和 HasEditorDelegate 来覆盖 getValue()。

    在 getValue() 中,使用您的验证器并在需要时调用 yourDelegate.recordError()。

    类似这样的东西:一个小整数框,检查值是否不大于 10。

    public class IntegerField extends ValueBox<Integer> implements LeafValueEditor<Integer>, HasEditorDelegate<Integer>
    {
    private EditorDelegate<Integer> delegate;
    
    public IntegerField()
    {
        super(Document.get().createTextInputElement(), IntegerRenderer.instance(), IntegerParser.instance());
    
        setStyleName("gwt-TextBox");
    
    }
    
    @Override
    public Integer getValue()
    {
        Integer value = super.getValue();
    
        if (value > 10)
        {
            delegate.recordError("too big integer !", value, null);
        }
    
        return value;
    }
    
    @Override
    public void setValue(Integer value)
    {
        super.setValue(value);
    }
    
    @Override
    public void setDelegate(EditorDelegate<Integer> delegate)
    {
        this.delegate = delegate;
    }
    }
    

    最好的方法是简单地将自定义验证添加到现有小部件而不覆盖它们,但我不知道该怎么做!

    【讨论】:

    • 我想在外部进行验证,然后添加我的验证错误。目前,我在每个编辑器中创建了一些自定义代码,以将 propertyPath 绑定到小部件。但是,此信息已经存在于系统中的某个位置,我似乎无法将其从系统中取出。
    【解决方案4】:

    GWT 中尚不存在验证,它将在下一个版本 AFAIK 中提供。 GWT 中当前对验证的支持是服务器端 JSR-303,而客户端 JSR-303 支持即将推出。因此,您必须手动进行验证。如果您遵循 MVP 模型,我认为此验证逻辑将存在于您的 Presenter 中。

    【讨论】:

    • 我正在尝试做的是将我的验证系统插入 GWT 编辑器框架。您在编辑器上有诸如 recordError 和 showErrors 之类的操作。我正在寻找正确的位置来触发验证并将我的验证错误连接到我用来配置我的编辑器的路径。
    【解决方案5】:

    这很麻烦,但要获得编辑器的路径,您可以实现 HasEditorDelegate(这将使您能够访问委托),然后将委托转换为具有公共 String getPath() 方法的 AbstractEditorDelegate。

    我认为不可能进行外部验证;验证在编辑器中从字段读取值时进行(请参阅 ValueBoxEditor - 此编辑器使用 getDelegate().recordError 引发错误)。我确实考虑过的一个选项是使用 AbstractEditorDelegate 访问来调用 flushErrors(List) 并自己创建 EditorErrors 列表。为此,您需要了解每个字段路径;对它们进行硬编码是不可取的,但我看不到通过编辑属性或类似的方式查找字段的方法。

    可能需要研究的另一种方法是使用 requestfactory 提交往返验证:

    http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/5be0bda80547ca5a

    【讨论】:

      猜你喜欢
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 2012-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多