org.springframework.mail.MailSendException: Failed messages: javax.mail.SendFailedException: Invalid Addresses

一、问题分析

  • org.springframework.mail.MailSendException: Failed messages: javax.mail.SendFailedException: Invalid Addresses

  • 分析:可能是收件人或抄送人列表存在无效的地址

坑:不能直接catch到SendFailedException

二、解决方案

遍历异常,提取无效地址后过滤原地址列表再次发送

具体代码如下:

1.发邮件方法代码

    /**
     * 发送html邮件
     *
     * @param to
     * @param cc
     * @param subject
     * @param content
     */
    public void sendHtmlMail(String[] to, String[] cc, String subject, String content) {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = null;
        try {
            //true表示需要创建一个multipart message
            helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setCc(cc);
            helper.setSubject(subject);
            helper.setText(content, true);

            mailSender.send(message);
            logger.info("sendHtmlMail success.from:" + from);
        } catch (Throwable e) {
            logger.error("sendHtmlMail fail.", e);
            String[] invalid = getInvalidAddresses(e);
            if (invalid != null) {
                sendHtmlMail(filterByArray(to, invalid), filterByArray(cc, invalid), subject, content);
            }
        }
    }

2.从异常获取无效地址的方法代码

    /**
     * 从异常获取无效地址
     * @param e
     * @return
     */
    private static String[] getInvalidAddresses(Throwable e) {
        if (e == null) {
            return null;
        }
        if (e instanceof MailSendException) {
            System.out.println("e instanceof SendFailedException");
            Exception[] exceptions = ((MailSendException) e).getMessageExceptions();
            for (Exception exception : exceptions) {
                if (exception instanceof SendFailedException) {
                    return getStringAddress(((SendFailedException) exception).getInvalidAddresses());
                }
            }
        }
        if (e instanceof SendFailedException) {
            return getStringAddress(((SendFailedException) e).getInvalidAddresses());
        }
        return null;
    }

    /**
     * 将Address[]转成String[]
     * @param address
     * @return
     */
    private static String[] getStringAddress(Address[] address) {
        List<String> invalid = new ArrayList<>();
        for (Address a : address) {
            String aa = ((InternetAddress) a).getAddress();
            if (!StringUtils.isEmpty(aa)) {
                invalid.add(aa);
            }
        }
        return invalid.stream().distinct().toArray(String[]::new);
    }

3.过滤发件人中无效地址的方法代码

    /**
     * 过滤数组source,规则为数组元素包含了数组filter中的元素则去除
     *
     * @param source
     * @param filter
     * @return
     */
    private static String[] filterByArray(String[] source, String[] filter) {
        List<String> result = new ArrayList<>();
        for (String s : source) {
            boolean contains = false;
            for (String f : filter) {
                if (s.contains(f)) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                result.add(s);
            }
        }
        return result.stream().toArray(String[]::new);
    }
原文地址:https://www.cnblogs.com/diffx/p/9876414.html