JSF1.1:如何在验证消息中显示组件标签而不是clientId?
我正在编写一个自定义组件来在弹出窗口中显示验证消息,它工作得很好,但我仍然有一个问题:我希望在验证消息中显示组件标签而不是cliendid 我已经看过这个问题和类似的问题: 但是我使用的是JSF1.1,如果我试图为属性JSF1.1:如何在验证消息中显示组件标签而不是clientId?,jsf,Jsf,我正在编写一个自定义组件来在弹出窗口中显示验证消息,它工作得很好,但我仍然有一个问题:我希望在验证消息中显示组件标签而不是cliendid 我已经看过这个问题和类似的问题: 但是我使用的是JSF1.1,如果我试图为属性label或requiredMessage设置一个值,就会出现编译错误。 因此,我尝试使用为组件分配标签: 没有效果 在JSF1.1中,有没有一种简单的方法可以使标签显示在验证消息中而不是客户端id中? 如果没有,那么给定一个组件,我如何检索它的相关标签组件以在Java代码中
label
或requiredMessage
设置一个值,就会出现编译错误。
因此,我尝试使用
为组件分配标签:
没有效果
在JSF1.1中,有没有一种简单的方法可以使标签显示在验证消息中而不是客户端id中?
如果没有,那么给定一个组件,我如何检索它的相关标签组件以在Java代码中完成工作
谢谢
我想到了一个解决办法。您可以添加新的
PhaseListener
,它将使用PhaseId=RENDER\u RESPONSE
查找PhaseEvent
,并在它的beforePhase方法中编写如下内容:
public class MyPhaseListener implements PhaseListener {
private void findKeyValuePairInTree(UIComponent root,
Map<String, String> map) {
if (root instanceof HtmlOutputLabel) {
map.put(((HtmlOutputLabel) root).getFor(),
((HtmlOutputLabel) root).getValue());
}
if (root.getChilder() != null && !root.getChildren().isEmpty()) {
for (UIComponent child : root.getChilder()) {
findKeyValuePairInTree(child, map);
}
}
private HashMap<String, String> idToLabelMap= new HashMap<String,String>();
public void beforePhase(PhaseEvent event) {
if (event.getPhaseId().equals(PhaseId.RENDER_RESPONSE) {
findKeyValuePairInTree(FacesContext.getCurrentInstance().getViewRoot(),
idToLabelMap);
// after above function finished execution in idToLabelMap will be all
// pairs of component ID used in standard FacesMessage as key
// and HtmlOutputLabel value attr used as value
Set<String> keySet = idToLabelMap.keySet();
for(String key : keySet) {
Iterator messages = FacesContext.getCurrentInstance().getMessages(key);
while (iterator.hasNext) {
FacesMessage msg = (FacesMessage) iterator.next();
// now replace all occurences of clientId with label value from map
msg.setSummary(msg.getSummary().replaceAll(key, idToLabelMap.get(key)));
msg.setDetails(msg.getDetails().replaceAll(key, idToLabelMap.get(key)));
}
}
FacesContext.getCurrentInstance().getMessages();
}
}
...
}
公共类MyPhaseListener实现PhaseListener{
私有void findKeyValuePairInTree(UIComponent根、,
(地图){
if(HtmlOutLabel的根实例){
map.put(((HtmlOutputLabel)root).getFor(),
((HtmlOutLabel)root.getValue());
}
if(root.getChilder()!=null&&!root.getChildren().isEmpty()){
对于(UIComponent子级:root.getChilder()){
findKeyValuePairInTree(子级,地图);
}
}
私有HashMap idToLabelMap=新HashMap();
前期公共无效(阶段事件事件){
if(event.getPhaseId()等于(PhaseId.RENDER_响应){
findKeyValuePairInTree(FacesContext.getCurrentInstance().getViewRoot(),
idToLabelMap);
//上述函数完成后,idToLabelMap中的执行将全部完成
//在标准FacesMessage中用作键的组件ID对
//并将HtmlOutLabel值attr用作值
Set keySet=idToLabelMap.keySet();
用于(字符串键:键集){
迭代器消息=FacesContext.getCurrentInstance().getMessages(键);
while(iterator.hasNext){
FacesMessage msg=(FacesMessage)迭代器.next();
//现在,用map中的标签值替换所有出现的clientId
msg.setSummary(msg.getSummary().replaceAll(key,idToLabelMap.get(key));
msg.setDetails(msg.getDetails().replaceAll(key,idToLabelMap.get(key));
}
}
FacesContext.getCurrentInstance().getMessages();
}
}
...
}
现在,在该方法之后的呈现阶段,FacesContext.getCurrentInstance().getMessages()
中的所有消息都将使用标签值更改clientId
,并且由于验证阶段在呈现阶段之前,所有验证都将通过或失败-验证不会产生更多消息
唯一的问题是,当您在htmloutlabel
的for
属性中使用同一id两次或两次以上时,因为在不同的形式中可以使用相同的id用于组件。然后您可以在for
attr-inside
中使用更复杂的id,例如,使用表单id或类似的东西来提示它
我希望这会有所帮助。我找到了一个不需要修改现有JSF代码的解决方案
HtmlMessageRenderer
,它能够使用组件标签而不是其idHTMLMessageRenderer#findInputId
检索包含消息的组件的IdHTMLMessageRenderer#findInputLabel
检索包含消息的组件标签encodeBegin
方法的代码摘录,在该方法中,我创建了两个独立的循环,第一个用于组件消息,另一个用于全局消息
请注意,FacesContext#getClientIdsWithMessages
还返回null
,它被认为是全局消息的clientId
请注意,由于组件本身能够检索和使用组件标签(如果存在);因此此解决方案只需要在JSF页面代码中放置
标记
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
// ....
// replace id with label in messages for components
Iterator<String> clientIdsWithMessages=context.getClientIdsWithMessages();
while(clientIdsWithMessages.hasNext()){
String clientIdWithMessages=clientIdsWithMessages.next();
if(clientIdWithMessages!=null){
Iterator<FacesMessage> componentMessages=context.getMessages(clientIdWithMessages);
while(componentMessages.hasNext()){
String stringMessage=componentMessages.next().getDetail();
try{
String inputId =findInputId(context, clientIdWithMessages);
String inputLabel = findInputLabel(context, clientIdWithMessages);
if(inputId!=null && inputLabel!=null)
stringMessage=stringMessage.replace(inputId, inputLabel);
} catch(Exception e){
// do nothing in this catch, just let the message be rendered with the componentId instead of a label }
msgBuilder.append(stringMessage);
msgBuilder.append("<br />");
}
}
}
// process global messages
Iterator<FacesMessage> globalMessages=context.getMessages(null);
while(globalMessages.hasNext()){
FacesMessage message=globalMessages.next();
msgBuilder.append(message.getDetail());
msgBuilder.append("<br />");
}
// ...
public void encodeBegin(FacesContext上下文,UIComponent)引发IOException{
// ....
//将组件消息中的id替换为标签
迭代器clientIdsWithMessages=context.getClientIdsWithMessages();
while(clientIdsWithMessages.hasNext()){
字符串clientIdWithMessages=clientIdWithMessages.next();
if(clientdwithmessages!=null){
迭代器组件消息=context.getMessages(clientdwithmessages);
while(componentMessages.hasNext()){
String stringMessage=componentMessages.next().getDetail();
试一试{
字符串inputId=findInputId(上下文,clientdwithmessages);
字符串inputLabel=findInputLabel(上下文,clientIdWithMessages);
if(inputId!=null&&inputLabel!=null)
stringMessage=stringMessage.replace(inputId,inputLabel);
}捕获(例外e){
//在这个catch中不执行任何操作,只使用componentId而不是label}来呈现消息
附加(stringMessage);
msgBuilder.append(“
”);
}
}
}
//处理全局消息
迭代器全局性
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
// ....
// replace id with label in messages for components
Iterator<String> clientIdsWithMessages=context.getClientIdsWithMessages();
while(clientIdsWithMessages.hasNext()){
String clientIdWithMessages=clientIdsWithMessages.next();
if(clientIdWithMessages!=null){
Iterator<FacesMessage> componentMessages=context.getMessages(clientIdWithMessages);
while(componentMessages.hasNext()){
String stringMessage=componentMessages.next().getDetail();
try{
String inputId =findInputId(context, clientIdWithMessages);
String inputLabel = findInputLabel(context, clientIdWithMessages);
if(inputId!=null && inputLabel!=null)
stringMessage=stringMessage.replace(inputId, inputLabel);
} catch(Exception e){
// do nothing in this catch, just let the message be rendered with the componentId instead of a label }
msgBuilder.append(stringMessage);
msgBuilder.append("<br />");
}
}
}
// process global messages
Iterator<FacesMessage> globalMessages=context.getMessages(null);
while(globalMessages.hasNext()){
FacesMessage message=globalMessages.next();
msgBuilder.append(message.getDetail());
msgBuilder.append("<br />");
}
// ...