AS400内のアプリは、5250エミュレータで接続することで操作可能になりますが、AS400の外にApplication Server(Web, Java)を立て、AS400(DB2 for i)をDB Serverで運用する場合、JDBCドライバーを使って、Web・DB間のやり取りを行うようになります。
この場合、役割が分離されて管理はしやすくなるのですが、Webアプリ側できちんとバリデーション対応をしていないと、文字化けで悩むことになります。
最近、文字化けではまったケースが2回あったので、備忘録としてまとめておきます。
文字化けとなった文字
DB側で文字化けとなってしまった対象の文字は、次の2つ。
- 水平TAB
- ラテン文字の中点
水平TABなんかは、WEB画面へ直接入力することはできないはずなんです。
しかし、操作をした方に聴いてみると、どちらの場合も「お取引先様からいただいたファイル」から情報をカット&ペーストしたという話でした。
その結果、バリデーション・チェックされずに、DBに格納されてしまったというわけです。
AS400側での文字化けの表示
- AS400のCCSIDは、5026。
- 文字化けが含まれているレコードをUPDDTAコマンドで直接中身を確認してみました。
水平TAB
「検索されたレコードに正しくないデータが入っている。」とエラーになり、レコードを開くことができませんでした。
ではなぜ、文字化け対象文字が、水平TABであるかがわかったのか? SQLのHEX関数でEBCDICの文字コードを確認できたからです。
SELECT MODEL, HEX(MODEL) FROM LIB_NAME.TABLE_NAME WHERE KEY = 'XXXXXXXXXX' -- MODEL HEX ( MODEL ) -- 123 F1F2F30540404040404040404040404040404040
せっかくなので、各サイトを頼りに今回の文字コードを調べました。
文字 | EBCDIC | Unicode | UTF-8 | MS932 |
---|---|---|---|---|
水平TAB | 0x05 | 0x09 | 0x09 | 0x09 |
ラテン文字の中点 | 0xD64D | 0xB7 | 0xC2 0xB7 | 0x8145(※注: 全角の中点と同じコード) |
ラテン文字の中点
UPDDTAコマンドでレコードは表示されましたが、該当文字の部分が「・」になっていました。 これは、ラテン文字中点としての中点ではなく、5250アプリでも、①などの機種依存文字を入力した場合に「・」と表示されていたので、同様に文字化けとして「・」という文字に置換されていると考えてよさそうです。
ACSの表示設定の中には、文字化けの場合、変換して表示する機能があることを発見したので、こちらの設定が適用されて「・」と表示されているのでしょう。
ちなみに、ACSの文字化け置換の確認・設定は、「編集 > 設定 > 外観 > 表示」の画面内で操作可能でした。
AS400側での文字化けの影響
- ODBCで接続しているサブシステム側で問題がありました。
SQLツール(ODBCドライバー連携)やPHPアプリでは、文字化け箇所が「?」に置換されて表示されたのですが、VBアプリでは文字化けフィールドをSQLで取得しただけで例外扱いになり、正常の処理ができなくなってしまいました。
ODBCドライバーとVBの相性が悪いのでしょうか?
それとも最新のODBCドライバーでは置換されるのか不明ですが、VBアプリで今回の文字化けの影響があることがわかりました。
解決策
- やはり、DBにエントリーするWebアプリできちんとバリデーションを行えばよいでしょう。
- もともと自作したStringUtilsクラス内で、AS400へ書き込み可能な文字列かのメソッドを用意していたので、その中に水平TABとラテン文字の中点を追加しました。
- 2つの文字だけをバリデーションエラーとする場合のサンプルソースは、下記の通りです。JavaEEであれば、このメソッドとBeanValidationを結びつければ、シンプルな実装が可能になります。
public static boolean canSetDB400(String target) { // Unicodeでの判別 for (char c : target.toCharArray()) { //ラテン文字の中点(0xb7)、水平TAB(0x9)は除外 String s = Integer.toHexString(c); if (s.equals("b7") || s.equals("9")) { return false; } } return true; }