基于SpringBoot发送邮件
java发送邮件
以QQ邮箱为例
首先需要获取到授权码
eynrcqbilfuzbifd
1.邮件组成及授权码获取
在发送邮件之前我们需要获取发送邮件的授权码
登录QQ邮箱->账户->设置->开启IMAP/SMTP服务获取授权码哦
我这里已经开启了,在第一次开启或者关闭之后再次开启时,需要按照提示发送一个短信到指定的端口号上进行验证,验证通过才行获取授权码,获取到授权码之后保存好就可以了。
2.搭建一个SpringBoot工程
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
邮件配置
# 配置 smtp 服务器地址
spring.mail.host=smtp.qq.com
# smtp 服务器的端口
spring.mail.port=587
# 设置传输协议smtp
spring.mail.protocol=smtp
# 配置邮箱用户名
spring.mail.username=252539670@qq.com
# 配置申请到的授权码
spring.mail.password=eynrcqbilfuzbifd
# 配置邮件编码
spring.mail.default-encoding=UTF-8
# 配饰 SSL 加密工厂
spring.mail.properties.mail.smtp.socketFactoryClass=javax.net.ssl.SSLSocketFactory
# 表示开启 DEBUG 模式
spring.mail.properties.mail.debug=true
编写测试类
@SpringBootTest
class LlpJavamailApplicationTests {
@Autowired
JavaMailSender javaMailSender;
/**
* 发送简单邮件
*/
@Test
public void sendSimpleMail() {
SimpleMailMessage msg = new SimpleMailMessage(); //构建一个邮件对象
msg.setSubject("这是一封测试邮件"); // 设置邮件主题
msg.setFrom("发件人邮箱"); // 设置邮箱发送者
msg.setTo("收件人邮箱"); // 设置邮件接收者,可以有多个接收者,多个接收邮箱用逗号隔开
msg.setSentDate(new Date()); // 设置邮件发送日期
msg.setText("这是测试邮件的正文"); // 设置邮件的正文
javaMailSender.send(msg);
}
/**
* 发送带附件的邮件
* @throws MessagingException
*/
@Test
public void sendAttachFileMail() throws Exception {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject("hello msj 这是一封测试邮件");
helper.setFrom("发件人邮箱");
helper.setTo("收件人邮箱");
helper.setSentDate(new Date());
helper.setText("测试邮件");
String fileUrl = "https://cdn.jsdelivr.net/gh/RayLin24/imgs/imgsimage-20220103201648553.png";
File file = FileUtil.getNetUrl(fileUrl);
helper.addAttachment(UUID.randomUUID().toString()+fileUrl.substring(fileUrl.lastIndexOf(".")),file);
javaMailSender.send(mimeMessage);
}
}
根据文件地址获取file对象
package com.llp.llpjavamail.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
@Slf4j
@Component
public class FileUtil {
/**
* 远程读取文件
*
* @param netUrl
* @return
*/
public static File getNetUrl(String netUrl) {
//判断http和https
File file = null;
if (netUrl.startsWith("https://")) {
file = getNetUrlHttps(netUrl);
} else {
file = getNetUrlHttp(netUrl);
}
return file;
}
public static File getNetUrlHttp(String fileUrl) {
//对本地文件命名
String fileName = UUID.randomUUID().toString()+fileUrl.substring(fileUrl.lastIndexOf("."));
log.info("filename: =======================>"+fileName);
File file = null;
URL urlfile;
InputStream inStream = null;
OutputStream os = null;
try {
file = File.createTempFile("net_url", fileName);
//下载
urlfile = new URL(fileUrl);
inStream = urlfile.openStream();
os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
log.error("远程图片获取错误:"+fileUrl);
e.printStackTrace();
} finally {
try {
if (null != os) {
os.close();
}
if (null != inStream) {
inStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
/**
* 下载文件到本地(支持https)
*
* @param fileUrl 远程地址
* @throws Exception
*/
public static File getNetUrlHttps(String fileUrl) {
//对本地文件命名
String fileName = UUID.randomUUID().toString()+fileUrl.substring(fileUrl.lastIndexOf("."));
log.info("filename: =======================>"+fileName);
File file = null;
DataInputStream in = null;
DataOutputStream out = null;
try {
file = File.createTempFile("net_url", fileName);
SSLContext sslcontext = SSLContext.getInstance("SSL", "SunJSSE");
sslcontext.init(null, new TrustManager[]{new X509TrustUtiil()}, new java.security.SecureRandom());
URL url = new URL(fileUrl);
HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslsession) {
log.warn("WARNING: Hostname is not matched for cert.");
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
HttpsURLConnection urlCon = (HttpsURLConnection) url.openConnection();
urlCon.setConnectTimeout(6000);
urlCon.setReadTimeout(6000);
int code = urlCon.getResponseCode();
if (code != HttpURLConnection.HTTP_OK) {
throw new Exception("文件读取失败");
}
// 读文件流
in = new DataInputStream(urlCon.getInputStream());
out = new DataOutputStream(new FileOutputStream(file));
byte[] buffer = new byte[2048];
int count = 0;
while ((count = in.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
out.close();
in.close();
} catch (Exception e) {
log.error("远程图片获取错误:"+fileUrl);
e.printStackTrace();
} finally {
try {
if (null != out) {
out.close();
}
if (null != in) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return file;
}
}
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class X509TrustUtiil implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
}