標準 <h:message> / <h:messages> 會對 FacesMessage 內容進行 HTML 轉義。若國際化資源文件中包含 HTML 標籤 (如 <b>, <font color=green>),前端將直接顯示原始標籤文本,而非渲染效果。
ems=<b>Amount Count</b> must be more than <font color=green>150$</font>
HtmlOutputText 提供 escape="false" 屬性可輸出原始 HTML,但 HtmlMessage 缺乏此屬性。關鍵在於:何時發生轉義? 經驗證,FacesContext.getMessages() 返回的 FacesMessage.getDetail() 為未轉義的原始內容。因此可在自定義標籤中直接輸出原始字符串,繞過默認渲染器轉義。
package com.xxx.xxx;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.IOException;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
public class ValidatorTag implements Tag {
private PageContext pageContext;
private Tag parent;
public void setPageContext(PageContext pc) { this.pageContext = pc; }
public void setParent(Tag p) { this.parent = p; }
public Tag getParent() { return parent; }
public PageContext getPageContext() { return pageContext; }
public int doStartTag() { return SKIP_BODY; }
public int doEndTag() throws JspTagException {
try {
StringBuilder errorMessages = new StringBuilder();
FacesContext ctx = FacesContext.getCurrentInstance();
if (ctx.getMessages() != null) {
for (Iterator i = ctx.getMessages(); i.hasNext(); ) {
FacesMessage msg = (FacesMessage) i.next();
errorMessages.append(msg.getDetail()); // 獲取未轉義詳情
}
}
if (errorMessages.length() > 0) {
pageContext.getOut().write(errorMessages.toString());
}
} catch (IOException e) {
throw new JspTagException(e.getMessage());
}
return EVAL_PAGE;
}
public void release() { /* 清理資源 */ }
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<taglib xmlns="https://java.sun.com/xml/ns/j2ee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>Demo</description>
<tlib-version>1.0</tlib-version>
<short-name>Demo Tag</short-name>
<uri>https://com.demo/tags</uri>
<tag>
<description>Validation Error Message with HTML Support</description>
<name>errorMessage</name>
<tag-class>com.xxx.xxx.ValidatorTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
<%@ taglib uri="https://com.demo/tags" prefix="demo" %>
...
<demo:errorMessage />
for 過濾。escape 屬性動態控制是否轉義,兼容純文本場景。for 屬性綁定特定組件 ID,實現精準訊息顯示。