首页 > 编程语言 >JavaMail 邮件发送,有意思的附件名乱码 → 客户端正常,web端乱码

JavaMail 邮件发送,有意思的附件名乱码 → 客户端正常,web端乱码

时间:2023-03-08 09:13:17浏览次数:47  
标签:web mail 乱码 JavaMail props msg new

开心一刻

  昨晚,媳妇很感伤的看着我

  媳妇:以后岁数大了,我要走你前面去了,你再找个老伴

  我:我不想找

  媳妇:你找一个,不用替我守着,以后你说你头疼发烧,也得有个给你端水递药的呀

  媳妇抹着眼泪:到老是个伴

  我:我想找个年轻的

  现在我左脸还有一个掌印,火辣辣的

问题背景

  基于 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);
}
View Code

  附件名是做了编码处理的

  我们来看下接收情况

  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、为什么要进行附件名的多段拆分? 呃呃呃...,由你们来回答

标签:web,mail,乱码,JavaMail,props,msg,new
From: https://www.cnblogs.com/youzhibing/p/17084304.html

相关文章

  • web.xml 配置
    <!DOCTYPEweb-appPUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><display-name>Archetype......
  • webservce附件下载
    usingSystem;usingSystem.IO;usingSystem.Text;usingSystem.Web;usingSystem.Data;usingRegister.DataAccess;usingSystem.Configuration;usingHrisInterFaceProje......
  • 接受参数和数据回传及JavaWeb可能遇到的乱码问题
    一.处理提交的数据我们通过编写一个控制类来测试:@Controller@RequestMapping("/user")publicclasscontrollerTest5{@GetMapping("/t1")publicStringte......
  • web界面的HMI/SCADA组态
    web界面的HMI/SCADA组态2022-12-0207:39·程序员修仙之路一、项目简介今天要说的是一个web界面的HMI/SCADA组态,支持各种图形,支持拖拽,支持放缩。大致流程是,通过拖拽控件......
  • 让 KEPServer 变成一款 Web 组态软件
    让KEPServer变成一款Web组态软件原创2023-03-0215:32·炸克婶小姐姐KEPServerEX是行业领先的连接平台,用于向您的所有应用程序提供单一来源的工业自动化数据。......
  • 如何解决MySQL字符集乱码问题
    MySQL自4.1版本推出之后由于中文的特殊性带来的乱码问题也随在互联网行业出现。主要原因就是不同字符集编码不同而产生的。本文简要介绍字符集相关知识及部分乱码情况的解决......
  • 浅谈基于Web的跨平台桌面应用开发
    作者:京东物流王泽知近些年来,跨平台跨端一直是比较热门的话题,Writeonce,runanywhere,一直是我们开发者所期望的,跨平台方案的优势十分明显,对于开发者而言,可以做到一次开发,......
  • 数字孪生智慧渔业Web3D可视化养殖系统
    中国作为全球第一大水产养殖大国,未来中国水产养殖的出路在哪里?智慧渔业到底能起到多大的作用?在未来它能为我国水产养殖做出什么深刻的变化吗?  今天给大家分享一个......
  • 财务软件打开乱码问题处理方法(自然人报税扣缴、etax3.0、鼎信诺等)
    1、首先保证电脑的系统区域、输入法区域、时区都处于中国,日期格式为yyy/MM/dd格式,设置完成后重启计算机。系统区域、输入法区域和时区可以根据这篇文章的方法查询:命令查看......
  • 07、clion中文乱码
    1、将全局编码和项目编码一级文件编码改为【UTF-8】2、按住快捷键:【Ctrl+Alt+Shift+/】,显示一下对话框3、取消勾选:【run.processes.with.pty】......