解决方法
不幸的是,这在标准的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>做同样的操作,只需执行相同的操作即可通过“消息”(组件系列,渲染器类型和类名称)替换“消息”.