JAVA使用465端口与25端口实现发送邮件的业务

SMTP服务以及SMTPS服务

1、场景介绍(为什么要使用SMTPS)

1、SMTP 服务使用明文通信,邮箱账号、密码极易被监听,导致邮箱被盗事件频繁发生、甚至发生泄密事件。
2、SMTPS是SSL/TLS通讯协议的 内容一开始就被保护起来了 是看不到原文的
它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。
为了加强网络安全管理,所以要使用SMTPS服务进行邮箱业务的完善
3、若只是简单的实现邮箱功能可以使用SMTP服务,若是追求安全性的邮箱业务必须要使用SMTPS服务

2、准备工作(业务实现的jar包等)

1、使用JAVA发送邮件前需要准备两个JAR包,分别为activation.jar与mail-1.4.7.jar
2、由于是使用SPring的JavaMailSenderImp实现的,所以JDK与Spring这些基础的也要准备好环境

在这里插入图片描述
jar包下载地址

链接:https://pan.baidu.com/s/1DiQDFjCPzc6y85JeZuGf-Q 
提取码:rodb
  • 1
  • 2

3、使用 25 端口简单的实现SMTP服务(代码演示)

本次使用163邮箱为实例进行展示

3.1、首先创建一个公共方法类

package com.yadong.mailUtil;
import javax.mail.PasswordAuthentication;

class MailAuthenticator extends javax.mail.Authenticator {
    private String strUser;

    private String strPwd;

    public MailAuthenticator(String user, String password) {
        this.strUser = user;
        this.strPwd = password;
    }
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(strUser, strPwd);
    }
}

3.2、代码的实现内容

package com.yadong.mailUtil;
import java.io.UnsupportedEncodingException;

import java.util.Date;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;


import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessagePreparator;


public class MailUtil {
    // 邮件分发器
    public static JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    //这是发送邮件的标题
    public static String subject = "这是发送邮件的标题";
    //这是发送邮件的内容
    public static String content = "这是发送邮件的内容";
    //这是发送者Email
    public static String fromAddress = "******@163.com";
    //这是发送者的用户名
    public static String smtpUserName = "*********@163.com";
    //163邮箱的授权码,并不是163邮箱的密码,而是开启SMTP服务时给予的授权码
    public static String smtpPassword = "******";
    //接收者Email
    public static String toAddress = "*******@qq.com";
    //SMTP服务器
    public static String ServerFromDB = "smtp.163.com";
    //服务器的端口
    private static String port = "25";

    /**
     * 发送邮件
     *
     * @param subject     标题
     * @param content     内容
     * @param fromAddress 发送者Email
     * @param toAddress   接收者Email
     * @throws Exception
     */
    public static void sendEmail(final String subject, final String content,
                                 final String fromAddress, final String toAddress) throws Exception {

        mailSender.setHost(ServerFromDB);//SMTP服务器
        mailSender.setPort(Integer.parseInt(port));//端口
        Properties props = System.getProperties();
        props.put("mail.smtp.auth", "true");
        MailAuthenticator mailAuth = new MailAuthenticator(smtpUserName, smtpPassword);
        Session session = Session.getInstance(props, mailAuth);
        mailSender.setSession(session);

            final InternetAddress[] mailToAddresses = new InternetAddress[1];
            mailToAddresses[0] = new InternetAddress(toAddress);
            MimeMessagePreparator preparator = new MimeMessagePreparator() {
                public void prepare(MimeMessage mimeMessage)
                        throws MessagingException, UnsupportedEncodingException {
                    mimeMessage
                            .setRecipients(RecipientType.TO, mailToAddresses);
                    InternetAddress ia = new InternetAddress(fromAddress);
                    ia.setPersonal(fromAddress);
                    mimeMessage.setFrom(ia);
                    mimeMessage.setSentDate(new Date());
                    mimeMessage.setSubject(subject);
                    mimeMessage.setText(content);
                }
            };
            mailSender.send(preparator);
        }

    public static void main(String[] args) throws Exception {
        sendEmail(subject,content,fromAddress,toAddress);
        }
    }

4、使用 465 端口实现SMTPS服务(代码演示)

本次使用163邮箱服务器的465端口为实例进行展示

4.1、首先创建一个公共方法类

package com.yadong.mailUtil;
import javax.mail.PasswordAuthentication;

class MailAuthenticator extends javax.mail.Authenticator {
    private String strUser;

    private String strPwd;

    public MailAuthenticator(String user, String password) {
        this.strUser = user;
        this.strPwd = password;
    }
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(strUser, strPwd);
    }
}

4.2、代码实现的内容

package com.yadong.mailUtil;

import java.io.UnsupportedEncodingException;

import java.util.Date;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;


import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessagePreparator;


public class MailUtil {
    // 邮件分发器
    public static JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    //这是发送邮件的标题
    public static String subject = "这是发送邮件的标题";
    //这是发送邮件的内容
    public static String content = "这是发送邮件的内容";
    //这是发送者Email
    public static String fromAddress = "******@163.com";
    //这是发送者的用户名
    public static String smtpUserName = "********@163.com";
    //163邮箱的授权码,并不是163邮箱的密码,而是开启SMTP服务时给予的授权码
    public static String smtpPassword = "******";
    //接收者Email
    public static String toAddress = "*******@qq.com";
    //SMTP服务器
    public static String ServerFromDB = "smtp.163.com";
    //服务器的端口
    private static String port = "465";

    /**
     * 发送邮件
     *
     * @param subject     标题
     * @param content     内容
     * @param fromAddress 发送者Email
     * @param toAddress   接收者Email
     * @throws Exception
     */
    public static void sendEmail(final String subject, final String content,
                                 final String fromAddress, final String toAddress) throws Exception {

        mailSender.setHost(ServerFromDB);//SMTP服务器
        mailSender.setPort(Integer.parseInt(port));//端口
        Properties props = System.getProperties();
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.port", port);
        props.setProperty("mail.smtp.socketFactory.port", port);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
        MailAuthenticator mailAuth = new MailAuthenticator(smtpUserName, smtpPassword);
        Session session = Session.getInstance(props, mailAuth);
        mailSender.setSession(session);

            final InternetAddress[] mailToAddresses = new InternetAddress[1];
            mailToAddresses[0] = new InternetAddress(toAddress);
            MimeMessagePreparator preparator = new MimeMessagePreparator() {
                public void prepare(MimeMessage mimeMessage)
                        throws MessagingException, UnsupportedEncodingException {
                    mimeMessage
                            .setRecipients(RecipientType.TO, mailToAddresses);
                    InternetAddress ia = new InternetAddress(fromAddress);
                    ia.setPersonal(fromAddress);
                    mimeMessage.setFrom(ia);
                    mimeMessage.setSentDate(new Date());
                    mimeMessage.setSubject(subject);
                    mimeMessage.setText(content);
                }
            };
            mailSender.send(preparator);
        }

    public static void main(String[] args) throws Exception {
        sendEmail(subject,content,fromAddress,toAddress);
        }
    }

4.3、SMTP与SMTPS代码实现的区别

//代码的主体并没有变化,而是在properties配置类中增加一些配置,分别为以下配置
        Properties props = System.getProperties();
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");

5、可能遇到的错误

5.1、Could not connect to SMTP host: smtp.163.com, port: 465;

5.1.1、解决方案一

查看自己设备是否可以PING通服务器
1、首先打开设备的telnet功能
控制面板(查看方式小图标) -》 程序与功能 -》启用或关闭window功能
在这里插入图片描述
打开CMD 输入 telnet smtp.163.com 465
在这里插入图片描述
显示黑窗口则表示可以PING通,如果PING不通则显示链接失败
在这里插入图片描述

5.1.2、解决方案二

添加配置

props.setProperty("mail.smtp.ssl.enable", true);
//将smtp.163.com修改为IP地址
props.setProperty("mail.smtp.host", "220.181.12.16"); //smtp.163.com

5.1.3、解决方案二

修改java.security:不要SSL3,TLSv1, TLSv1.1

# dk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
jdk.tls.disabledAlgorithms=RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

5.2、Unrecognized SSL message, plaintext connection?

5.2.1、解决方案一

检查端口是否正确
检查是否使用的25端口,却是465端口的配置?

5.3、unable to find valid certification path to requested target

5.2.1、解决方案一

一、导入证书
因为ssl 465端口是加密的https,所以需要将邮箱服务器的证书导入到java虚拟机环境。
更加详情的步骤可以查看 使用keytool将https证书导入JDK详情步骤
导入https证书具体路径如下:

1.	从邮箱服务器上下载证书,具体步骤可以参考网页:
https://jingyan.baidu.com/article/e75aca851e0b5f142edac632.html
2.	保存证书到服务器磁盘后,打开cmd命令行窗口,进入到项目使用的java环境的bin目录
3.	在cmd命令行窗口执行如下两条命令:
keytool.exe -importcert -file C:\Users\Administrator\Desktop\163.cer -keystore  F:\Java\jdk1.8.0_171\jre\lib\security\cacerts -storepass changeit -alias 163.cer

keytool.exe -importcert -file C:\Users\Administrator\Desktop\163.cer -keystore   F:\Java\jdk1.8.0_171\jre\lib\security\jssecacerts -storepass changeit -alias 163.cer

其中C:\Users\Administrator\Desktop\youjianbuding\163.cer为第一步导出的证书的磁盘路径;
	F:\Java\jdk1.8.0_171\jre\lib\security\cacerts为项目使用的jdk的证书环境。
	-alias 163.cer 为起别名
4.	执行命令后会出现如下提示:是否信任证书。输入Y即可。然后证书就导入java环境成功。

在这里插入图片描述

DNSName 中含有SMTP 服务器地址的证书才能成功发送邮件,若证书中不包含SMTP 服务器地址,则无法发送
关于导入证书,详情可以查看 https://blog.csdn.net/qq_45728838/article/details/128547568?spm=1001.2014.3001.5501

猜你喜欢

转载自blog.csdn.net/zhaofuqiangmycomm/article/details/132457663
今日推荐