jsf - 在JSF消息中嵌入链接(或其他html)

标签 jsf jsf-2

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

当我尝试时,h:messages标记的呈现的html会转义html字符。我尝试将h:messages标记的转义属性设置为false,但这没有帮助。

最佳答案

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

由于这是一个非常普遍的要求/愿望,因此我想看一看所有可能的情况。

首先介绍一些背景信息:默认情况下,JSF使用ResponseWriter#writeText()编写标记主体,默认情况下会转义HTML。我们想让它像ResponseWriter#write()一样使用<h:outputText escape="false" />。我们想扩展标准JSF实现的MessagesRenderer并相应地覆盖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实现会覆盖它。我怀疑这里有错误,所以我报告了issue 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"(组件族,渲染器类型和类名)。

关于jsf - 在JSF消息中嵌入链接(或其他html),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3356546/

相关文章:

Spring MVC 与 Spring WebFlow

java - Primefaces ajax 监听器未在树组件中的选择事件上调用

java - 无法使用 jsf 和 hibernate 插入数据库。对象返回null

javax.faces.application.ViewExpiredException 看似被忽略

jsf - Facelet 被修改消息

java - <h :inputText> enabled/disabled - change background color

java - 将 @Named 托管 bean 注入(inject)另一个重用 JSF 页面?

java - OpenFaces 3 和 IE6(按钮操作)

JSF 不会使用提交的输入值填充 @Named @RequestScoped bean

java - 什么是莫哈拉?