我正在使用以下技术的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属性? 谢谢
答案 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:inputText
和h: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));
}
}
}
}
}
答案 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吗?