Java Email邮件阿里云发不了怎么处理?

2,796 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

最近升级了一下SpringBoot的版本,结果发现之前工作的好好的邮件突然罢工了,罢工的原因还不止一个,接下来记录一下解决方案

1. Couldn't connect to host, port: smtp.163.com, 25; timeout -1

这个异常提示就有点搞人了,连接超时,之前可以现在居然不行,感觉是被针对了啊

上面这个问题,主要原因在于端口号的限制,如果项目中是使用SpringBoot封装的email客户端,可以调整一下配置参数

spring:
  #邮箱配置
  mail:
    host: smtp.163.com
    from: xhhuiblog@163.com
    # 使用自己的发送方用户名 + 授权码填充
    username: 
    password: 
    default-encoding: UTF-8
    port: 465
    properties:
      mail:
        smtp:
          socketFactory:
            port: 465
            class: javax.net.ssl.SSLSocketFactory
            fallback: false
          auth: true
          starttls:
            enable: true
            required: true

重点注意几个新增的配置

spring:
	mail:
		port: 465
		properties:
			mail:
				smtp:
					socketFactory:
                        port: 465
                        class: javax.net.ssl.SSLSocketFactory
                        fallback: false

2. JavaMailSender no object DCH for MIME type multipart/mixed

从堆栈信息上来看,主要问题貌似是MIME不合法,从网上检索来的结果来看,大概是因为版本的问题,导致META-INF下的数据加载异常

参考 stackoverflow.com/questions/2… 这个问答里的解决方案

方案一:设置MailcapCommandMap

在具体的发送之前,添加下面这段代码

// Original answer from Som:
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");

// Additional elements to make DSN work 
mc.addMailcap("multipart/report;;  x-java-content-handler=com.sun.mail.dsn.multipart_report");
mc.addMailcap("message/delivery-status;; x-java-content-handler=com.sun.mail.dsn.message_deliverystatus");
mc.addMailcap("message/disposition-notification;; x-java-content-handler=com.sun.mail.dsn.message_dispositionnotification");
mc.addMailcap("text/rfc822-headers;;   x-java-content-handler=com.sun.mail.dsn.text_rfc822headers");

实测结果:依然没有解决问题

方案二: 指定activation版本

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.1</version>
</dependency>

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
 </dependency>

基于上面这种方案,要求我们使用的客户端是javax.mail,然而SpringBoot-Email封装是jakarta,.mail它做的

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

放弃了使用这种姿势进行尝试

方案三:setContextClassLoader

这种方式比较简单,在执行邮件发送前,添加下面这一行代码

Thread.currentThread().setContextClassLoader(javax.mail.Message.class.getClassLoader());

实测结果:可行

根据描述结果来看,主要是通过这一个声明来允许加载META-INF/mailcap

allow javax.activation bundle to load the "META-INF/mailcap" resource from the javax.mail bundle

一灰灰的联系方式

尽信书则不如无书,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激