java
  • postgresql
  • jdbc
  • unicode
  • 2014-12-04 51 views 1 likes 
    1

    每當通過我的應用程序進行插入時,所有Unicode字符(日語,希臘語等)都會被問號替換。PostgreSQL插入問號而不是Unicode字符

    SAVEPOINT "DAO" 
    LOG: execute <unnamed>: insert into foo values ($1,$2,$3) 
    DETAIL: parameters: $1 = '23', $2 = '34bcb5f2-e7ee-40cf-9103-f2d1bf2ac7acd853d7c6-1703-44d2-aa99-6fd1df84da37', $3 = 'Anyone-日本語_l' 
    

    正如您從上面的日誌條目中看到的,數據庫接受正確的Unicode參數。

    然而,在插入後,表項如下:

    23 | 34bcb5f2-e7ee-40cf-9103-f2d1bf2ac7acd853d7c6-1703-44d2-aa99-6fd1df84da37 | Anyone-???_l 
    

    我的第一個猜測是,這是一個數據庫配置的問題,但是我已確認(據我所知),其Postgres的通過執行確實接受UTF-8以下:

    SHOW server_encoding; 
    server_encoding 
    ----------------- 
    UTF8 
    (1 row) 
    
    SHOW client_encoding; 
    client_encoding 
    ----------------- 
    UTF8 
    (1 row) 
    

    我還進一步通過手動插入到數據庫中的條目cornfirmed此

    正如你從上面可以理解的,數據庫已經接受了我的值,併成功地將Unicode字符添加到數據庫中。

    此時,我認爲問題發生在將這些值從我的應用程序推送到JDBC連接器並進入數據庫時​​。我想可能是JDBC連接器需要被告知它將傳輸Unicode數據。確實是有辦法做到這一點,通過附加在JDBC連接器的網址如下:

    jdbc:postgresql://localhost/bar?useUnicode=yes&characterEncoding=UTF-8 
    

    不幸的是,上面沒有任何區別。

    我已經排除了應用程序的代碼,因爲它是一個非常大的項目的一部分,相關的碎​​片在這裏和那裏都是碎片。但是,我認爲它們與問題無關,因爲Postgres日誌清楚地顯示了它收到的參數。

    查詢和數據庫接收的unicode數據是否正確,導致此問題的原因是什麼?

    OS: RHEL 6.6 
    Postgres version: 9.3.5 
    JDBC Connector: Tried a couple (8.1, 9.3) 
    JRE: 1.7 
    

    數據庫確實期待UTF-8:

    psql -U postgres -h localhost --list 
    
    Name  | Owner | Encoding | Collate | Ctype | Access privileges 
    ----------------+----------+----------+-------------+-------------+-------------- 
    bar  | postgres | UTF8  | en_US.UTF-8 | en_US.UTF-8 | 
    

    相關條目的BYTEA結果如下:

    SELECT foo_name::bytea FROM foo; 
    
    foo_name 
    -------------------------- 
    \x416e796f6e652d3f3f3f5f6c 
    

    問題嘛RKS實際上已經插入到數據庫:

    SELECT * FROM foo WHERE foo_name LIKE 'Anyone-?%' 
    23 | 34bcb5f2-e7ee-40cf-9103-f2d1bf2ac7acd853d7c6-1703-44d2-aa99-6fd1df84da37 | Anyone-???_l 
    

    我也抓起這是由JDBC控制器產生它被送入PGStream之前我的測試中一個的字節序列。

    {65, 110, 121, 111, 110, 101, 45, -26, -105, -91, -26, -100, -84, -24, -86, -98, 95, 105} 
    

    我已經通過執行這個轉換爲UTF-8字符串以下(在一個獨立的應用程序):

    String result = new String(bytes, StandardCharsets.UTF_8); 
    

    結果是正確的:Anyone-日本語_我

    +2

    只是爲了記錄在案,在'了useUnicode = yes'和'的characterEncoding = UTF-8'連接參數做不適用於所有JDBC驅動程序。它們特定於MySQL Connector/J,並且它們不出現在[PostgreSQL JDBC驅動程序的連接參數]列表中(http://jdbc.postgresql.org/documentation/93/connect.html#connection-parameters) 。 – 2014-12-04 18:56:04

    +1

    從OS命令行嘗試'psql -U postgres -h localhost --list'以列出數據庫並檢查相關實際數據庫的'Encoding'。您已驗證* server *的(默認)編碼是「UTF8」,但* database *可能具有不同的編碼。 – 2014-12-04 19:43:03

    +2

    運行'從表'中選擇column_with_dubious_text :: bytea來知道實際字節是否是預期的utf-8表示。取決於你會知道問題是預先插入還是後插入。 – 2014-12-04 20:16:38

    回答

    3

    深入調查我發現並解決了問題的遺留代碼。

    數據庫層工作得很好;當系統嘗試通過使用ByteArrayInputStream將相同的值重新插入數據庫時​​發生問題。

    通過在包含foo_name的字符串中執行getBytes()來填充ByteArrayInputStream。但是,調用此方法時應定義UTF-8編碼。

    通過改變:

    String name = "日本語"; 
    InputStream is = new ByteArrayInputStream(name.getBytes()); 
    

    到:

    String name = "日本語"; 
    InputStream is = new ByteArrayInputStream(name.getBytes(StandardCharsets.UTF_8)); 
    

    的問題是固定的。

    1

    我有unicode-8的問題,用postgres和glassfish。我在persistence.xml中試了這個,並修復了它。我希望它可以幫助你

    <properties> 
        <property name="javax.persistence.jdbc.url" 
          value="jdbc:postgresql://(url_Project)?useUnicode=yes"/> 
    </properties> 
    

    (url_Proyecto)是數據庫的完整URL

    相關問題