Встраивание ссылки (или другого html) в сообщение JSF - PullRequest
15 голосов
/ 28 июля 2010

Я хочу встроить ссылку в сообщение JSF, возможно ли это?

Когда я пытаюсь это сделать, визуализированный html тега h: messages экранирует символы html.Я попытался установить для атрибута escape тега h: messages значение false, но это не помогло.

Ответы [ 2 ]

21 голосов
/ 29 июля 2010

К сожалению, это невозможно в стандартной реализации JSF. Компонент и средство визуализации официально не поддерживают этот атрибут. Вы можете, однако, homegrow рендер, который обрабатывает это.

Поскольку это довольно распространенное требование / желание, я подумал, что все возможно.

Сначала некоторая справочная информация: JSF по умолчанию использует ResponseWriter#writeText() для написания тела тега, которое по умолчанию экранирует HTML. Мы хотели бы позволить ему использовать ResponseWriter#write() вместо этого, как с <h:outputText escape="false" />. Мы хотели бы расширить MessagesRenderer стандартной реализации JSF и переопределить метод encodeEnd() соответственно. Но так как MessagesRenderer#encodeEnd() содержит довольно много кода (~ 180 строк), который мы предпочитаем не копировать, чтобы просто изменить одну или две строки, я обнаружил, что лучше заменить ResponseWriter пользовательской реализацией с помощью ResponseWriterWrapper, где writeText() был переопределен для обработки побега.

Итак, я закончил с этим:

package com.example;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.context.ResponseWriterWrapper;
import javax.faces.render.FacesRenderer;

import com.sun.faces.renderkit.html_basic.MessagesRenderer;

@FacesRenderer(componentFamily="javax.faces.Messages", rendererType="javax.faces.Messages")
public class EscapableMessagesRenderer extends MessagesRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        final ResponseWriter originalResponseWriter = context.getResponseWriter();

        try {
            context.setResponseWriter(new ResponseWriterWrapper() {

                @Override
                public ResponseWriter getWrapped() {
                    return originalResponseWriter;
                }

                @Override
                public void writeText(Object text, UIComponent component, String property) throws IOException {
                    String string = String.valueOf(text);
                    String escape = (String) component.getAttributes().get("escape");
                    if (escape != null && !Boolean.valueOf(escape)) {
                        super.write(string);
                    } else {
                        super.writeText(string, component, property);
                    }
                }
            });

            super.encodeEnd(context, component); // Now, render it!
        } finally {
            context.setResponseWriter(originalResponseWriter); // Restore original writer.
        }
    }
}

Несмотря на аннотацию @FacesRenderer, она переопределяется реализацией MessagesRenderer по умолчанию. Я подозреваю здесь ошибку, поэтому я сообщил о выпуск 1748 . Чтобы заставить его работать в любом случае, мы должны вернуться к faces-config.xml:

<render-kit>
    <renderer>
        <component-family>javax.faces.Messages</component-family>
        <renderer-type>javax.faces.Messages</renderer-type>
        <renderer-class>com.example.EscapableMessagesRenderer</renderer-class>
    </renderer>
</render-kit>

Затем, чтобы вызвать его, просто выполните:

<h:messages escape="false" />

И это работает! :)


Примечание: вышеуказанное влияет только на <h:messages>. Чтобы сделать то же самое для <h:message>, просто сделайте то же самое, но замените в любом месте "Messages" на "Message" (семейство компонентов, тип рендерера и имена классов).

1 голос
/ 16 января 2015

Приписываемое вам escape="false" предоставляется компонентом OmniFaces <o:messages> .Библиотека утилит OmniFaces доступна для JSF 2.

Я опубликовал это решение, упомянутое в комментарии @ BalusC, в качестве ответа, поскольку это самое простое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...