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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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
在JSF消息中嵌入链接(或其他html)_Jsf_Jsf 2 - Fatal编程技术网

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

在JSF消息中嵌入链接(或其他html),jsf,jsf-2,Jsf,Jsf 2,我想在JSF消息中嵌入一个链接,这可能吗 当我尝试时,h:messages标记的呈现html将转义html字符。我尝试将h:messages标记的escape属性设置为false,但没有帮助。不幸的是,这在标准JSF实现中是不可能的。组件和渲染器不正式支持此属性。但是,您可以自行生成处理此问题的渲染器 因为这是一个非常普遍的要求/愿望,我想看看什么是可能的 首先是一些背景信息:JSF默认情况下用于编写标记体,默认情况下转义HTML。我们想让它像一样使用。我们希望扩展标准JSF实现的message

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


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

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

因为这是一个非常普遍的要求/愿望,我想看看什么是可能的

首先是一些背景信息:JSF默认情况下用于编写标记体,默认情况下转义HTML。我们想让它像
一样使用。我们希望扩展标准JSF实现的
messagesrender
,并相应地重写
encodeEnd()
方法。但是由于
messagesrender#encodeEnd()
包含大量的代码(~180行),我们不希望通过复制粘贴来更改一行或两行代码,因此我发现最好使用一个自定义实现来替换
ResponseWriter
,其中
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.
        }
    }
}
尽管有
@facesrender
注释,它还是会被默认的
messagesrender
实现覆盖。我怀疑这里有窃听器,所以我报告了。无论如何,要让它正常工作,我们必须回到
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>

javax.faces.Messages
javax.faces.Messages
com.example.EscapableMessagesRenderer
然后,要触发它,只需执行以下操作:

<h:messages escape="false" />

而且它是有效的!:)


注意:以上仅影响
。要对
执行相同的操作,只需执行相同的操作,但将任何
的“消息”替换为
的“消息”
(组件族、渲染器类型和类名)。

OmniFaces提供了所需的
escape=“false”
属性。OmniFaces实用程序库可用于JSF2


我发布了@BalusC评论中提到的这个解决方案作为答案,因为这是最简单的解决方案。

谢谢BalusC,我今天也找到了同样的解决方案(并提交了同样的错误)。我使用了delegator模式作为我的回复作者,但我想我更喜欢你使用包装器的方式。谢谢报告问题的一个新链接:@Mr.Pichler:您确实应该扩展它自己的链接。现在有了
作为替代方案。只有组件的原始
encodeEnd()
(或错误页面,我已经编辑了答案以修复该问题)。@user1766169:也许您意外地使用了遗留JSP,而不是2009年引入的后续Facelets。这里所有的JSF2.x答案都是针对Facelets的,因为JSP从那时起就被弃用了。