茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1729597 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
PI20101106_00093.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2019/11/5 10:30:42

javaMail 標題亂碼說明及處理











原文如下,(作者未知)


使用java mail 包收發中文郵件的編碼,解碼問題以及解決方法












編碼



郵件頭(參見RFC822,RFC2047)只能包含US-ASCII字符。郵件頭中任何包含非US-ASCII字符的部分必須進行編碼,使其只包含US-ASCII字符。所以使用java mail發送中文郵件必須經過編碼,否則別人收到你的郵件只能是亂碼一堆。不過使用java mail 包的解決方法很簡單,用它自帶的MimeUtility工具中encode開頭的方法(如encodeText)對中文信息進行編碼就可以了。



例子:




MimeMessage mimeMsg = new MimeMessage(mailSession);



//讓javamail決定用什麼方式來編碼 ,編碼內容的字符集是系統字符集


mimeMsg.setSubject( MimeUtility.encodeText( Subject) );





//使用指定的base64方式編碼,並指定編碼內容的字符集是gb2312



mimeMsg.setSubject( MimeUtility.encodeText( Subject,”gb2312”,”B”));







通常對郵件頭的編碼方式有2種,一種是base64方式編碼,一種是QP(quoted-printable)方式編碼,javamail根據具體情況來選擇編碼方式。





如“txt測試”編碼後內容如下:



=?GBK?Q?Txt=B2=E2=CA=D4







裡面有個=?GBK?Q?,GBK表示的是內容的字符集,?Q?表示的是以QP方式編碼的,後面緊跟的才是編碼後的中文字符。所以用MimeUtility工具編碼後的信息裡包含了編碼方式的信息。




郵件的正文也要進行編碼,但它不能用MimeUtility裡的方法來編碼。郵件正文的編碼方式的信息是要放在Content-Transfer-Encoding這個郵件頭參數中的,而MimeUtility裡面的方法是將編碼方式的信息放在編碼後的正文內容中。所以如果你對正文也用MimeUtility進行處理,那麼其他郵件程序就不會正常顯示你編碼的郵件,因為其他郵件軟件如outlook,foxmail只會根據Content-Transfer-Encoding這個裡面的信息來對郵件正文進行解碼。



其實,郵件正文部分的編碼javamail已經自動幫你做了,當你發送郵件的時候,它會自己決定編碼方式,並把編碼方式的信息放入Content-Transfer-Encoding這個郵件頭參數中,然後再發送。所以你所要做的就是直接把郵件正文的內容放入郵件中就可以了。



對郵件正文的編碼方式比較多,包括了base64和QP方式,還有一些如7bit,8bit等等,因為javamail自動為郵件正文編碼,所以我就不一一祥敘了。





例子:



//處理郵件正文



MimeBodyPart mbp=new MimeBodyPart();



if ( ContentType() == null || ContentType.equals(""))



mbp.setText( Content );



else



mbp.setContent( Content, Content );








解碼





javamail包中的MimeUtility工具中也提供了對郵件信息解碼的方法,都是以decode開頭的一些方法(如decodeText)



例子:



String Subject = mimemsg.getSubject();



String ChSubject = MimeUtility.decodeText(Subject);



對於base64和QP編碼後信息,decode* 方法能將他們正確的解碼,但是,如果指定的字符集不對,那麼javamail就會出現錯誤,不能正確地將其解碼。



如有的郵件系統將”txt測試”編碼後如下:



=?x-unkown?Q?Txt=B2=E2=CA=D4



這裡指定的字符集是x-unknown,是非明確的字符集,javamail就不能正確的處理了,但是”測試”這兩個中文字還是按照gbk字符集編碼的,所以你可以手工的將編碼方式信息改正確,再用decode*方法來解碼。





例子:



if ( str.indexOf("=?x-unknown?") >=0 ){



str = str.replaceAll("x-unknown","gbk" ); // 將編碼方式的信息由x-unkown改為gbk



try{




str = MimeUtility.decodeText( str ); //再重新解碼



}catch( Exception e1){



return str ;



}



decode*方法都是根據在編碼信息中包含的編碼方式的信息來解碼,所以decode*方法對郵件正文解碼是無效的,因為郵件正文中不包含編碼方式的信息。

同編碼一樣,郵件正文的解碼也是由javamail做了。Javamail根據Content-Transfer-Encoding裡的信息,來對郵件的正文解碼。

客戶程序從javamail取得的正文內容字符集為iso-8859-1,所以還要將字符集轉換一下,例:



String CorrectContent = new String( Content.getbytes(“iso-8859-1”),”gb2312”);



CorrentContent為正確的郵件正文了 。


本人測試了一下,發送郵件時沒有什麼問題,javaMail會自動為你加上編碼信息


接收時發現subject的編碼一般與正文相同,需要做字符串轉換。


相關代碼如下:

        String contenttype = part.getContentType();


        System.out.println("CONTENTTYPE:  " + contenttype);

        int icharset = contenttype.toLowerCase().indexOf("charset");

        if (icharset != -1) {

            System.out.println(contenttype.charAt(icharset + 8));

            if (contenttype.charAt(icharset + 8) == '"') {

                int iend = contenttype.lastIndexOf("\"");

                if (iend > icharset + 9) {


                    bodyCharset = contenttype.substring(icharset + 9, iend);

                }

            }

            else {

                bodyCharset = contenttype.substring(icharset + 8);

            }

        }


取得正文編碼信息。Foxmail發送的郵件一般為text/html;charset="GB2312",其他的為text/html;charset=GB2312,差了一個引號。還有一些郵件沒有編碼信息,此時bodyCharset默認為ISO-8859-1。



            subject = MimeUtility.decodeText(mimeMessage.getSubject());

            if (subject == null) {

                subject = "";

            }

            subject = new String(subject.getBytes(bodyCharset), "GBK");


內容解碼同上。


試了試FoxMail,WEB,javamail等方式發送的郵件,MimeUtility.decodeText(mimeMessage.getSubject())與mimeMessage.getSubject()的值是相等的。





原文出處:javaMail 標題亂碼說明及處理 @ 狼翔天地 :: 痞客邦 ::
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|