Java 002:发邮件,及NoSuchAlgorithmException报错解决办法

第1步:首先,项目要引入javax.mail库:

<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

1.1 或者,你也可以直接下载这2个jar引入到你的java项目中:下载地址当然你也可以Maven仓库下载(javax.mail-1.6.2.jar和activation-1.1.1.jar)。


第2步:写代码,以下是我Hyb测试过(2023/5/12测试可行)可正常发邮件的代码:

import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public final class EmailTest {
	public static void main(String[] args) throws Exception {
		final String subject = "邮件标题";
		final String content = "邮件内容";

		final Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.126.com");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable", "true");
		props.put("mail.smtp.ssl.trust", "*");

		final String to = "收件人@126.com";
		final String from = "发件人@126.com";
		final String fromPwd = "发件邮箱的授权密码";

		final MimeMessage mm = new MimeMessage(Session.getInstance(props, new Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(from, fromPwd);
			}
		})); // 创建MimeMessage
		mm.setFrom(new InternetAddress(from)); // 设置发件人、收件人、主题和消息内容
		mm.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
		mm.setSubject(subject);
		mm.setText(content);
		Transport.send(mm); // 发送消息
	}
}

2.1 以上代码,你只需要将收件人发件人发件邮箱的授权密码 改成你的就可以了。


第3步:以上授权密码从哪来?这就需要你登录你的发件邮箱去设置、开启SMTP服务


第4:以上发邮件的代码,发出的邮件内容是纯文本。如果要求邮件内容是html,下面代码可以做到:

import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public final class EmailTest {
	public static void main(String[] args) throws Exception {
		final String subject = "邮件标题";
		final String content = "<font color=red>邮件内容</font>";

		final Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.126.com");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable", "true");
		props.put("mail.smtp.ssl.trust", "*");

		final String to = "收件人@126.com";
		final String from = "发件人@126.com";
		final String fromPwd = "发件邮箱的授权密码";

		final MimeMultipart 正文和附件 = new MimeMultipart();

		final MimeBodyPart html = new MimeBodyPart();
		html.setContent(content, "text/html;charset=utf-8");
		正文和附件.addBodyPart(html);

		final MimeMessage mm = new MimeMessage(Session.getInstance(props, new Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(from, fromPwd);
			}
		})); // 创建MimeMessage
		mm.setFrom(new InternetAddress(from)); // 设置发件人、收件人、主题和消息内容
		mm.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
		mm.setSubject(subject);
		mm.setContent(正文和附件); // 设置发件内容
		Transport.send(mm); // 发送消息
	}

}

第5:如果要求邮件内容是html,且带图片,下面代码可以做到:

import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public final class EmailTest {
	public static void main(String[] args) throws Exception {
		final String subject = "邮件标题";
		final String content = "<font color=red>邮件内容</font>";

		final Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.126.com");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable", "true");
		props.put("mail.smtp.ssl.trust", "*");

		final String to = "收件人@126.com";
		final String from = "发件人@126.com";
		final String fromPwd = "发件邮箱的授权密码";

		final MimeMultipart 正文和附件 = new MimeMultipart();
		正文和附件.setSubType("related"); //文本和图片内嵌成功

		final MimeBodyPart image = new MimeBodyPart();
		image.setDataHandler(new DataHandler(new FileDataSource("D:/aaa.png")));
		image.setContentID("a.png"); //设置图片id,这个非常重要。如果这个a.png跟下面的不一样,那这个图片就成邮件附件了
		正文和附件.addBodyPart(image);

		final MimeBodyPart html = new MimeBodyPart();
		html.setContent(content + "<br/><img src='cid:a.png'>", "text/html;charset=utf-8");
		正文和附件.addBodyPart(html);

		final MimeMessage mm = new MimeMessage(Session.getInstance(props, new Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(from, fromPwd);
			}
		})); // 创建MimeMessage
		mm.setFrom(new InternetAddress(from)); // 设置发件人、收件人、主题和消息内容
		mm.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
		mm.setSubject(subject);
		mm.setContent(正文和附件); // 设置发件内容
		Transport.send(mm); // 发送消息
	}

}

第6:如果要求邮件带附件,只要让上面代码setContentID("a.png")中,a.png不要被引用就可以了,当然网上还有其它办法,具体自己查查。反正以上3份代码,你copy后,改下收件人、发件人、发件邮箱授权密码,代码就可以成功运行的,本人Hyb测试多次没有问题。


第7:以上代码在eclipse中运行,没有一点问题。但如果脱离IDE环境,改成命令行部署的方式,就会报错。

7.1 命令行执行为:java -Djava.ext.dirs=D:/K/lib/ KxSnapshot 3600 1600 Z:/K/

      关于这条命令, 参数-Djava.ext.dirs指定了KxSnapshot.class依赖jar的存放目录。

7.2 但该命令在执行时会报错:NoSuchAlgorithmException: SunTls12RsaPremasterSecret KeyGenerator not available

javax.mail.MessagingException: Could not convert socket to TLS
	at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2155)
	at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:752)
	at javax.mail.Service.connect(Service.java:388)
	at javax.mail.Service.connect(Service.java:246)
	at javax.mail.Service.connect(Service.java:195)
	at javax.mail.Transport.send0(Transport.java:254)
	at javax.mail.Transport.send(Transport.java:124)
	at KxSnapshot.emailSend(KxSnapshot.java:897)
	at KxSnapshot.emailFindKDJ紫色连续2点升降(KxSnapshot.java:859)
	at KxSnapshot.main(KxSnapshot.java:105)
Caused by: javax.net.ssl.SSLKeyException: RSA premaster secret error
	at sun.security.ssl.RSAClientKeyExchange.<init>(Unknown Source)
	at sun.security.ssl.ClientHandshaker.serverHelloDone(Unknown Source)
	at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
	at sun.security.ssl.Handshaker.processLoop(Unknown Source)
	at sun.security.ssl.Handshaker.process_record(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:626)
	at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:553)
	at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2150)
	... 9 more
Caused by: java.security.NoSuchAlgorithmException: SunTls12RsaPremasterSecret KeyGenerator not available
	at javax.crypto.KeyGenerator.<init>(KeyGenerator.java:169)
	at javax.crypto.KeyGenerator.getInstance(KeyGenerator.java:223)
	at sun.security.ssl.JsseJce.getKeyGenerator(Unknown Source)
	... 21 more

7.3 对于发邮件时报出NoSuchAlgorithmException,我Hyb实际的解决办法也简单:

      将jdk1.8.0_112/jre/lib/ext目录下的5个jar,copy到上面命令中的D:/K/lib/下。这5个jar是:

      ​​​​​​​localedata.jar , sunpkcs11.jar , sunmscapi.jar , sunjce_provider.jar , dnsns.jar  

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值