java
  • postgresql
  • jdbc
  • unicode
  • 2014-12-04 44 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

    相关问题