如何避免多次显示 FacesMessage?
How to avoid displaying of FacesMessage multiple times?
我需要为这个组件显示一个 FacesMessage
,如下所示,
问题是它多次显示在 UI 上,如下所示,
其次,输入的日期是 40.06.2015
,这是无效的,因此是 FacesMessage
,但它被转换成了 10.07.2015
。我不知道如何防止这种情况。非常感谢任何帮助。我知道可以使用 DateFormat
class 上的 setLenient()
轻松处理它,但不知何故,在它对我可用之前,UI 组件将其转换为日期下个月。
附加到该组件的验证器如下:
那么,如何避免多次显示 "Please enter date in correct format"?
我想到了使用 h:message
而不是 h:messages
,并且在验证器方法的 catch 块中是这样的
FacesContext.getCurrentInstance().addMessage("formId:aboveCompId", message);
但 UI 上没有显示任何内容。有什么建议吗?
这种方法至少有两个问题。
您正在将组件绑定到 bean 属性。症状表明该 bean 不在请求范围内。这是一个非常糟糕的主意。 UI 组件本质上是请求范围的,不应在更广泛的范围内绑定为 bean 的 属性,否则 JSF 将重用它们而不是创建新的。如果你继续这样做,所有标签处理程序(包括验证器绑定)将 运行 一遍又一遍地在同一个 UI 组件实例上跨越对同一 bean 的请求,因此在每次回发时累积(你会看到相同视图上每次回发的消息数量增加,这是由于将相同的验证器重新附加到相同的组件实例造成的)。
您在验证器中手动添加面孔消息,而不是在其中抛出包含面孔消息的 ValidatorException
。因此,JSF 生命周期在验证阶段之后错误地继续,而没有按照规范中止它。
另请参阅:
- How does the 'binding' attribute work in JSF? When and how should it be used?
- Custom Validator, should I use FacesContext#addMessage() or throw ValidatorException?
回到具体的功能需求。
至于非宽松日期转换,直接使用<f:convertDateTime>
即可。如果需要,可以通过输入组件的 converterMessage
属性自定义转换器消息。
至于日期范围验证,等到转换完成,然后抓取右边的Date
作为value
,然后与Date#before()
或[=进行比较18=].
所以,简而言之,这应该为您完成:
private Date startDate;
private Date endDate;
<t:inputCalendar id="startDate" binding="#{startDateComponent}" value="#{bean.startDate}"
renderAsPopup="true" renderPopupButtonAsImage="true"
popupDateFormat="dd.MM.yyyy" popupTodayDateFormat="dd.MM.yyyy"
converterMessage="Please enter date in correct format"
>
<f:convertDateTime pattern="dd.MM.yyyy" />
</t:inputCalendar>
<t:inputCalendar id="endDate" value="#{bean.endDate}"
renderAsPopup="true" renderPopupButtonAsImage="true"
popupDateFormat="dd.MM.yyyy" popupTodayDateFormat="dd.MM.yyyy"
converterMessage="Please enter date in correct format"
>
<f:convertDateTime pattern="dd.MM.yyyy" />
<f:validator validatorId="dateRangeValidator" />
<f:attribute name="startDateComponent" value="#{startDateComponent}" />
</t:inputCalendar>
其中 dateRangeValidator
是真实且可重复使用的 @FacesValidator
,可以在下面的第二个“另请参阅”link 中找到。请注意,第一个组件绑定到视图并且 绝对不是 绑定到 bean,并且验证是 not 紧密耦合到支持 bean .
另请参阅:
- PrimeFaces calendar accepts invalid dates as input
- Date range validation
我需要为这个组件显示一个 FacesMessage
,如下所示,
问题是它多次显示在 UI 上,如下所示,
其次,输入的日期是 40.06.2015
,这是无效的,因此是 FacesMessage
,但它被转换成了 10.07.2015
。我不知道如何防止这种情况。非常感谢任何帮助。我知道可以使用 DateFormat
class 上的 setLenient()
轻松处理它,但不知何故,在它对我可用之前,UI 组件将其转换为日期下个月。
附加到该组件的验证器如下:
那么,如何避免多次显示 "Please enter date in correct format"?
我想到了使用 h:message
而不是 h:messages
,并且在验证器方法的 catch 块中是这样的
FacesContext.getCurrentInstance().addMessage("formId:aboveCompId", message);
但 UI 上没有显示任何内容。有什么建议吗?
这种方法至少有两个问题。
您正在将组件绑定到 bean 属性。症状表明该 bean 不在请求范围内。这是一个非常糟糕的主意。 UI 组件本质上是请求范围的,不应在更广泛的范围内绑定为 bean 的 属性,否则 JSF 将重用它们而不是创建新的。如果你继续这样做,所有标签处理程序(包括验证器绑定)将 运行 一遍又一遍地在同一个 UI 组件实例上跨越对同一 bean 的请求,因此在每次回发时累积(你会看到相同视图上每次回发的消息数量增加,这是由于将相同的验证器重新附加到相同的组件实例造成的)。
您在验证器中手动添加面孔消息,而不是在其中抛出包含面孔消息的
ValidatorException
。因此,JSF 生命周期在验证阶段之后错误地继续,而没有按照规范中止它。
另请参阅:
- How does the 'binding' attribute work in JSF? When and how should it be used?
- Custom Validator, should I use FacesContext#addMessage() or throw ValidatorException?
回到具体的功能需求。
至于非宽松日期转换,直接使用
<f:convertDateTime>
即可。如果需要,可以通过输入组件的converterMessage
属性自定义转换器消息。至于日期范围验证,等到转换完成,然后抓取右边的
Date
作为value
,然后与Date#before()
或[=进行比较18=].
所以,简而言之,这应该为您完成:
private Date startDate;
private Date endDate;
<t:inputCalendar id="startDate" binding="#{startDateComponent}" value="#{bean.startDate}"
renderAsPopup="true" renderPopupButtonAsImage="true"
popupDateFormat="dd.MM.yyyy" popupTodayDateFormat="dd.MM.yyyy"
converterMessage="Please enter date in correct format"
>
<f:convertDateTime pattern="dd.MM.yyyy" />
</t:inputCalendar>
<t:inputCalendar id="endDate" value="#{bean.endDate}"
renderAsPopup="true" renderPopupButtonAsImage="true"
popupDateFormat="dd.MM.yyyy" popupTodayDateFormat="dd.MM.yyyy"
converterMessage="Please enter date in correct format"
>
<f:convertDateTime pattern="dd.MM.yyyy" />
<f:validator validatorId="dateRangeValidator" />
<f:attribute name="startDateComponent" value="#{startDateComponent}" />
</t:inputCalendar>
其中 dateRangeValidator
是真实且可重复使用的 @FacesValidator
,可以在下面的第二个“另请参阅”link 中找到。请注意,第一个组件绑定到视图并且 绝对不是 绑定到 bean,并且验证是 not 紧密耦合到支持 bean .
另请参阅:
- PrimeFaces calendar accepts invalid dates as input
- Date range validation