1. 程式人生 > >spagobi 4.0 中文問題初探

spagobi 4.0 中文問題初探

         Spagobi4.0版本出來有一段時間了,之前忙於專案,沒有時間專門研究下新版的中文問題。聽有的網友說,新版本支援中文輸入了,但是中文顯示上還有些問題。於是,從官網上下載了最新版的 all in one包。解壓,啟動。進入登入介面,眼前一亮。新版本在登入介面和進入系統的主介面上更改比較大,整體來說還算不錯。

         進入主介面後,一下子還有點不太適應,很多原來版本的功能不知道入口在哪裡了。摸索了一下,找到了三個功能入口:Engines management,Data source,Maps。

        

engines management中找一個引擎的description欄位,增加了幾個中文字元,發現能正常儲存,重新整理介面後也能正常顯示。data source介面裡中文內容可以正常儲存,但是重新整理後顯示亂碼。Maps中新增一條記錄,不出意外,返回一大推提示,中文字元不能儲存。

         這裡先把軟體環境介紹下。下載後的all in one包中將預設系統執行資料庫改成的MySql。改資料庫之前先要到官網下載4.0版本的mysql資料庫初始化sql ,建立好資料庫後執行初始化sql檔案。然後,需要修改以下幾個檔案:

         conf/server.xml:修改其中的Resource name="jdbc/spagobi"資源定義中的資料庫連線配置為:<Resourceauth="Container" driverClassName="com.mysql.jdbc.Driver"maxActive="20" maxIdle="10" maxWait="-1"name="jdbc/spagobi" password="root"type="javax.sql.DataSource"url="jdbc:mysql://localhost:3306/spagobi4?characterEncoding=utf-8&amp;useOldAliasMetadataBehavior=true"username="root"/>這裡需要注意的是url中的characterEncoding=utf-8&amp;useOldAliasMetadataBehavior=true兩個連線引數,第一個連線引數指定資料庫的字符集為UTF-8,第二個引數解決了部分頁面提示“ENGINE_ID”,”DS_ID” 列不存在異常,據說這是mysql的一個bug。

         webapps/spagobi/WEB-INF/classes目錄下的3個檔案:hibernate.cfg.xml,jbpm.hibernate.cfg.xml和quartz.properties檔案中的資料庫方言都改成MySQLDialect。

         這些檔案修改完後,不要再用bin/SpagoBIStartup.bat啟動了,直接使用bin/ startup.bat啟動即可。啟動完成後在驗證上邊提到的三個功能,中文問題依然存在,不過看資料庫中相應的表,前兩個引擎管理和資料來源管理表中均能正常儲存中文內容了。

         已經能正常使用的engines management功能暫時先不管他具體怎麼實現的。下邊重點看一下data source和Maps兩個功能。

         data source管理中,通過火狐瀏覽器的fire debug外掛檢視後臺資料處理URL發現如下圖:

         通過對比Engines management功能的URL:

發現有兩點不同

(1)   請求的URL路徑不同。引擎管理功能中使用“http://localhost:8081/SpagoBI/servlet/AdapterHTTP?“,資料來源管理功能中使用“http://localhost:8081/SpagoBI/restful-services/domains/listValueDescriptionByType?”。熟悉之前版本原始碼的朋友應該知道,servlet/AdapterHTTP是之前版本中所有後端處理的統一入口。現在新版本中增加了另外一種處理後端資料的web url “restful-services”。

(2)   響應頭資訊中Content-Type內容不同。正常儲存和顯示中文的引擎管理功能中Content-Type=application/x-json;charset=UTF-8,不能正常顯示中文的資料來源管理中Content-Type=application/json。也許就是因為這個差異才導致的中文顯示亂碼。

 那麼,這個restful-services到底是什麼呢?通過查詢web.xml檔案,找到了這個配置“<context-param><param-name>resteasy.servlet.mapping.prefix</param-name><param-value>/restful-services</param-value></context-param>

<servlet><servlet-name>Resteasy</servlet-name><servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class></servlet>”

         通過搜尋HttpServletDispatcher,發現,這是一種處理web請求的框架,名字叫“RESTEasyJAX-RS”,通過這個工具可以實現,前端jsp通過傳送web url請求來處理或者查詢資料。這種工具中又是如何處理響應資訊頭的呢?通過搜尋發現,RESTEasy是通過java註解的方式來實現請求url的定義和響應資訊頭的配置。其中@Produces就是用來定義響應資訊頭的。那麼,data source管理介面中查詢所有已定義的資料來源資訊的url”http://localhost:8081/SpagoBI/restful-services/datasources?SBI_EXECUTION_ID=-1&_dc=1377007659045&page=1&start=&limit=5”對應的處理類是哪個呢?通過搜尋原始碼中的“@Path("/datasources")”發現,it.eng.spagobi.tools.datasource.service.rest.DataSourceCRUD.java中的getAllDataSources方法正好是查詢所有資料來源的方法。另外,也可以在“log/SpagoBI_[1]_OperatorTrace.log”檔案中發現箇中端倪。而這個方法註解上正好有個“@Produces(MediaType.APPLICATION_JSON)”,把這個改成@Produces("application/x-json;charset=UTF-8")就可以了。

       這種處理方式有些麻煩,要找到所有以這種註解方式註解的方法並改成新的註解。這工作量不小,也容易出錯。目前我沒有發現有沒有一種集中統一的方式來處理。

       剩下還有一箇中文問題,就是Maps功能。看到這種介面,馬上想起來,之前的版本中已經處理過了,方法是:把所有jsp檔案中的ISO-88559-1編碼改成UTF-8。同時增加html meta UTF-8。還有就是jsp頁面中有些input輸入框使用了value="<%=StringEscapeUtils.escapeHtml(label) %>" StringEscapeUtils類是“org.apache.commons.lang.StringEscapeUtils.java”這種方式在處理中文的時候同樣有問題,儲存到資料庫中中文字元是轉化後的,所以這個類要替換成我寫好的“com.zeroy.bi.util.StringEscapeUtils.java”。在一個是在web.xml中增加中文過濾器:

增加了這些以前成功驗證過的配置後,發現,Maps介面中還是不能儲存中文,但是其他,像document配置介面是可以儲存中文的。這時不得不去跟蹤下原始碼中的負責集中處理servlet的類“AdapterHTTP.java”。這個類中對form表單提交有兩個處理方法,分別是“handleMultipartForm”和“handleSimpleForm”,凡是走了handleSimpleForm方法的都能正常儲存中文,而“handleMultipartForm”方法卻不可以。這又是為什麼呢?原來,決定要走這個兩個方法中哪一個的判斷邏輯是:

    而isMultipartContent方法判斷的是jsp中form表單的enctype屬性。如下兩個form的不同定義:
<form method='POST' action='/SpagoBI/servlet/AdapterHTTP' id='mapForm' name='mapForm' enctype='multipart/form-data' >
    正是因為Maps功能頁面jsp中form 使用enctype='multipart/form-data'屬性,才會使處理類中使用了“handleMultipartForm”方法進行處理。那麼這個方法要怎麼改呢?也很簡單,只需要改一下249行的程式碼即可,如下圖
    到這裡,集中常見的中文處理問題已經都能解決,但還是不很完美。希望有研究的同學能提供更好的解決方法。歡迎加QQ群:150039031