質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.93%

JavaMailで環境依存文字が文字化け

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 6,423

score 9

前提・実現したいこと

JavaMailでWindows環境依存文字の文字化けを解消したいです。
代替文字に置き換える方法ではなく、①は①として送りたいと思っています。
・charsetはISO-2022-JPです。
・起動オプションでx-windows-iso2022jpに読み替える方法が今の開発では使用できません。
・メールの確認方法として、メーラーが環境整ってなくて使用できないので、
メールサーバーに送られたメールを落としてきて、
サクラエディタにてJIS→SJISに変換してメールの確認をしています。

発生している問題・エラーメッセージ

JavaMailを使用してメールを送ろうとしていますが、①や㍻等のWindows環境依存文字が文字化けしています。
前提に記述したとおり、起動オプションに設定を追加する方法が取れませんので、
①等をJISコードにするメソッド(下記参照)を作ったのですが、ステップ数が多く、
今の開発の規約で200ステップに抑えるようにと言われているので今のままでは使えません。
ステップ数を抑えるや他に何かやり方がないでしょうか?
よろしくお願いします。

該当のソースコード

引数で貰った文字列の中に①等の環境依存文字があったら、$B-! (B等JISコードに変換しています。
これでreturnした文字列をメール本文としてsetTextに渡して送信しています。
public String convert(String str){
if(str == null){
return null;
}
char[] ch = str.toCharArray();
char[] convert = new char[500];
int j = 0
for(int i = 0; i < ch.length; i++){
switch (ch[i]){
case ‘\u2460’: //①のUnicode
convert[j] = ‘\u001B’ //ESC
j++;
convert[j] = ‘\u0024’ //$
j++;
convert[j] = ‘\u0042’ //B
j++;
convert[j] = ‘\u002D’ //-
j++;
convert[j] = ‘\u0021’ //!
j++;
convert[j] = ‘\u001B’ //ESC
j++;
convert[j] = ‘\u0028’ //(
j++;
convert[j] = ‘\u0042’ //B
j++;
break;
case ‘\u2460’: //②のUnicode
convert[j] = ‘\u001B’ //ESC
j++;
convert[j] = ‘\u0024’ //$
j++;
convert[j] = ‘\u0042’ //B
j++;
convert[j] = ‘\u002D’ //-
j++;
convert[j] = ‘\u0022’ //"
j++;
convert[j] = ‘\u001B’ //ESC
j++;
convert[j] = ‘\u0028’ //(
j++;
convert[j] = ‘\u0042’ //B
j++;
break;
(略)環境依存文字分、①②と似たことを書いてます。
default:
convert[j] = ch[i];
j++;
break;
}
return String.valueOf(convert);
}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+1

なぜこんなに無駄に行数長くしているのですか?Unicodeのところまとめて文字列リテラルにすればいいのに。
また、StringBuilderという便利なクラスがありまして…

public String convert(String str){
    if(str == null){
        return null;
    }
    char[] ch = str.toCharArray();
    StringBuilder builder = new StringBuilder();
    for(int i = 0; i < ch.length; i++){
        switch (ch[i]){
        case '\u2460': //①のUnicode
            builder.append("\u001B\u0024\u0042\u002D\u0021\u001B\u0028\u0042");
            continue;
        case '\u2461': //②のUnicode
            builder.append("\u001B\u0024\u0042\u002D\u0022\u001B\u0028\u0042");
            continue;
        // 中略
        default:
            builder.append(ch[i]);
        }
    }
    return builder.toString();
}


なお、丸数字からの変換規則はよくわかりませんが、5文字目が単純に順番に対応するだけなら、
まとめてこう書けそうな気がします。

// 丸付き1~20までに対応するUnicode
if (0x2460 <= ch[i] && ch[i] <= 0x2473) {
    builder.append("\u001B\u0024\u0042\u002D").append((char)(0x21 + (ch[i] - 0x2460))).append("\u001B\u0028\u0042");
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/20 09:16 編集

    回答ありがとうございます。

    char型以外コードポイントをいれてもただの文字列として扱われると思っていたので、長くなっていました。

    追記
    解決できそうです。ありがとうございました。

    キャンセル

  • 2017/06/20 10:13

    Unicodeエスケープはあらゆる解析に先立って解釈されるため、コード中の{を\u007Bと書くこともできます。

    キャンセル

0

メールを送信する対象にもよりますが、思い切ってcharsetをUTF-8にしてみるとか?
一昔前は、対応していないSMTPサーバーやメーラーが多かったので、
ISO-2022-JP 7bitが常識でしたけど、最近はけっこうUTF-8いけますよ。
GmailもUTF-8 base64 で送ってますし。
ただ、ガラケーとかだとしんどいかもしれません。。。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/21 19:59 編集

    返信が遅れてしまい申し訳ありません。回答ありがとうございます。
    その案も真っ先に上げましたが、却下されてしまいました。。。
    それで、あれこれと模索していました。
    メールはISO-2022-JPで送るものっていうのを変えたくないのかもしれません。

    キャンセル

-1

便乗質問で大変申し訳ありませんが、こちらも同じ内容で悩んでおりましたが、
環境等は、全て投稿された「HiroS」さんと同じで、ご回答頂きました「swordone」
さんの内容で、対応をしようと実施しました。
しかし、「①」が「$B-!(B」へ化けてしまい思うように「①」と表示出来ません。

「やりたい事」
JavaMailで環境依存文字(①から⑳まで)の
文字化けをしないでメール上に正しく表示させたい。

「IDE環境」
①.OS:Windows7
②.IDE:Eclipse(Ver.4.8)All In One
③.JDK:Eclipseバンドル版JDK10.0.1
④.MIAL:Apache commons-email(SimpleEmail) 

public static void main(String[] args) {
   String _maruichi = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳";
   char[] chars = _maruichi.toCharArray();
   StringBuilder _sb = new StringBuilder();

   for ( int i = 0; i < chars.length; i++ ) {
          // ①⇒1、②⇒2、③⇒3に変換
          if ( 0x2460 <= chars[ i ] && chars[ i ] <= 0x2462 ) {
             _sb.append( "\u001B\u0024\u0042\u0023" ).
                append( ( char )( 0x31 + ( chars[ i ] - 0x2460 ) ) ).
                append( "\u001B\u0028\u0042" );
        }
        else {
            _sb.append( chars[ i ] );
           }
    }
   String out = _sb.toString();
   System.out.println( out );
}


なぜなのかを教えて頂けませんでしょうか。

以上、宜しくお願い申し上げます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/14 22:11

    「①」を「$B-!(B」に変換するためのコードなので、もしかしたら、メーラーの環境に原因があるかもしれません。エンコードの設定を変えると正常に見えるかもしれません。

    自前でjisコードに変換する無理やりな方法なので、charsetを変えれるようなら、charsetを変えたほうが良いと思います。

    キャンセル

-2

HiroSさん、ご返信が遅くなり、
大変申し訳ありませんでした。

「$B-!(B」をサクラエディター上へコピペして、
「変換」>「文字コード変換」>「EMAIL(JIS→SJIS)コード変換」
を実行すると、正しく「①」へ変換されますが、メール上の当該環境依存文字
だけは、「$B-!(B」で化けてしまします。

charsetヘッダー変更の件につきましては、
1.「x-windows-iso2022jp」は、イントラ側が古い為、
本文・ヘッダー含めて化けてしまいました。
2.「iso-2022-jp」は、当該環境依存文字のみ化ける現象でした。
3.「shift_jis」は、本文・ヘッダー含めて化けてしまいました。

因みに、メーラーについては、
1.Net側側は、Thunderbird(自動判別の日本語)で、日本語(ISO-2022-JP)です。
2.Intra側は、Sylpheed(自動認識)です。

以上、宜しくお願い申し上げます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/17 14:59

    ここは回答するところなので、質問するなら新たに質問を立てましょう。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る