Как написать и настроить собственный фейслет для переопределения сообщений h:?

Я переписываю сайт, изначально написанный на Weblogic Beehive, на JSF 2.0, и столкнулся с проблемой, когда мне нужно преобразовать сообщения, создаваемые новым сайтом, в формат, ТОЧНО соответствует выходным данным существующего сайта.

Я попытался использовать тег, который хорош, но стиль и логика существующей структуры сообщений не очень хорошо вписываются в этот вывод.

Есть ли в JSF параметры, которые позволили бы мне создать собственный тег, который будет не только выводить сообщения, но и выполнять для них условную логику?

Например, я создавал FacesMessages со строкой сводки и подробностей, но формат старого сайта отображает только самую высокую сводку. Например, я добавляю 4 сообщения, каждое из которых имеет одинаковое сводное сообщение и разные детали. Я хочу отображать сводку только с наивысшей серьезностью.

Кроме того, мне нужно, чтобы сообщения отображались и оформлялись в виде поля, а не каждое сообщение, а некоторые детали должны иметь условные классы CSS.


person bakoyaro    schedule 09.08.2011    source источник
comment
В будущих вопросах JSF, пожалуйста, укажите и отметьте используемую версию спецификации JSF. Ответы обычно сильно зависят от этого.   -  person BalusC    schedule 09.08.2011


Ответы (2)


Если вы используете JSF 2.x, вы можете выполнить итерацию по FacesContext#getMessageList() в цикле. Каждый элемент представляет собой FacesMessage, который, в свою очередь, имеет несколько геттеров.

<ui:repeat value="#{facesContext.messageList}" var="facesMessage">
    Severity: #{facesMessage.severity}<br />
    Summary: #{facesMessage.summary}<br />
    Detail: #{facesMessage.detail}<br />
    <br />
</ui:repeat>

Это позволяет использовать более точную HTML-разметку вокруг сообщений.

Если вы все еще используете JSF 1.x, в котором отсутствует этот метод в FacesContext, вам необходимо собрать FacesContext#getMessages() в List<FacesMessage> first с помощью некоторого служебного компонента или даже функции EL:

List<FacesMessage> messageList = new ArrayList<FacesMessage>();
Iterator<FacesMessage> messages = FacesContext.getCurrentInstance().getMessages();

while (messages.hasNext()) {
    messageList.add(messages.next());
}

Затем вы можете повторить этот messageList в своем представлении, используя <ui:repeat> таким же образом.

person BalusC    schedule 09.08.2011
comment
Спасибо за совет. Итерация по списку не так уж и важна. Я могу сделать это с закрытыми глазами ;-) Я хочу условно отображать сводку и отображать неэкранированный html в тех случаях, когда сообщение имеет особый стиль. Я использую JSF 2.0 - person bakoyaro; 09.08.2011
comment
Просто используйте соответственно атрибут JSF rendered и компонент <h:outputText escape="false"> обычным способом. Как уже было сказано, теперь у вас есть полная свобода управления разметкой. - person BalusC; 09.08.2011
comment
Спасибо за комментарий, я ценю, что вы нашли время, чтобы помочь мне. У меня возникли проблемы с изучением и использованием JSF, и вы де-факто являетесь шрифтом информации для JSF в SO. Можете ли вы порекомендовать мне хорошую книгу по JSF 2.0? Я старший разработчик, использующий Eclipse, знакомый с JEE, это просто материал JSF, с изучением/использованием которого у меня проблемы. спасибо, бакояро - person bakoyaro; 14.08.2011

В итоге я получил это на своей странице JSF (xhtml):

            <c:set var="messageList" value="#{facesContext.messageList}" />
            <c:set var="maxSev" value="#{facesContext.maximumSeverity.ordinal}" />
            <ui:repeat value="${messageList}" var="fm" >
                <c:choose>
                     <c:when test="${fm.severity.ordinal eq 0}">
                         <c:set var="summaryStyleClass" value="outcome"/>
                         <c:set var="detailStyleClass" value="outcome_details"/>
                     </c:when>
                     <c:when test="${fm.severity.ordinal eq 1}">
                         <c:set var="summaryStyleClass" value="warning_title"/>
                         <c:set var="detailStyleClass" value="warning"/>
                     </c:when>
                     <c:when test="${fm.severity.ordinal eq 2}">
                         <c:set var="summaryStyleClass" value="error_title"/>
                         <c:set var="detailStyleClass" value="error"/>
                     </c:when>
                     <c:when test="${fm.severity.ordinal eq 3}">
                         <c:set var="summaryStyleClass" value="fatal"/>
                         <c:set var="detailStyleClass" value="fatal_details"/>
                     </c:when>
                </c:choose>
            </ui:repeat>
            <div class="${detailStyleClass}" >
                 <div class="${summaryStyleClass}">
                        <ui:repeat value="${messageList}" var="fm" >
                             <c:choose>
                                 <c:when test="${fm.severity.ordinal eq maxSev}">
                                     ${fm.summary}
                                 </c:when>
                             </c:choose>
                        </ui:repeat>
                 </div>
                  <ul>
                     <ui:repeat value="${messageList}" var="msg">
                         <li><h:outputText value="${msg.detail}"/></li>
                     </ui:repeat>
                </ul>
            </div>

Я уверен, что здесь я нарушаю шаблон, но раздел, похоже, не работает, где он может разрешать вары summaryStyleClass и detailStyleClass. Я перебираю их, потому что мне нужно стилизовать сообщение в зависимости от того, какое сообщение имеет наивысшую серьезность для страницы. Это визуализированный вывод, который я получаю на странице в браузере:

            <div>
                 <div>Warning:</div>
                 <ul>
                      <li>Warning message.</li>
                </ul>
            </div>

Обратите внимание, что нет стилей...

person bakoyaro    schedule 15.08.2011