我想在JSF消息中嵌入鏈接,這可能嗎?在JSF消息中嵌入鏈接(或其他html)
當我嘗試它時,h:messages標記的呈現html轉義html字符。我嘗試將h:messages標記的escape屬性設置爲false,但這沒有幫助。
我想在JSF消息中嵌入鏈接,這可能嗎?在JSF消息中嵌入鏈接(或其他html)
當我嘗試它時,h:messages標記的呈現html轉義html字符。我嘗試將h:messages標記的escape屬性設置爲false,但這沒有幫助。
不幸的是,這在標準的JSF實現中是不可能的。組件和渲染器不正式支持此屬性。然而,你可以在一個處理這個的渲染器中生長。
由於這是一個相當常見的要求/希望,我想看看什麼是可能的。
首先介紹一些背景信息:默認情況下,JSF使用ResponseWriter#writeText()
來編寫標籤主體,默認情況下它會轉義HTML。我們想讓它使用ResponseWriter#write()
而不是像<h:outputText escape="false" />
那樣。我們想擴展標準JSF實現的MessagesRenderer
,並相應地覆蓋encodeEnd()
方法。但由於MessagesRenderer#encodeEnd()
包含很多代碼(~180行),我們不喜歡複製粘貼來改變一兩行,所以我發現用ResponseWriterWrapper
替代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.
}
}
}
儘管@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>
,只需要做同樣的事情,但是可以用任何地方代替"Messages"
由"Message"
(組件族,渲染器類型和類名稱)。
escape="false"
歸因於您的需要由OmniFaces <o:messages>
component提供。 OmniFaces實用程序庫可用於JSF 2.
我發佈了@ BalusC評論中提到的此解決方案作爲答案,因爲這是最直接的解決方案。
感謝BalusC,我今天也得到了同樣的解決方案(並提交了相同的錯誤https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1750)我使用了委託人模式我的迴應作家,但我認爲我更喜歡你用包裝紙做的事情。謝謝! – 2010-07-29 03:57:51
報告問題的新鏈接: http://java.net/jira/browse/JAVASERVERFACES-1750 – 2011-12-12 13:57:20
它完美地工作BalusC,謝謝! – 2013-03-31 15:18:40