解决方法
不幸的是,这在标准的JSF实现中是不可能的.组件和渲染器不正式支持此属性.然而,您可以设置处理此操作的渲染器.
既然这是一个很常见的要求/愿望,我想看看什么是可能的.
首先一些背景信息:JSF默认使用ResponseWriter#writeText()
写标签体,默认情况下转义HTML.我们想让它使用ResponseWriter#write()
,就像< h:outputText escape =“false”/> ;.我们想扩展标准JSF实现的MessagesRenderer并相应地覆盖encodeEnd()方法.但是由于MessagesRenderer#encodeEnd()包含了很多代码(〜180行),我们更希望不要使用copypaste来改变一行或两行,所以我发现更好地将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实现覆盖.我怀疑这里有一个bug,所以我报了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>做同样的操作,只需执行相同的操作即可通过“消息”(组件系列,渲染器类型和类名称)替换“消息”.