网易邮箱退信 554 垃圾邮件 解决办法

Email JAVA

Posted by gomyck on January 23, 2021

系统报警, 选择发邮件的形式, 被网易退信的解决办法

原因

平台支付业务需要同步订单数据, 通过 RPC 调用, 在最终失败时需要发送邮件告知运维人员, 故做了个 JAVA 邮件发送工具类

但是在测试支付失败场景时, 经过几次的发件之后, 再次发送被网易退件, 使用的是 163 邮箱, 查看错误码, 为垃圾邮件退件

查找解决办法为: 把原邮件抄送给发件人一份, 即可解决该问题, 并不在复现

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
 * Copyright (c) 2019 gomyck
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.gomyck.util;

import com.sun.net.ssl.internal.ssl.Provider;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.Security;
import java.util.Properties;

/**
 * 发送邮件工具类
 *
 * @author gomyck
 */
public abstract class EMailUtil {

    private static Logger logger = LoggerFactory.getLogger(EMailUtil.class);

    public static Session initSession(final String userName, final String password, SmtpSetting smtpSetting) {
        Properties props = new Properties();
        props.setProperty("mail.smtp.host", smtpSetting.getHost());
        props.setProperty("mail.smtp.auth", smtpSetting.getAuth().toString());
        props.setProperty("mail.debug", smtpSetting.getDebug().toString());
        if (smtpSetting.getSsl()) {
            Security.addProvider(new Provider());
            props.setProperty("mail.smtp.ssl.enable", "true");
            props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.setProperty("mail.smtp.socketFactory.fallback", "false");
            props.setProperty("mail.smtp.port", smtpSetting.getSslPort().toString());
            props.setProperty("mail.smtp.socketFactory.port", smtpSetting.getSslPort().toString());
        }
        return Session.getDefaultInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, password);
            }
        });
    }

    public static void sendEmail(final Session session, final String sender, final String[] receivers, final String emailTitle, final String emailContent) throws MessagingException {
        sendMessage(session, sender, receivers, null, null, emailTitle, emailContent, "text/html; charset=utf-8");
    }

    public static void sendEmailWithCopyers(final Session session, final String sender, final String[] receivers, final String[] copyers, final String emailTitle, final String emailContent) throws MessagingException {
        sendMessage(session, sender, receivers, copyers, null, emailTitle, emailContent, "text/html; charset=utf-8");
    }

    public static void sendMessage(final Session session, final String sender, final String[] receivers, final String[] copyers, final String[] secretSenders, final String emailTitle, final String content, final String mimeType) throws MessagingException {
        final Message message = new MimeMessage(session);
        if (!StringJudge.isNull(sender)) {
            final InternetAddress sentFrom = new InternetAddress(sender);
            message.setFrom(sentFrom);
            if (logger.isDebugEnabled()) {
                logger.debug("e-mail sender: " + sentFrom);
            }
        }
        if (receivers != null) {
            final InternetAddress[] sendTo = new InternetAddress[receivers.length];
            for (int i = 0; i < receivers.length; i++) {
                sendTo[i] = new InternetAddress(receivers[i]);
                if (logger.isDebugEnabled()) {
                    logger.debug("sending e-mail receivers: " + receivers[i]);
                }
            }
            message.setRecipients(Message.RecipientType.TO, sendTo);
        }
        if (copyers != null) {
            final InternetAddress[] copyTo = new InternetAddress[copyers.length];
            for (int i = 0; i < copyers.length; i++) {
                copyTo[i] = new InternetAddress(copyers[i]);
                if (logger.isDebugEnabled()) {
                    logger.debug("copying e-mail receivers: " + copyers[i]);
                }
            }
            message.setRecipients(Message.RecipientType.CC, copyTo);
        }
        if (secretSenders != null) {
            final InternetAddress[] copyTo = new InternetAddress[secretSenders.length];
            for (int i = 0; i < secretSenders.length; i++) {
                copyTo[i] = new InternetAddress(secretSenders[i]);
                if (logger.isDebugEnabled()) {
                    logger.debug("blind copying e-mail receivers: " + secretSenders[i]);
                }
            }
            message.setRecipients(Message.RecipientType.BCC, copyTo);
        }
        message.setSubject((emailTitle == null) ? "(no emailTitle)" : emailTitle);
        message.setContent(content, mimeType);
        message.setSentDate(new java.util.Date());
        Address[] remainingAddresses = message.getAllRecipients();
        int nAddresses = remainingAddresses.length;
        boolean bFailedToSome = false;
        final SendFailedException sendex = new SendFailedException("Unable receivers send message receivers some recipients");
        do {
            nAddresses = remainingAddresses.length;
            try {
                Transport.send(message, remainingAddresses);
            } catch (final SendFailedException ex) {
                bFailedToSome = true;
                sendex.setNextException(ex);
                remainingAddresses = ex.getValidUnsentAddresses();
            }
        } while (remainingAddresses != null && remainingAddresses.length > 0 && remainingAddresses.length != nAddresses);
        if (bFailedToSome) {
            throw sendex;
        }
    }

    public static void sendTextMessageToManyReceivers(final Session session, final String sender, final String[] receivers, final String[] copyers, final String[] secretSenders, final String emailTitle, final String content) throws MessagingException {
        sendMessage(session, sender, receivers, copyers, secretSenders, emailTitle, content, "text/plain; charset=utf-8");
    }

    public static void sendTextMessageToOneReceiver(final Session session, final String sender, final String receivers, final String[] copyers, final String[] secretSenders, final String emailTitle, final String content) throws MessagingException {
        String[] recipient = null;
        if (receivers != null) {
            recipient = new String[]{receivers};
        }
        sendMessage(session, sender, recipient, copyers, secretSenders, emailTitle, content, "text/plain; charset=utf-8");
    }

    public static void sendTextMessageToOneReceiverAndOneCopyer(final Session session, final String sender, final String receivers, final String copyers, final String secretSenders, final String emailTitle, final String content) throws MessagingException {
        String[] recipient = null;
        String[] copy = null;
        String[] bcopy = null;
        if (receivers != null) {
            recipient = new String[]{receivers};
        }
        if (copyers != null) {
            copy = new String[]{copyers};
        }
        if (secretSenders != null) {
            bcopy = new String[]{secretSenders};
        }
        sendMessage(session, sender, recipient, copy, bcopy, emailTitle, content, "text/plain; charset=utf-8");
    }

    public static void sendHTMLMessageToManyReceivers(final Session session, final String sender, final String[] receivers, final String[] copyers, final String[] secretSenders, final String emailTitle, final String content) throws MessagingException {
        sendMessage(session, sender, receivers, copyers, secretSenders, emailTitle, content, "text/html; charset=utf-8");
    }

    public static void sendHTMLMessageToOneReceiver(final Session session, final String sender, final String receivers, final String[] copyers, final String[] secretSenders, final String emailTitle, final String content) throws MessagingException {
        String[] recipient = null;
        if (receivers != null) {
            recipient = new String[]{receivers};
        }
        sendMessage(session, sender, recipient, copyers, secretSenders, emailTitle, content, "text/html; charset=utf-8");
    }

    public static void sendHTMLMessageToOneReceiverAndOneCopyer(final Session session, final String sender, final String receivers, final String copyers, final String secretSenders, final String emailTitle, final String content) throws MessagingException {
        String[] recipient = null;
        String[] copy = null;
        String[] bcopy = null;
        if (receivers != null) {
            recipient = new String[]{receivers};
        }
        if (copyers != null) {
            copy = new String[]{copyers};
        }
        if (secretSenders != null) {
            bcopy = new String[]{secretSenders};
        }
        sendMessage(session, sender, recipient, copy, bcopy, emailTitle, content, "text/html; charset=utf-8");
    }

    @Data
    public static class SmtpSetting {
        private String host;
        private Boolean auth = true;
        private Boolean ssl = false;
        private Boolean debug = false;
        private Integer sslPort = 994;
    }

}