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