開心一刻
昨晚,媳婦很感傷的看著我
媳婦:以後歲數大了,我要走你前面去了,你再找個老伴
我:我不想找
媳婦:你找一個,不用替我守著,以後你說你頭疼發燒,也得有個給你端水遞藥的呀
媳婦抹著眼淚:到老是個伴
我:我想找個年輕的
現在我左臉還有一個掌印,火辣辣的
問題背景
基於 JavaMail 1.5.5 ,實現了郵件傳送功能,也對接了一些客戶,沒出現什麼問題
程式碼如下
/** * 郵件傳送 * @param message 郵件內容 * @param to 收件人郵箱 * @param attachment 附件 */ public static void sendEmail(String message, String to, File attachment) throws Exception { //設定郵件會話引數 Properties props = new Properties(); //郵箱的傳送伺服器地址 props.setProperty("mail.smtp.host", MAIL_HOST); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.fallback", "false"); props.put("mail.smtp.ssl.enable", "true"); //郵箱傳送伺服器埠,這裡設定為465埠 props.setProperty("mail.smtp.port", "465"); props.setProperty("mail.smtp.socketFactory.port", "465"); props.put("mail.smtp.auth", "true"); //獲取到郵箱會話,利用匿名內部類的方式,將傳送者郵箱使用者名稱和密碼授權給jvm Session session = Session.getDefaultInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(MAIL_USER_NAME, MAIL_AUTH_CODE); } }); // 開啟除錯,生產不開啟 session.setDebug(true); Multipart multipart = new MimeMultipart(); BodyPart contentPart = new MimeBodyPart(); //contentPart.setContent(message, "text/html;charset=UTF-8"); contentPart.setText(message); multipart.addBodyPart(contentPart); if (attachment != null) { BodyPart attachmentBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(attachment); attachmentBodyPart.setDataHandler(new DataHandler(source)); //MimeUtility.encodeWord可以避免附件檔名亂碼 attachmentBodyPart.setFileName(MimeUtility.encodeWord(attachment.getName())); multipart.addBodyPart(attachmentBodyPart); } //透過會話,得到一個郵件,用於傳送 Message msg = new MimeMessage(session); //設定發件人 msg.setFrom(new InternetAddress(MAIL_USER_NAME)); //設定收件人,to為收件人,cc為抄送,bcc為密送 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false)); // msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(to, false)); // msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(to, false)); msg.setSubject("我是主題"); //設定郵件訊息 msg.setContent(multipart); //設定傳送的日期 msg.setSentDate(new Date()); //呼叫Transport的send方法去傳送郵件 Transport.send(msg); }
附件名是做了編碼處理的
我們來看下接收情況
Foxmail
outlook windows 版本
一切看似都很平靜
直到她們的出現,讓我慌了神
QQ郵箱(web 端)
outlook web 版本
此刻,我們的腦中應該有 2 個問題
1、亂碼該如何修復
2、為什麼客戶端版(Foxmail、outlook windows版)接收正常,而 web版 卻出現了亂碼?
亂碼處理
這個上網一搜,很容易就能找到答案,加一個系統屬性即可
mail.mime.splitlongparameters 預設值是 true ,表示編碼後的附件名檔名長度超過 60 之後會進行多段拆分,每 60 個字元作為一個引數,最後不足 60 個字元的作為一個引數
我們把 mail.mime.splitlongparameters 設定成 false ,再看下效果
QQ 郵箱
outlook web
有人可能會有疑問了:你說 60 就 60,你說拆分就拆分?
既然不信我,那我們從原始碼找答案
原始碼解析
設定附件名的時候,有這樣一段程式碼
注意第一個 if 中的條件,是有三個
1、附件名編碼後的長度
2、 mail.mime.splitlongparameters
3、 mail.mime.encodeparameters ,預設值是 true
當三個條件都為 true ,才會以 60 字元為單位進行多段拆分
你好_好久不見_別來無恙_20230306.txt 編碼後再拆分得到的結果是
檔名被拆分成了三段,我可曾欺你們?
為什麼只有 web 版“亂碼”
此刻需要糾正下,web 版出現的附件名不是亂碼,而是編碼之後未能正確解碼
為什麼未能正確解碼?
那是因為不支援 RFC2231 style encoded parameters
其實可能不只是 web 版不支援,可能還有其他的郵件客戶端不支援,只是樓主未去嘗試而已
總結
1、是要滿足三個條件才會對附件名進行多段拆分,忘記了的往上翻一翻
2、為什麼要進行附件名的多段拆分? 呃呃呃...,由你們來回答