富文本信息存儲顯示?亂碼問題

前兩天遇到了一個前臺富文本保存異常的問題,具體表現爲前臺編輯好的富文本保存後再次查看會發現每一行的縮進都變成了 ? ,頁面顯示非常糟糕,尋求解決的辦法。

bug背景

  • 項目前臺採用了ext組件提供的富文本編輯框(老項目的無奈)
  • 文件在進入java處理之前經過了基於antisamy框架的防xss攻擊filter
  • 數據庫爲oracle,頁面編碼格式爲UTF-8

解決過程

debug模式逐步跟進bug,追蹤縮進在哪一步變成?亂碼。最開始懷疑是頁面格式沒有嚴格限定爲UTF-8,導致數據庫不能識別。結果發現兩點異常:

1.數據庫有正常存儲的空格;
2.斷點跟進發現前臺信息在進入java存儲代碼時已經變成了?

也就是說,問題很可能出在antisamy框架上。
然後我把debug的斷點打到了filter裏,request傳入時,顯示正常。出filter時,就不正常了。那隻好把斷點跟進了框架裏,最終發現異常出現在執行了antisamy框架對輸入進行decode,也就是說decode()方法將縮進變成了空格。
下一步就是求助搜索引擎了。以下內容來自網絡:

在UTF-8編碼和ASCII碼中,空格都對應0x20,但在UTF-8不是所有的空格都會被認爲是0x20,有一種空格寬度不會被壓縮,這種不會被壓縮的空格對應的字節碼是“0xC2 0xA0”。

縮進就是一種寬度不會被壓縮的空格,也就是說縮進對應的字節碼就是”0xC2 0xA0”。

由於在GB2312等其他編碼中並不存在”0xC2 0xA0”,直接使用decode()進行編碼轉換,這個字符就會被替換爲”ox3F”,對應的就是半角問號。

解決辦法

知道問題原因再去解決就比較簡單了,我們只需要在得到UTF-8字符的時候進行一個字符串的替換,將縮進變爲標準空格,就可以解決問題。但是要注意,由於這個空格用於排版,我們再進行替換的時候,要根據富文本編輯插件的顯示效果嘗試插入幾個空格會正常顯示。替換代碼如下:

byte bytes[] = {(byte) 0xC2,(byte) 0xA0};
String UTFSpace = new String(bytes,"utf-8");
html = html.replaceAll(UTFSpace, " ");

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章