
Java初心者です。
(確認したい内容)
ServletからMySQLのデータを取得したResultSetの項目で、2バイト文字が文字化けしていました。
私自身で調査した結果、
str = new String(str.getBytes("ISO-8859-1"), "JISAutoDetect");
※str…文字化けしている項目
のコーディングで文字化けが解消されました。
しかし、この対応だと全ての2バイト文字に対して、このコーディングを入れなければなりません。
これはスタンダードなコーディングなんでしょうか?
それとも環境周りの設定一発で不要になるものなんでしょうか?
私自身の周りに先生がいないため、自分の書いてるコーディングに自信がありません。
ご意見よろしくお願いします。
(環境)
WinXP-Pro-SP1
j2sdk4.1.2_05
Tomcat4.1.24
Eclipse2.1.3
MySQL4.1.7
No.4ベストアンサー
- 回答日時:
MySQLのバージョンあわせてませんでした。
すみません。
>必ずUTF8経由での文字変換していてそのマッピングがSJISとEUCだけだから
>一部文字列が通らない
>サーバーもクライアントもUTF8設定ならキャラクタ変換が起こらないので
>クライアント側であらためて好きな文字コードに変換するしか今のところない
というように2バイト文字の扱いが変化しているようです。
おそらくダウングレードするか、マイナーバージョンアップするのを待つと直ると思いますが、
クラス設計をすることによって回避できます。
つまりResultSetインターフェースを実装したカスタムResultSetを作成するとビジネスロジックを変化させることなく、文字化けやその他の低レベル層での環境の違いをResultSetで吸収できます。
いいかえてみるならば、JDBCドライバをカスタム化するといってもいいでしょうか。
もちろんResultSetはStatementオブジェクトから取得されますから、Statementオブジェクトもカスタム化します。
コネクション周りは大手ベンダーはすべてカスタム化して、フレームワークに埋めこんでますので、一度コネクション周りを作ってみるのもいいかもしれません。
私も製品としてフレームワークとコネクション周りを作成しましたが、相当便利になります。
hidebu-さん、ありがとうございました。
>おそらくダウングレードするか、マイナーバージョンアップするのを待つと直ると思いますが、
>クラス設計をすることによって回避できます。
とりあえず今の私の知識レベルだと、ダウングレードかマイナーバージョンアップを
待つ方法を取りたいと思います。
カスタム化については、もう少しJavaの知識を増やしつつ勉強したいと思います。
No.3
- 回答日時:
とりあえずコネクション部分の接続文字列がきちんとしていれば可能なはずです
-------------------------------------------------
public class test {
static public void main(String[] args) {
Connection connection = null;
try{
Class.forName("org.gjt.mm.mysql.Driver");
connection = DriverManager.getConnection("jdbc:mysql:///test?useUnicode=true&characterEncoding=SJIS");//接続文字列
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from test");
if(resultSet.next()){
System.out.println(resultSet.getString(2));//対象の文字列を取得するところ
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
connection.close();
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
}
}
-------------------------------------------------
こんな感じになると思いますが
どこか相違点ありますか?
この回答への補足
以下のようなコーディングです。
//コネクションの取得メソッド
private static Connection _getConnection() throws NamingException, SQLException {
/* イニシャルコンテキストの取得 */
Context ctx = new InitialContext();
/* データソースをアプリケーションサーバーから取得(JNDIのルックアップ) */
DataSource ds = (DataSource) ctx.lookup("java:comp/env/データソース名");
/* コネクションを取得して返す */
return ds.getConnection();
}
//MySQLからのデータ取得メソッド(一部抜粋)
public static UserData checkUser(String empid, String passwd) throws Exception {
/* ユーザテーブルからのデータ取得SQL */
String sqlstr = "select * from user_tbl where empid = ?";
Connection con = null;
UserData user = new UserData(empid);
try {
/* コネクションの取得 */
con = _getConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
/* PreparedStatementを作成し問い合わせを実行 */
stmt = con.prepareStatement(sqlstr);
stmt.setString(1,empid);
rs = stmt.executeQuery();
/* 結果の存在確認 */
if (!rs.next()) {
user.setLoginState("user_not_found");
return user;
}
/* パスワードのチェック */
if (!rs.getString(2).equals(passwd)) {
user.setLoginState("passwd_invalid");
return user;
}
/* ユーザ情報をセット */
user.setEmpName(rs.getString(3));
-----------------------------------------------------------------
データソースurl
jdbc:mysql://localhost/empdb?useUnicode=true&characterEncoding=SJIS
余計なコードも入ってしまっていますが、私が分かる相違点として以下のことがあります。
1.lookupを使用している
2.prepareStatementを使用している
※MySQL4.1.7をしようしているのが原因でしょうか?
No.2
- 回答日時:
JDBCドライバの実装に依存しますが、
基本的にJDBCのコンバータとMySqlの文字エンコーディングがあっていないんでしょう。
JDBCドライバのバージョンとMySqlの文字エンコーディングが何なのかを教えてくれると判断しやすいですが。
普通はコネクションなどはFactryパターン等を使用して、取得するようにします。
ステートメント取得
クエリー発行
レコード取得
といった感じになっていると思いますが、生のコネクションからステートメントを取得すると、ステートメントやResultSetをラッピングすることができなくなるので、いろいろと厄介ですよ。
ResultSetをラッピングしておけば、ResultSet内のgetString()等のメソッド内で適切なエンコーディングが出来ますから。
この回答への補足
ご回答ありがとうございます。
使用しているJDBCは以下のものです。
mysql-connector-java-3.0.15-ga-bin.jar
MySQLの文字エンコーディング
[mysqld]
default-character-set=sjis
です。
No.1
- 回答日時:
まず、mysql に接続
mysql> SHOW CHARACTER SET
とすれば、お使いのmysqlのキャラクタセットが分かります。
それが合っていない可能性が。
my.cnf で設定を確認できます。
どこに問題があるか分からなくなったときは、文字列を hex (16進) に変換して出力すると、何がどうなってるか分かることが多いですよ。
ご回答ありがとうございます。
mysql> SHOW CHARACTER SET の結果には34個のcharacter set が出てきました。
その中にはsjisも入ってました。
my.iniの設定には
[mysqld]
default-character-set=sjis
が記述されています。
文字列の16進変換は未着手です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- PDF PDFソフト 1 2023/08/23 16:14
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- Excel(エクセル) ExcelデータのMacとWindowsの文字化け対策について教えてください‼︎ 私はMacを使って 1 2022/08/22 12:46
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- その他(プログラミング・Web制作) python質問 1 2023/08/14 11:54
- Excel(エクセル) 表示形式、文字列セル(列)に数式を入力するには マクロ 1 2022/09/18 10:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
javaで質問です。 文字列2023/2...
-
ダブルクォーテーションのrepla...
-
DBから取得したデータの文字化け
-
substring バイト単位でやりたい
-
javascriptで文字列のsjis利用...
-
エクセルVBAで「〜」が表現でき...
-
JavaのStringクラスに「外字」...
-
カタカナをローマジに変換する。
-
int型のゼロ埋め
-
javaの初歩的な質問です。
-
IE11においてのIME予測変換時の...
-
Path型をString型へ変換する(Java)
-
Visual Basic でのコードをASCI...
-
Oracle BLOB→Byte→.tif の変換
-
PerlプログラムをJavaに変換す...
-
System.err. printlnとSystem.o...
-
C言語のポインターに関する警告
-
一定のスペースを空けて端を揃...
-
ループ処理の際、最後だけ","を...
-
EXCEL VBA で、0から?1から?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
javaで質問です。 文字列2023/2...
-
ダブルクォーテーションのrepla...
-
javascriptで文字列のsjis利用...
-
javaの初歩的な質問です。
-
Visual Basic でのコードをASCI...
-
JavaのStringクラスに「外字」...
-
Path型をString型へ変換する(Java)
-
エクセルVBAで「〜」が表現でき...
-
int型のゼロ埋め
-
JAVAでのShift-JISとEUC-JP間の...
-
C言語32bitから64bitの移行につ...
-
UTF-8とUnicodeの互換性
-
文字列の比較
-
COBOLで半角カナを全角カナに変換
-
substring バイト単位でやりたい
-
Windows-31Jからutf-8への変換...
-
カタカナをローマジに変換する。
-
[Javascript]エンターキー押下...
-
byte型のマイナスの扱いについて
-
文字化け対策について
おすすめ情報