3

JavaMail 1.4.1 を使用して電子メール アカウントからメッセージを読んでいます (1.4.5 バージョンにアップグレードしましたが、同じ問題があります) が、コンテンツのエンコードに問題があります。

POP3Message pop3message;
... 
Object contentObject = pop3message.getContent();
...   
String contentType = pop3message.getContentType();
String content = contentObject.toString();

一部のメッセージは正しく読み取られますが、適切なエンコーディングが行われていないため、他のメッセージはおかしな文字になります。特定のコンテンツ タイプでは機能しないことに気付きました。

contentType が次のいずれかの場合にうまく機能します。

  • テキスト/プレーン; charset=ISO-8859-1

  • テキスト/プレーン;
    charset="iso-8859-1"

  • テキスト/プレーン;
    charset="ISO-8859-1";
    format="流れる"

  • テキスト/プレーン; charset=windows-1252

ただし、次の場合はそうではありません。

  • テキスト/プレーン;
    charset="utf-8"

この contentType (UTF-8 one) のエンコーディング (pop3message.getEncoding()) を取得しようとすると、

引用された印刷可能

後者のエンコーディングでは、たとえば、デバッガーで String 値を取得します (オブジェクトを永続化した後にデータベースで確認するのと同じ方法で):

Ubicación (Ubicación の代わりに)

しかし、ブラウザのメール クライアントでメールを開くと、問題なく読むことができ、通常のメッセージ (添付ファイルなし、テキストのみ) であるため、メッセージは問題ないようです。

この問題を解決する方法について何か考えはありますか?

ありがとう。


更新 これは、jlordo によって与えられた関数 getUTF8Content() を試すために追加したコードです。

POP3Message pop3message = (POP3Message) message;
String uid = pop3folder.getUID(message);

//START JUST FOR TESTING PURPOSES
if(uid.trim().equals("1401")){
    Object utfContent = pop3message.getContent();
    System.out.println(utfContent.getClass().getName()); // it is of type String
    //System.out.println(utfContent); // if not commmented it prints the content of one of the emails I'm having problems with.
    System.out.println(pop3message.getEncoding()); //prints: quoted-printable
    System.out.println(pop3message.getContentType()); //prints: text/plain; charset="utf-8"
    String utfContentString = getUTF8Content(utfContent); // throws java.lang.ClassCastException: java.lang.String cannot be cast to javax.mail.util.SharedByteArrayInputStream
    System.out.println(utfContentString);
}

//END TEST CODE
4

4 に答える 4

1

これらのメッセージに「奇妙な文字」が含まれていることをどのように検出していますか?データをどこかに表示していますか?データを表示するために使用している方法が、Unicode文字を適切に処理していない可能性があります。

最初のステップは、問題が間違った文字を取得しているのか、正しい文字が正しく表示されていないのかを判断することです。データ内(たとえば、getContentメソッドから返された文字列内)の各文字のUnicode値を調べて、各文字が正しいUnicode値を持っていることを確認できます。もしそうなら、問題はあなたが文字を表示するために使用している方法にあります。

于 2012-11-14T19:05:25.080 に答える
0

これを試して、うまくいくかどうか教えてください:

if ( *check if utf 8 here* ) {
    content = getUTF8Content(contentObject);
}

// TODO take care of UnsupportedEncodingException, 
// IOException and ClassCastException
public static String getUTF8Content(Object contentObject) {
    // possible ClassCastException
    SharedByteArrayInputStream sbais = (SharedByteArrayInputStream) contentObject;
    // possible UnsupportedEncodingException
    InputStreamReader isr = new InputStreamReader(sbais, Charset.forName("UTF-8"));
    int charsRead = 0;
    StringBuilder content = new StringBuilder();
    int bufferSize = 1024;
    char[] buffer = new char[bufferSize];
    // possible IOException
    while ((charsRead = isr.read(buffer)) != -1) {
        content.append(Arrays.copyOf(buffer, charsRead));
    }
    return content.toString();
}

ところで、JavaMail 1.4.1 は必須ですか? 最新バージョンは 1.4.5 です。

于 2012-11-14T20:43:26.590 に答える
0

私にとってうまくいったのは、私が呼び出しgetContentType()て、文字列に「utf」が含まれているかどうかを確認することでした(UTFの1つとして使用される文字セットを定義します)。

はいの場合、この場合はコンテンツを別の方法で扱います。

private String encodeCorrectly(InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is, StandardCharsets.UTF_8.toString()).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

( SO に関するこの回答からの IS から String へのコンバーターの変更)

ここで重要なのは、正しい文字セットを使用することです。これで問題は解決しました。

于 2015-09-18T14:54:51.420 に答える