JSF Validator和outputLabel

时间:2017-08-19 21:53:57

标签: jsf primefaces jsf-2.2

我正在使用以下技术的Web应用程序 春天4.3 JSF 2.2.14 PrimeFaces 6.1 Omnifaces 2.6.4

我需要验证一个h:inputText,我正在尝试使用javax.faces.validator.Validator接口。

一切运行良好但是当验证失败时,我无法检索字段的标签,该标签使用“for”属性存储在p:outputLabel中。

Facelets代码

public void validate(FacesContext context, UIComponent component, Object value) {
        if (value != null) {
            String v = value.toString();
            if (StringUtils.isNotEmpty(v)) {
                try {
                    BigDecimal bd = new BigDecimal(v);
                    if(bd.compareTo(BigDecimal.ZERO) <= 0){
                        // how to retrieve the field label???
                        FacesMessage msg = new FacesMessage("messageWithout label", "messageWithout label");
                        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                        throw new ValidatorException(msg, new IllegalArgumentException(exceptionMessage));
                    }
                } catch (NumberFormatException e) {
                        FacesMessage msg = new FacesMessage("messageWithout label", "messageWithout label");
                        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                        throw new ValidatorException(msg, new IllegalArgumentException(exceptionMessage));
                }

            }
        }
    }

验证器 - 验证方法

public class ConsumersFileController : Controller
{
    private readonly TDCContext _db = new TDCContext();


    public ActionResult Index()
    {
        IEnumerable<Consumer> list = _db.Consumers.ToList();

        //put List in memory stream object
        MemoryStream memoryStream = new MemoryStream();
        using (memoryStream)
        {
            //return memory stream as file stream result:
            using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream, System.Text.Encoding.UTF8, true))
            {
                foreach (var item in list)
                {
                    var itemBytes = item.Serialize();
                    binaryWriter.Write(itemBytes.Length);
                    binaryWriter.Write(itemBytes);

                }

                FileStreamResult fileStream =
                    new FileStreamResult(memoryStream, "application/txt") {FileDownloadName = "zips.csv"};

                return fileStream;
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _db.Dispose();
        }
        base.Dispose(disposing);
    }

}

如何检索链接到未通过验证的h:inputText的p:outputLabel的value属性? 谢谢

2 个答案:

答案 0 :(得分:1)

根据Primefaces User's Guide --> 3.93 OutputLabel

  

自动标签
  OutputLabel将其值设置为要在验证错误中显示的目标组件的标签,以便显示目标组件   不需要再次定义label属性。

<h:outputLabel for="input" value="Field" />
<p:inputText id="input" value="#{bean.text}" label="Field"/>
     

可以改写为;

<p:outputLabel for="input" value="Field" />
<p:inputText id="input" value="#{bean.text}" />

这意味着,OutputLabel只是设置标签所附加组件的label属性。

只需在验证器中检索此attributte,例如以这种方式:

public void validate(FacesContext context, UIComponent component, Object value) {

    Object labelObj = component.getAttributes().get("label");
    String label = (labelObj!=null) ? labelObj.toString() : "Unknown label";
    .....
    .....
    // how to retrieve the field label???
    String message = String.format("%s : My conversion error message", label);
    FacesMessage msg = new FacesMessage(message,message) ;
    .....
    ..... 

我已对其进行了测试,它适用于p:inputTexth:inputText组件。

  

嗨,我调试了代码和component.getAttributes()。get(“label”)   为空

我已经在JSF 2.2 / Primefaces 6.1 / Wildfy 10.x上再次测试了它并且它有效 这是一个关于GitHub link的简单演示项目

的index.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">

<h:head></h:head>
<h:body>
    <h:form>
        <p:panel id="panel" header="Form" style="margin-bottom:10px;">
            <p:messages id="messages" />

            <h:panelGrid columns="2" cellpadding="5">

                <p:outputLabel id="label1_id"
                    for="input1_id" value="This Is My label for h:input" />

                <h:inputText id="input1_id" value="#{myBean.price1}"
                    required="true" >
                    <f:validator validatorId="MyValidator" />
                </h:inputText>

                <p:outputLabel id="label2_id"
                    for="input2_id" value="This Is My label for p:input" />

                <p:inputText id="input2_id" value="#{myBean.price2}" required="true">
                    <f:validator validatorId="MyValidator" />
                </p:inputText>

            </h:panelGrid>
            <p:commandButton update="panel" value="Submit" />

        </p:panel>
    </h:form>
</h:body>
</html>

<强>豆

@Named
@SessionScoped
public class MyBean implements Serializable {

    private static final long serialVersionUID = 5455916691447931918L;

    private Integer price1;

    private Integer price2;

    public Integer getPrice2() {
        return price2;
    }

    public void setPrice2(Integer price2) {
        this.price2 = price2;
    }

    public Integer getPrice1() {
        return price1;
    }

    public void setPrice1(Integer price1) {
        this.price1 = price1;
    }
}

<强>验证

@FacesValidator("MyValidator")
public class MyValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value) {

        Object labelObj = component.getAttributes().get("label");
        String label = (labelObj!=null) ? labelObj.toString() : "Unknown label";

        if (value != null) {
            String v = value.toString();
            if (null != v && !v.isEmpty()) {
                try {
                    BigDecimal bd = new BigDecimal(v);
                    if (bd.compareTo(BigDecimal.ZERO) <= 0) {
                        // how to retrieve the field label???
                        String message = String.format("%s : Value must be greater than 0", label);
                        FacesMessage msg = new FacesMessage(message,message) ;
                        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                        throw new ValidatorException(msg, new IllegalArgumentException("Validator exception:" + message));
                    }
                } catch (NumberFormatException e) {
                    String message = String.format("%s : Value must be a number", label);
                    FacesMessage msg = new FacesMessage(message,message);
                    msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                    throw new ValidatorException(msg, new IllegalArgumentException("Validator exception:" + message));
                }
            }
        }
    }

}

结果是: enter image description here

答案 1 :(得分:0)

可能有用或常见的一些事情:

  • id移除*:outputLabel,因为不需要
  • 使用validatorMessage="#{bundle.SOME_FIELD_VALIDATION_ERROR}"来获取可本地化的消息,如果您的验证器正在抛出javax.faces.validator.ValidatorException(当然,您可以将其导入验证器类之上)
  • 删除标签检索的代码,请参阅上面的validatorMessage字段
  • <f:validator binding="#{someValidator}" />似乎会导致更多问题,常见的方法是:<f:validator validatorId="SomeFooValidator" /> *:inputText(你必须让它非自我关闭)
  • 然后使用@FacesValidator ("SomeFooValidator")javax.faces.validator.FacesValidator
  • 注释您的验证器类

您使用的是JSF2.2吗?