java发送邮件操作(携带或不携带附件),发送失败异常情况分析

文章讨论了在使用Java发送邮件时,遇到SendFailedException异常并未按预期抛出的情况,作者通过测试发现该异常是否出现取决于邮件服务器,如QQ邮箱会抛出异常,而163邮箱则可能直接退回邮件,强调了服务器反馈在异常处理中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析新需求时,发现收件邮箱有问题导致发送邮件失败时并没有抛出预估的sendfailedexception异常,在网上找了许多博客也没有说清楚院校,在我进行一些测试后断定,这个和发邮件的服务器有关

导入依赖

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

代码示例

需要邮件发送服务器的邮箱和密钥,一般来说密钥不等于密码;以QQ邮箱和163邮箱为例,在 安全设置账号与安全中可找到开启 SMTP服务,然后生成授权码,这个授权码就是我们用到的密钥;可在其帮助或者说明文档中找到对应的服务器地址和端口。smtp为发送邮件服务,imap为接收邮件服务。

一些参数并不一定是非得设置,视情况而定,下面是测试代码。

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

/**
 * @Description
 * @Author 
 */
public class MailTest {
    public static void main(String[] args) {
   
        String username1 = ""; // 邮箱
        String password1 = ""; // 密钥
        String host1 = "smtp.163.com";
        String username2 = "";
        String password2 = "";
        String host2 = "smtp.qq.com";
        sendingEmails(username2, password2, host2);
    }


    private static void sendingEmails(String username, String password, String host) {
        try {
            // 创建连接对象,用来连接邮箱地址
            Properties props = new Properties();
            // 设置发送邮箱的服务器协议
            props.setProperty("mail.transport.protocol", "SMTP");
            // 设置服务器地址
            props.setProperty("mail.smtp.host", host);
            // 设置服务器端口
            props.setProperty("mail.smtp.port", "465"); // qq为 465或587
            // 发件人是否合法,需为true
            props.setProperty("mail.smtp.auth", "true");
            // 若为ssl连接则需要设置
            props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.setProperty("mail.smtp.socketFactory.port", "465");
            // 设计发送邮件的账号和密码,此处的密码大都为密钥,要看服务器决定
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
            Message msg = new MimeMessage(session);
            // 创建收件人 可以用数组存多个收件人
//            Address[] address = new InternetAddress[2];
//            address[0]=new InternetAddress("");
//            address[1]=new InternetAddress("");
            Address address = new InternetAddress("email@qq.com");
            // 设置发件人属性,需和登录邮箱一致
            msg.setFrom(new InternetAddress(username));
            // 设置收件人或者抄送人等,收件人地址(可用数组存放多个收件人)
            msg.setRecipient(Message.RecipientType.TO, address);
//            msg.setRecipients(Message.RecipientType.TO, address); // 多个收件人
            msg.setText("test"); // 设置邮件内容(不携带附件有效)

            // ------------携带附件,若没有附件可不配置------------
            // 设置邮件正文,msg.setText()设置的内容会失效
            Multipart multipart = new MimeMultipart();
            MimeBodyPart messageBody = new MimeBodyPart();
            // 第一个参数为邮件正文,第二个参数未解析类型
            messageBody.setContent("test","text/html");
            multipart.addBodyPart(messageBody);

            // 添加附件,可添加多个附件,要注意文件名
            MimeBodyPart mimeBodyPart = new MimeBodyPart();
            // 需上传的附件的Inputstream
            InputStream inputStream = new FileInputStream("E:\\information\\新建文本文档.txt");
            DataSource source = new ByteArrayDataSource(inputStream, "application/octet-stream");
            mimeBodyPart.setDataHandler(new DataHandler(source));
            mimeBodyPart.setFileName("test.txt"); // 附件文件名字
            multipart.addBodyPart(mimeBodyPart);
            msg.setContent(multipart);
            // ------------------------------------------

            // 发送邮件
            Transport.send(msg);
        } catch (Exception e) {
        	// 捕获抛出的异常,打印在控制台
            System.err.println("" + e);
        }
    }
}

抛出异常分析

源码的注释说明了,Transport.send()这个方法会抛出MessagingException和SendFailedException这两个异常;
抛出MessagingException一般是除发送外的其他异常情况;抛出SendFailedException则是邮件发送的问题,但经过测试发现这个异常是否抛出还和邮件服务器有关。
在这里插入图片描述
以QQ邮箱和163邮箱为例
我用这两个服务器向同一个不存在的邮箱(email@qq.com)发送邮件,QQ是程序抛出异常,163是退回邮件(没有异常被捕获)
QQ
在这里插入图片描述163
在这里插入图片描述如果是@后面的域名问题都会退回邮件
QQ
在这里插入图片描述
163
在这里插入图片描述
像收件邮箱满了之类的也是退回邮件,sendFailedException这个异常和服务器的反馈有关。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值