java - 如何将 validator 指定为自定义控件的属性

标签 java validation custom-controls xpages

我正在构建一个自定义控件来格式化我的 Bootstrap 输入控件。我验证数据的方式我有一个带有验证方法的 bean(遵循 validator 的方法签名)。但是,我找不到通过自定义控件属性指定 validator 的方法...

这是“正常的”inputText 控件:

<xp:inputText xp:key="inputControl" id="inputCity" value="#{User.user.city}"
    validator="#{User.validate}">
    <xp:this.attrs>
        <xp:attr name="placeholder" value="Enter city"></xp:attr>
    </xp:this.attrs>
            <xp:this.validators>
                <xp:validateRequired message="You must enter a city"></xp:validateRequired>
            </xp:this.validators>
</xp:inputText>

这是来自自定义控件的:

<xp:inputText type="text" id="inputText1" value="#{compositeData.dataSource[compositeData.fieldName]}"
    required="${compositeData.required}" disableClientSideValidation="true" validator="${compositeData.dataValidator}">
    <xp:this.attrs>
        <xp:attr name="placeHolder" value="${compositeData.placeHolder}"></xp:attr>
    </xp:this.attrs>
    <xp:this.validators>
        <xp:validateRequired message="${compositeData.helpText}"></xp:validateRequired>
    </xp:this.validators>
</xp:inputText>
<xp:message id="message1" for="inputText1"></xp:message>

... 在 XPage 上我尝试这样调用它:

<xc:field fieldName="city" dataSource="#{User.user}" placeHolder="Enter city" fieldLabel="City" required="true"
    helpText="You must enter a city" dataValidator="#{User.validate}">
</xc:field>

“dataValidator”被指定为“com.ibm.xsp.validator.ValidatorImpl”——我也尝试过使用“object”……——但同样的错误 500:

> Page Name: /editUser.xsp javax.faces.el.PropertyNotFoundException:
> Error getting property 'validate' from bean of type
> dk.dtu.aqua.catchlog.bean.UserBean    at
> com.sun.faces.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:119)
>   at
> com.ibm.xsp.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:144)

很明显,自定义控件试图将其作为属性读取(通过隐式“getter”)。

有什么想法吗??

编辑:

好的,在与 Toby Samples 来回写了一些内容之后,我尝试将 bean 注册为 faces-config.xml 中的 validator 并给它一个 id。这似乎奏效了 - 在某种程度上。

在自定义控件中,我删除了“validator”属性并在 attrs 下添加了一个“validator”:

<xp:validator validatorId="${compositeData.validatorId}"></xp:validator>

在我从 XPage 调用它的地方我添加了新属性(作为字符串):

<xc:field fieldName="city" dataSource="#{User.user}" placeHolder="Enter city" fieldLabel="City" required="true"
    helpText="You must enter a city" validatorId="userValidator">
</xc:field>

但是,我真正想要的是使用一个包含所有 Bootstrap 格式的通用 CC,以及一个可以放置各种输入类型(例如 inputText、comboBox 等)的可编辑区域。这样 Bootstrap 标记的结构是相同的,而无需一遍又一遍地复制相同的代码。

因此,如果我创建一个新的 CC,请使用以下内容(为简单起见)说 fieldLayout:

<xp:label value="#{compositeData.label}" for="#{compositeData.inputField}"></xp:label>
<xp:div styleClass="col-sm-6">
    <xp:callback facetName="inputControl" id="callback1"></xp:callback>
</xp:div>

然后将它放到我的字段 CC(在开头提到)中,我将所有的都放入可编辑区域 - 具有相同的属性等,这样它现在看起来像这样:

<xc:fieldLayout label="#{compositeData.label}" inputField="inputText1">
    <xp:this.facets>
        <xp:inputText xp:key="inputControl" type="text" id="inputText1" value="#{compositeData.dataSource[compositeData.fieldName]}"
            required="${compositeData.required}" disableClientSideValidation="true">
            <xp:this.attrs>
                <xp:attr name="placeHolder" value="${compositeData.placeHolder}"></xp:attr>
            </xp:this.attrs>
            <xp:this.validators>
                <xp:validator validatorId="${compositeData.validatorId}"></xp:validator>
                <xp:validateRequired message="You must enter something"></xp:validateRequired>
            </xp:this.validators>
        </xp:inputText>
        <xp:message id="message1" for="inputText1"></xp:message>
    </xp:this.facets>
</xc:fieldLayout>

然后失败....并出现以下错误:

Caused by: java.lang.NullPointerException: Argument Error: One or more parameters are null. validatorId null
    at com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:630)
    at com.ibm.xsp.application.ApplicationExImpl.createValidator(ApplicationExImpl.java:1161)
    at com.ibm.xsp.validator.ValidatorImpl.getValidator(ValidatorImpl.java:75)
    at com.ibm.xsp.validator.ValidatorImpl.validate(ValidatorImpl.java:48)
    at javax.faces.component.UIInput.validateValue(UIInput.java:828)

这可能与 compositeData.validatorId 现在在另一个 CC 的构面内的 inputText 中引用的事实直接相关。请注意,我将“validateRequired”消息更改为字符串文字。因此,当我在没有输入任何内容的情况下进行测试时,它会给我该消息。如果我只输入一个字符,它会改为调用 validator - 或尝试,因为这样会抛出异常...... :-(

有什么想法吗?这会严重影响自定义控件的使用 - 除非我做的完全错误...?

/约翰

最佳答案

您可以尝试在 xp:validator validator 中使用 validatorId。

人脸配置

  <validator>
    <validator-id>val</validator-id>
    <validator-class>com.tobysamples.validators.user</validator-class>
</validator>

自定义控件

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:inputText>
        <xp:this.validators>
            <xp:validator validatorId="${compositeData.val}"></xp:validator>
        </xp:this.validators></xp:inputText>
</xp:view>

X页面

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xc="http://www.ibm.com/xsp/custom">

    <xc:inputfield val="val">
    </xc:inputfield>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:button value="Label" id="button1">
        <xp:eventHandler event="onclick" submit="true"
            refreshMode="complete">
        </xp:eventHandler></xp:button></xp:view>

自定义控件定义

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
  <faces-config-extension>
    <namespace-uri>http://www.ibm.com/xsp/custom</namespace-uri>
    <default-prefix>xc</default-prefix>
  </faces-config-extension>
  <composite-component>
    <component-type>inputfield</component-type>
    <composite-name>inputfield</composite-name>
    <composite-file>/inputfield.xsp</composite-file>
    <composite-extension>
      <designer-extension>
        <in-palette>true</in-palette>
      </designer-extension>
    </composite-extension>
    <property>
      <property-name>val</property-name>
      <property-class>string</property-class>
      <display-name>val</display-name>
      <property-extension>
        <designer-extension>
          <editor>com.ibm.std.String</editor>
        </designer-extension>
      </property-extension>
    </property>
  </composite-component>
</faces-config>

新的二次抄送

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
<xc:field val2="${compositeData.val}">
    <xp:this.facets>
    <xp:inputText xp:key="inputControl">
        <xp:this.validators>
            <xp:validator validatorId="${compositeData.val2}"></xp:validator>
        </xp:this.validators></xp:inputText>
        </xp:this.facets>
        </xc:field>
</xp:view>

关于java - 如何将 validator 指定为自定义控件的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21607408/

相关文章:

java - 反序列化对象图时 hashCode() 中的 NullPointerException

java - Hibernate SessionFactory 到 Spring

android - 验证由 ViewPager 托管的多个 fragment 上的字段

javascript - $rootScope :infdig error in AngularJS when using ng-disabled to validate a collection of elements

javascript - 如何使用自定义控件在谷歌地图中获取用户输入?

c# - 模拟管理系统?

java - 即使在运行时请求权限后如何解决 "Access Denied"错误

JavaScript Date 对象无法处理传递给它的字符串

c# - Picturebox 中的可移动 FrameControl 无法按预期工作

wpf - 基于 LOCBaml 或 Resx 的本地化的最佳本地化方法是什么?