【问题标题】:how to use a seam validator in jsf?如何在 jsf 中使用接缝验证器?
【发布时间】:2011-06-16 16:34:38
【问题描述】:

我制作了一个新的 Seam 验证器:

    package validators;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.faces.Validator;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;

@Name("roCountyValidator")
@Validator
@BypassInterceptors
public class RoCountyValidator implements javax.faces.validator.Validator,
        Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -3876319398131645955L;
    Log log = Logging.getLog(RoCountyValidator.class);

    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {
        log.info("validating....!");
        if (String.valueOf(value).equals("Arad"))
            ((UIInput) component).setValid(true);
        else {
            ((UIInput) component).setValid(false);
            FacesMessage message = new FacesMessage();
            message.setDetail("Invalid county");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(message);
        }
    }
}

问题是我不知道如何直接从jsf中使用它...

以下不起作用....

我已经在一个特殊的 taglib 文件中声明了它:myvalidators.taglib.xml

<facelet-taglib>
<namespace>http://example.com/jsf/my/validators</namespace>
<tag>
    <tag-name>roCountyValidator</tag-name>
    <validator>
        <validator-id>roCountyValidator</validator-id>
    </validator>
</tag>

并尝试像这样使用它:

<h:inputText id="someField" value="#{booking.creditCardName}" 
                               required="true" label="County">
                <my:roCountyValidator/>
                <h:message for="someField"/>
            </h:inputText>

你能告诉我哪里错了吗?

谢谢。

【问题讨论】:

    标签: java jsf seam validation


    【解决方案1】:

    解决这个问题的两种方法。

    一个,是使用@BalusC 所写的。 你不需要在 faces-config.xml 中定义任何东西

    <h:inputText id="cc" required="true" value="#{booking.creditCardName}">
                    <f:validator validatorId="roCountyValidator"/>
                    <f:attribute name="oldCreditCardNumber" value="#{booking.creditCardName}" />
                    <s:validate />
    </h:inputText>
    

    在这里你甚至可以绑定旧的信用卡号码,如果你也想检查的话。

    然后在您的验证方法中:

    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {
        log.info("validating....!");
    
        String oldCreditcard = String.valueOf(component.getAttributes().get("oldCreditCardNumber"));
        String newCreditCard = (String) value;
        if(SomeClass.isCorrectCreditcard(newCreditCard)) {
            //You don't need to setValid(false), this is done automatically
            Map<String, String> messages = Messages.instance();
                throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, messages.get("wrongCreditCardNumber"), messages
                        .get("wrongCreditCardNumber")));
    
        }
    }
    



    另一种方法是在&lt;h:inputText&gt;中使用validator标签

    您甚至不需要创建@Validator 类,只要它是一个接缝组件并且您使用相同的方法签名即可。

    我对所有通用验证器都使用了一个验证器组件

    @Name("validator")
    @Scope(ScopeType.EVENT)
    @BypassInterceptors
    public class Validator {
    
    public void positiveInteger(FacesContext context, UIComponent toValidate, Object value) {
            String val = (String) value;
    
            try {
                int v = Integer.parseInt(val);
                if (v < 0)
                    throw new NumberFormatException();
            } catch (NumberFormatException e) {
                ((UIInput) toValidate).setValid(false);
                FacesMessages.instance().addToControlFromResourceBundle(toValidate.getId(), "invalid.integer");
            }
        }
    }
    

    现在你可以添加验证器了:

    <h:inputText value="#{foo.bar}" required="true" validator="#{validator.positiveInteger}">
      <s:validate/>
    <h:inputText>
    

    【讨论】:

    • 很好的例子。所以关键是如果你在绑定验证器时使用 EL,你必须使用一个方法并调用 s:validate。谢谢。
    • 是的。您必须使用 s:validate 让 seam 知道要对其进行验证
    【解决方案2】:

    我不知道 Seam 部分,它可能有不同的方法,但在标准 JSF 中,您通常faces-config.xml 中将其定义为 &lt;validator&gt;

    <validator>
        <validator-id>roCountyValidator</validator-id>
        <validator-class>validators.RoCountyValidator</validator-class>
    </validator>
    

    并按如下方式使用:

    <h:inputText>
        <f:validator validatorId="roCountyValidator" />
    </h:inputText>
    

    【讨论】:

    • 是的,我知道在 JSF 中,但我想像 Seam 一样使用它,特别是因为 Seam 具有 @Validator 功能,所以它一定是某个地方的诡计......但是谢谢。
    • 为此创建一个完整的标签库似乎不必要地过度复杂化。顺便说一句,JSF 2.0 有一个 @FacesValidator,这使得 &lt;validator&gt; 也变得不必要了。
    【解决方案3】:

    找到解决方案:)。

    忘记标签库和其他东西!

    像这样使用它:

    <h:inputText id="someField" value="#{booking.creditCardName}" 
                                   required="true" label="County" validator="roCountyValidator">
                    <h:message for="someField"/>
                </h:inputText>
    

    请注意

    validator="roCountyValidator"
    

    它不应该像EL表达式一样使用!!! (我的第一个错误决定)

    所以使用 Seam + @Validator 的优势:Seam 将在后台将该组件转换为 jsf 验证器,因此您不再需要 jsf 验证器标签或 faces-config.xml 中的任何其他配置。

    【讨论】:

      猜你喜欢
      • 2013-01-23
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 2012-05-17
      • 1970-01-01
      • 2012-02-12
      • 2013-07-25
      相关资源
      最近更新 更多