代码之家  ›  专栏  ›  技术社区  ›  yali

如何解决jsf中的f:validateLength错误消息[duplicate]

jsf
  •  0
  • yali  · 技术社区  · 7 年前

    今天我要找一点关于我遇到的问题的指导。

    我所要做的是建立一个动态的页面验证和所有。最终的结果是允许用户通过管理功能配置页面上的字段。下面是我用作测试页的代码的副本,在这里我循环遍历“configured”字段并使用定义的条件写出字段。

    <ui:repeat var="field" value="#{eventMgmt.eventFields}" varStatus="status">
      <div class="formLabel">
        <h:outputLabel value="#{field.customName}:"></h:outputLabel>
      </div>
      <div class="formInput">
        <h:inputText id="inputField" style="width:# {field.fieldSize gt 0 ? field.fieldSize : 140}px;">
          <f:validateRegex  disabled="#{empty field.validationPattern}" pattern="#{field.validationPattern}"></f:validateRegex>
        </h:inputText>
        <h:message for="inputField" showDetail="true" errorClass="errorText"></h:message>
      </div>
    </ui:repeat>
    

    在页面呈现并尝试提交该字段的任何值之后,我得到以下消息“regex pattern必须设置为非空值”。这显然意味着表达式未填充。使我感兴趣的是,当计算el时,没有表达式的字段将被禁用。我也可以使用相同的代码{field.validationpattern}并将其放在页面中,页面上将会写入正确的值。

    所以,我的问题是: 1。这可能吗? 2。jsf容器在什么时候考虑绑定validate regex的模式? 三。我做错了什么?正确的方法是什么??

    我正在运行tomcat 7.0.22、mojarra 2.1.5和eclipse作为我的ide。

    0 回复  |  直到 11 年前
        1
  •  12
  •   Community Mohan Dere    9 年前

    这是由于使用 <f:validateRegex> 其属性依赖于 <ui:repeat> .

    这个 <f:xxx> 标记是标记处理程序,而不是ui组件。当要在视图生成期间生成ui组件树时,将分析和计算标记处理程序。所有el都在视图构建时进行评估。这个 <h:xxx> 标签和一些 <ui:xxx> 类标签 <ui:重复> 是用户界面组件。它们的所有EL都是在视图渲染期间计算的。

    所以在你的情况下,当 <f:validateregex> 分析并执行 #{field} 在当前EL范围内不可用,因此评估为 null .

    有几种方法可以让它发挥作用。

    • 将验证器移动到表示 Field 并引用如下:

      <h:inputText ... validator="#{field.validate}" />
      

      与在 在其中手动实例化它的类:

      public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
          if (pattern != null) {
              RegexValidator regexValidator = new RegexValidator();
              regexValidator.setPattern(pattern);
              regexValidator.validate(context, component, value);
          }
      }
      

    • 或者,包裹 #{eventMgmt.eventFields} 在一个 ListDataModel<Field> 并将验证程序绑定到 #{eventMgmt} 菜豆。这样您就可以根据行数据设置验证器的属性:

      <h:inputText ... validator="#{eventMgmt.validate}" />
      

      在后面的backing bean类中 {{事件MGMt} :

      private DataModel<Field> model;
      private RegexValidator regexValidator;
      
      @PostConstruct
      public void init() {
          regexValidator = new RegexValidator();
      }
      
      public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
          String pattern = model.getRowData().getPattern();
      
          if (pattern != null) {
              regexValidator.setPattern(pattern);
              regexValidator.validate(context, component, value);
          }
      }
      

    • 或者,创建一个自定义 Validator 延伸的 RegexValidator 并将模式设置为组件的自定义属性 <f:attribute> 验证器 截获。这个 <F:属性> 基本上在组件中添加一个新属性 ValueExpression ,因此在调用时将重新评估它。例如。:

      <h:inputText ...>
          <f:validator validatorId="extendedRegexValidator" />
          <f:attribute name="pattern" value="#{field.pattern}" />
      </h:inputText>
      

      具有

      @FacesValidator("extendedRegexValidator")
      public class ExtendedRegexValidator extends RegexValidator {
      
          @Override
          public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
              String pattern = (String) component.getAttributes().get("pattern");
      
              if (pattern != null) {
                  setPattern(pattern);
                  super.validate(context, component, value);
              }
          }
      
      }
      

    • 或者,如果您碰巧使用jsf实用程序库 OmniFaces 使用它的 <o:validator> . 例如。

      <h:inputText ...>
          <o:validator validatorId="javax.faces.RegularExpression" pattern="#{field.pattern}" />
      </h:inputText>
      

      是的,就这些。这个 <o:验证器> 将确保所有属性都计算为延迟表达式而不是立即表达式。

    参见:

    推荐文章