- - PR -
DBの値を取り出す際の文字化けについて
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-09-03 00:57
○事象:
DBから値を取り出すと文字化けしている。 tomcat、MySQLは同一マシンで稼働しており、文字コードはutf8にしているつもりです。 DB設定、tomcatからDBへの接続設定など見直したのですが、原因がわかりません。 他に確認すべき個所等あれば、ご教授願えないでしょうか。 ○環境: Linux FedoraCore5 tomcat 5.5.17 JDK 1.5.0_07-b03 MySQL 5.0.22 ○DB値を取得するJavaロジック InitialContext ic = new InitialContext(); DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/MySQLXoops"); Connection con = ds.getConnection(); Statement stmt = con.createStatement(); String sql = "SELECT * FROM xoops_users"; ResultSet rs = stmt.executeQuery(sql); int user_id = 0; while(rs.next()){ String uname = rs.getString("uname");・・・・・(※) user_id = rs.getInt("uid"); if (uname.equals(villagerName)){ flag = true; break; } } ※のunameを標準出力すると文字化けしています。 文字化けの仕方は、このような具合です。 \A\1\E\a!?\¶ これを確認したのもutf-8エンコーディングのコンソール上です。 ※の部分を String uname = new String(rs.getString("uname").getBytes("8859_1")); このようにしてみてもだめでした。 この時は ・・・・・ のように化けています。 ○tomcat設定 ・/usr/share/tomcat5/conf/Catalina/localhost/コンテキスト名.xml <Context docBase="コンテキスト名" path="/コンテキスト名" reloadable="true" source="org.eclipse.jst.j2ee.server:コンテキスト名"> <Resource name="jdbc/MySQLXoops" auth="Container" type="javax.sql.DataSource" username="ユーザ名" password="パスワード" driverClassName="org.gjt.mm.mysql.Driver" url="jdbc:mysql:///xoops?useUnicode=true&characterEncoding=utf8"/> </Context> ○DB設定: xoopsという名のデータベース内にxoops_usersテーブルがあります mysql> status; : Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 : mysql> show full columns from xoops_users; +-----------------+-----------------------+-----------------+------+-----+-----------+----------------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-----------------+-----------------------+-----------------+------+-----+-----------+----------------+---------------------------------+---------+ | uid | mediumint(8) unsigned | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | | | name | varchar(60) | utf8_general_ci | NO | | NULL | | select,insert,update,references | | | uname | varchar(25) | utf8_general_ci | NO | MUL | NULL | | select,insert,update,references | | : : mysql> show create database xoops; +----------+----------------------------------------------------------------+ | Database | Create Database | +----------+----------------------------------------------------------------+ | xoops | CREATE DATABASE `xoops` /*!40100 DEFAULT CHARACTER SET utf8 */ | +----------+----------------------------------------------------------------+ | ||||||||
|
投稿日時: 2006-09-03 01:15
追加情報です。
JDBCは以下のものです。解凍したjarファイルをcommon/libに配備しています。 http://dev.mysql.com/downloads/connector/j/5.0.html | ||||||||
|
投稿日時: 2006-09-03 12:43
getString()ではなく、getBytes()を使ってどういうデータが送られてきているかを 確認されてはいかがでしょうか。 生のバイト列を各種エンコードしたバイト列と比べてみれば何かわかるかも。 少なくともUTF-8にしているつもりだけど設定できていないのかどうかを 確認することはできますよね? | ||||||||
|
投稿日時: 2006-09-03 16:24
(※)の部分をこのようにしてみました。
byte[] uname = rs.getBytes("uname"); for (byte b:uname){ System.out.print(Integer.toHexString(b) + " "); } 出力結果: ffffffc2 ffffffa5 ffffffc3 ffffff86 ffffffc2 ffffffa5 ffffffc2 ffffffb9 ffffffc2 ffffffa5 ffffffc3 ffffff88 中身には「テスト」といれているつもりです。1文字が4byteになってる? UTF8は3byteだったような…。 取り急ぎ報告です。 | ||||||||
|
投稿日時: 2006-09-03 17:13
そりゃ、byteをintにキャストしてるのですから。 0〜7fまではそのまま表示、80〜ffまでは上位3byteがfで埋まって 表示されることでしょう。
みたいな工夫は必要です。 もっとスマートに書く方法もありそうですけどね。 さて、問題の本質は c2, a5, c3, 86, c2, a5, c2, b9, c2, a5, c3, 88 というバイト列は何者なのかということですが。 DBに入っているデータはどういったものでしたか? その文字列をいろいろなエンコードで変換したバイト列と 見比べるとなにかわかるかもしれませんね。 | ||||||||
|
投稿日時: 2006-09-03 17:39
1文字が4byteと書いたのは、 「テ」が c2, a5, c3, 86の4つのbyte列 「ス」が c2, a5, c2, b9の4つのbyte列 「ト」が c2, a5, c3, 88の4つのbyte列 で表現されているという意味です。 ff埋めのことではなかったのですが、わかりにくくてすいません。
前投稿にも書いたのですが、「テスト」といれているつもりです。 「テスト」は本来、 E3 83 86、E3 82 B9、 E3 83 88 とならなければならないようです。 なぜかそれぞれの文字の最後のbyte列「86」、「B9」、「88」だけは合っているということはわかりました。さらに調べます。 [ メッセージ編集済み 編集者: Java使い 編集日時 2006-09-03 17:45 ] | ||||||||
|
投稿日時: 2006-09-03 17:49
「テスト」のEUCコード a5 c6 a5 b9 a5 c8 を 0xa5c6 0a5b9 0xa5c8 という Unicodeだとみなして UTF-8 にエンコードすると、そういうバイト列になります。 EUCで書き込んだデータをUTF-8で読み出しているということは、ありませんか? | ||||||||
|
投稿日時: 2006-09-03 19:28
なるほど…。 DBには「テスト」をUTF8エンコードしたバイト列が格納されているのではなく、 「テスト」のEUCコードをUTF8にエンコードしたバイト列が格納されているということになるのでしょうか…。 格納の仕方に問題がありそうですが、今からその部分を変更することは難しいのです。 読み出しの仕方によって解決できるのでしょうか。 |