首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

JSF 進階:自定義標籤實現 HTML 富文本驗證訊息渲染

     編輯:J2EE

問題背景

標準 <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() 為未轉義的原始內容。因此可在自定義標籤中直接輸出原始字符串,繞過默認渲染器轉義。

解決方案:自定義 ValidatorTag

1. Tag Handler 實現 (Java)

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() { /* 清理資源 */ }
}

2. TLD 描述文件

<?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>

3. JSP 頁面使用

<%@ taglib uri="https://com.demo/tags" prefix="demo" %>
...
<demo:errorMessage />

關鍵設計決策說明

  • 不註冊 faces-config.xml: 純 JSP Tag 擴展,非 JSF 組件,無需 JSF 配置。
  • 直接輸出所有訊息: 簡化邏輯,適用於全局錯誤展示區。如需針對特定組件,可擴展屬性 for 過濾。
  • 安全性提醒: 直接輸出用戶可控內容存在 XSS 風險。生產環境務必對資源文件內容進行白名單過濾 (如僅允許 b, i, font, span 等安全標籤) 或使用成熟庫 (OWASP Java HTML Sanitizer)。

擴展思路

  1. 增加 escape 屬性動態控制是否轉義,兼容純文本場景。
  2. 支援 for 屬性綁定特定組件 ID,實現精準訊息顯示。
  3. 整合 CSS Class 屬性,統一錯誤訊息樣式風格。
  4. 升級為 JSF 2.0+ Facelets Tag 或 Composite Component,獲得更好 IDE 支援與類型安全。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved