Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF1.1:如何在验证消息中显示组件标签而不是clientId?_Jsf - Fatal编程技术网

JSF1.1:如何在验证消息中显示组件标签而不是clientId?

JSF1.1:如何在验证消息中显示组件标签而不是clientId?,jsf,Jsf,我正在编写一个自定义组件来在弹出窗口中显示验证消息,它工作得很好,但我仍然有一个问题:我希望在验证消息中显示组件标签而不是cliendid 我已经看过这个问题和类似的问题: 但是我使用的是JSF1.1,如果我试图为属性label或requiredMessage设置一个值,就会出现编译错误。 因此,我尝试使用为组件分配标签: 没有效果 在JSF1.1中,有没有一种简单的方法可以使标签显示在验证消息中而不是客户端id中? 如果没有,那么给定一个组件,我如何检索它的相关标签组件以在Java代码中

我正在编写一个自定义组件来在弹出窗口中显示验证消息,它工作得很好,但我仍然有一个问题:我希望在验证消息中显示组件标签而不是cliendid

我已经看过这个问题和类似的问题:

但是我使用的是JSF1.1,如果我试图为属性
label
requiredMessage
设置一个值,就会出现编译错误。 因此,我尝试使用
为组件分配标签:


没有效果

在JSF1.1中,有没有一种简单的方法可以使标签显示在验证消息中而不是客户端id中? 如果没有,那么给定一个组件,我如何检索它的相关标签组件以在Java代码中完成工作

谢谢

  • 绑定输出标签
  • 绑定错误消息
  • 现在从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代码的解决方案

  • 让我的组件渲染器扩展Tomahawk的
    HtmlMessageRenderer
    ,它能够使用组件标签而不是其id
  • 使用
    HTMLMessageRenderer#findInputId
    检索包含消息的组件的Id
  • 使用
    HTMLMessageRenderer#findInputLabel
    检索包含消息的组件标签
  • 将消息中的组件Id替换为组件标签
  • 下面是我的组件Render
    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 />");
            }
    // ...