使用smtp.163.com发送邮件,参考:https://www.cnblogs.com/tohxyblog/p/6593654.html

登录邮箱做好设置之后,代码如下:

    @Test
    public void testSendEmail() throws Exception {

        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", "smtp"); //协议
        prop.setProperty("mail.smtp.host", "smtp.163.com"); //主机名smtp.163.com
        prop.setProperty("mail.smtp.auth", "true"); //是否开启权限控制
        prop.setProperty("mail.debug", "true"); //返回发送的cmd源码
        Session session = Session.getInstance(prop);

        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("zhustar520@163.com")); //自己的email
        msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("goethe007@163.com")); // 要发送的email,可以设置数组
        msg.setSubject("装修问题咨询");  //邮件标题
        msg.setText("请问你们装修一次多少钱");//邮件正文
        //不被当作垃圾邮件的关键代码--Begin ,如果不加这些代码,发送的邮件会自动进入对方的垃圾邮件列表
        msg.addHeader("X-Priority", "3");
        msg.addHeader("X-MSMail-Priority", "Normal");
        msg.addHeader("X-Mailer", "Microsoft Outlook Express 6.00.2900.2869"); //本文以outlook名义发送邮件,不会被当作垃圾邮件
        msg.addHeader("X-MimeOLE", "Produced By Microsoft MimeOLE V6.00.2900.2869");
        msg.addHeader("ReturnReceipt", "1");
        //不被当作垃圾邮件的关键代码--end
        Transport trans = session.getTransport();

        //密码不是邮箱登录密码,是客户端授权密码
        trans.connect("zhustar520@163.com", "******"); // 邮件的账号密码
        trans.sendMessage(msg, msg.getAllRecipients());

    }

这段逻辑在本地运行只要内容没有被163服务器退信,就没有问题。但在阿里云服务器上,不管是杭州的还是香港的,都会有连接超时的问题,由于在阿里云服务器上部署了nginx,前端会返回一个504错误。查看nginx的log(/usr/local/nginx/logs/error.log)发现有:

2019/05/14 16:06:46 [error] 16039#0: *137116 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 60.176.118.119, server: localhost, request: "POST /zk/alarmConfig/sendEmail?emial=undefined HTTP/1.1", upstream: "http://127.0.0.1:9999/alarmConfig/sendEmail?emial=undefined", host: "esl.zkong.com:8888", referrer: "http://esl.zkong.com:8888/"
 

归根到底还是由于方法本身的调用超时,排除nginx的问题。搜了一下“阿里云 smtp”发现阿里云的服务器将向外访问25的端口封了,需要使用465端口和ssl通信,参考:https://blog.csdn.net/liouxl0623/article/details/65446662

使用代码:

    @Test
    public void testSslSend() {
        try{
            AgencyAlarmConfig agencyAlarmConfig = new AgencyAlarmConfig();
            agencyAlarmConfig.setAccount("zhustar520@163.com");
            agencyAlarmConfig.setPassword("******");
            agencyAlarmConfig.setSendServer("smtp.163.com");
            agencyAlarmConfig.setTestMail("goethe007@163.com");
            agencyAlarmConfig.setMailTitle("真不巧");
            Assert.assertTrue(sslSend(agencyAlarmConfig, "嘿嘿"));
        } catch (Exception e) {
            Assert.fail();
        }
    }


    private boolean sslSend(AgencyAlarmConfig agencyAlarmConfig, String content)
            throws AddressException, MessagingException, IOException {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        // Get a Properties object
        Properties props = new Properties();
        props.setProperty("mail.smtp.host", agencyAlarmConfig.getSendServer());
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.auth", "true");

        final String username = agencyAlarmConfig.getAccount();
        final String password = agencyAlarmConfig.getPassword();
        Session session = Session.getDefaultInstance(props, new Authenticator(){
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }});
        Message msg = new MimeMessage(session);

        // 设置发件人和收件人
        msg.setFrom(new InternetAddress(agencyAlarmConfig.getAccount()));
        List<String> tos = new ArrayList<>();
        tos.add(agencyAlarmConfig.getTestMail());
        Address to[] = new InternetAddress[tos.size()];
        for(int i=0;i<tos.size();i++){
            to[i] = new InternetAddress(tos.get(i));
        }
        // 多个收件人地址
        msg.setRecipients(Message.RecipientType.TO, to);
        msg.setSubject(agencyAlarmConfig.getMailTitle()); // 标题
        msg.setText(content);// 内容
        msg.setSentDate(new Date());
        Transport.send(msg);
        System.out.println("EmailUtil ssl协议邮件发送打印" +msg.toString());
        return true;
    }

由此可在阿里云的香港,杭州服务器发送,对于封端口,阿里云的回应:

去年9月底开始,出于上级对垃圾邮件管控的要求,新购VPC服务器限制了25端口,我们建议您使用邮件服务商的加密465端口。 或者您查询下所希望访问的发信服务是否提供了像阿里云企业邮箱一样的重定向25端口,这样不用解封25端口也可以发信。阿里云企业邮箱将80端口重定向到了25端,与直接调用25端的发信方式没有区别。 如果您仅用于本地发信,可尝试使用阿里企邮 smtp 80 端口。smtp.mxhichina.com 80
05-15 02:17