在JSF消息中嵌入链接(或其他html) [英] Embedding a link (or other html) in a JSF message

查看:131
本文介绍了在JSF消息中嵌入链接(或其他html)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在JSF消息中嵌入链接,这可能吗?

I want to embed a link in a JSF message, is this possible?

当我尝试时,h:messages标记的呈现的html会转义html字符.我尝试将h:messages标记的转义属性设置为false,但这无济于事.

When I try it, the rendered html of the h:messages tag escapes the html characters. I tried setting the escape attribute of the h:messages tag to false, but that didn't help.

推荐答案

不幸的是,这在标准JSF实现中是不可能的.组件和渲染器不正式支持此属性.但是,您可以在本地渲染处理此问题的渲染器.

Unfortunately, this is not possible in the standard JSF implementation. The component and the renderer doesn't officially support this attribute. You can however homegrow a renderer which handles this.

由于这是一个很常见的要求/愿望,我想看看有什么可能.

Since this is a pretty common requirement/wish, I thought to take a look what's all possible.

首先提供一些背景信息:默认情况下,JSF使用 ResponseWriter#write() 相反,就像<h:outputText escape="false" />一样.我们想扩展标准JSF实现的MessagesRenderer并相应地覆盖encodeEnd()方法.但是由于MessagesRenderer#encodeEnd()包含很多代码(〜180行),我们不希望复制粘贴而只改变一两行,所以我发现最好用自定义实现替换ResponseWriter并使用自定义实现 ResponseWriterWrapper 其中,writeText()是已被覆盖以处理转义.

First some background information: JSF by default uses ResponseWriter#writeText() to write the tag body, which escapes HTML by default. We'd like to let it use ResponseWriter#write() instead like as with <h:outputText escape="false" />. We'd like to extend the MessagesRenderer of the standard JSF implementation and override the encodeEnd() method accordingly. But since the MessagesRenderer#encodeEnd() contains pretty a lot of code (~180 lines) which we prefer not to copypaste to just change one or two lines after all, I found it better to replace the ResponseWriter with a custom implementation with help of ResponseWriterWrapper wherein the writeText() is been overriden to handle the escaping.

所以,我最终得到了这个:

So, I ended up with this:

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:

In spite of the @FacesRenderer annotation, it get overriden by the default MessagesRenderer implementation. I suspect here a bug, so I reported issue 1748. To get it to work anyway, we have to fall back to the 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>

然后,要触发它,只需执行以下操作:

Then, to trigger it, just do:

<h:messages escape="false" />

它有效! :)

注意:以上内容仅影响<h:messages>.要对<h:message>执行相同操作,只需执行相同操作,但将任何地方 "Messages"替换为"Message"(组件族,渲染器类型和类名).

Note: the above affects <h:messages> only. To do the same for <h:message>, just do the same, but replace anywhere "Messages" by "Message" (component family, renderer type and classnames).

这篇关于在JSF消息中嵌入链接(或其他html)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆