虽然这些天很忙,但是有一些额外的与这些必要的事情无关的、但是我很感兴趣的事情还是没有放下。
今天要说的java发送邮件就是其中一个,另外一个令我感到欣喜的是发送短信验证码,都是利用SDK实现的(虽然我还不知道SDK的定义是什么,但是起码还是知道这是个什么东西)。
▍实验环境
我的实验环境:
1、Maven、SpringBoot
2、开发工具:IntelliJ IDEA
3、邮箱服务:QQ邮箱
某些环境不一致,可能导致效果实现不成功。
▍操作步骤及代码
1、开通SMTP服务:
1.1、进入设置:
1.2、选择账户:
1.3、开启SMTP服务:
1.4、获取到授权码,记住这个授权码:
注意:以下代码中带橙色标记的,需按实际情况进行相应的调整;带灰色标记的可删去。
2、引入jar包:
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<!--发送邮件-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.5</version>
</dependency>
3、创建工具类:
package com.coder.calculator.Util;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import com.sun.mail.util.MailSSLSocketFactory;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
public class SendmailUtil {
//邮件服务器主机名
// QQ邮箱的 SMTP 服务器地址为: smtp.qq.com
private static String myEmailSMTPHost = "smtp.qq.com";
//发件人邮箱
private static String myEmailAccount = "[email protected]";
//发件人邮箱密码(授权码)
//在开启SMTP服务时会获取到一个授权码,把授权码填在这里
private static String myEmailPassword = "xxxxxxxxxxxx";
/**
* 邮件单发(自由编辑短信,并发送,适用于私信)
*
* @param toEmailAddress 收件箱地址
* @param emailTitle 邮件主题
* @param emailContent 邮件内容
* @throws Exception
*/
public static void sendEmail(String toEmailAddress, String emailTitle, String emailContent) throws Exception{
Properties props = new Properties();
// 开启debug调试
props.setProperty("mail.debug", "true");
// 发送服务器需要身份验证
props.setProperty("mail.smtp.auth", "true");
// 端口号
props.put("mail.smtp.port", 465);
// 设置邮件服务器主机名
props.setProperty("mail.smtp.host", myEmailSMTPHost);
// 发送邮件协议名称
props.setProperty("mail.transport.protocol", "smtp");
/**SSL认证,注意腾讯邮箱是基于SSL加密的,所以需要开启才可以使用**/
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
//设置是否使用ssl安全连接(一般都使用)
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);
//创建会话
Session session = Session.getInstance(props);
//获取邮件对象
//发送的消息,基于观察者模式进行设计的
Message msg = new MimeMessage(session);
//设置邮件标题
msg.setSubject(emailTitle);
//设置邮件内容
//使用StringBuilder,因为StringBuilder加载速度会比String快,而且线程安全性也不错
StringBuilder builder = new StringBuilder();
//写入内容
builder.append("\n" + emailContent);
//写入我的官网
builder.append("\n官网:" + "https://www.hbuecx.club");
//定义要输出日期字符串的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//在内容后加入邮件发送的时间
builder.append("\n时间:" + sdf.format(new Date()));
//设置显示的发件时间
msg.setSentDate(new Date());
//设置邮件内容
msg.setText(builder.toString());
//设置发件人邮箱
// InternetAddress 的三个参数分别为: 发件人邮箱, 显示的昵称(只用于显示, 没有特别的要求), 昵称的字符集编码
msg.setFrom(new InternetAddress(myEmailAccount,"好学堂", "UTF-8"));
//得到邮差对象
Transport transport = session.getTransport();
//连接自己的邮箱账户
//密码不是自己QQ邮箱的密码,而是在开启SMTP服务时所获取到的授权码
//connect(host, user, password)
transport.connect( myEmailSMTPHost, myEmailAccount, myEmailPassword);
//发送邮件
transport.sendMessage(msg, new Address[] { new InternetAddress(toEmailAddress) });
//将该邮件保存到本地
OutputStream out = new FileOutputStream("MyEmail.eml");
msg.writeTo(out);
out.flush();
out.close();
transport.close();
}
}
4、Controller调用Util:
package com.coder.calculator.controller;
import com.coder.calculator.Util.CalculatorUtil;
import com.coder.calculator.Util.SendmailUtil;
import com.coder.calculator.Util.VerifyCodeUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
@Controller
public class UserController{
/**
* 发送自由编辑的邮件
*
* @param toEmailAddress 收件人邮箱
* @param emailTitle 邮件主题
* @param emailContent 邮件内容
* @return
*/
@RequestMapping(value={"/sendEmailOwn/"},method={RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public String sendEmailOwn(@RequestParam("toEmailAddress") String toEmailAddress,
@RequestParam("emailTitle") String emailTitle,
@RequestParam("emailContent") String emailContent){
try{
//发送邮件
SendmailUtil.sendEmail(toEmailAddress, emailTitle, emailContent);
return CalculatorUtil.getJSONString(0);
}catch(Exceptione){
return CalculatorUtil.getJSONString(1,"邮件发送失败!");
}
}
/**
* 发送系统验证
*
* @param toEmailAddress 收件人邮箱
* @return
*/
@RequestMapping(value={"/sendEmailSystem/"},method={RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public String sendEmailSystem(@RequestParam("toEmailAddress") String toEmailAddress){
try{
//生成验证码
String verifyCode = VerifyCodeUtil.generateVerifyCode(6);
//邮件主题
String emailTitle = "【好学堂】邮箱验证";
//邮件内容
String emailContent = "您正在【好学堂】进行邮箱验证,您的验证码为:" + verifyCode + ",请于10分钟内完成验证!";
//发送邮件
SendmailUtil.sendEmail(toEmailAddress, emailTitle, emailContent);
return CalculatorUtil.getJSONString(0,verifyCode);
}catch(Exceptione){
return CalculatorUtil.getJSONString(1,"邮件发送失败!");
}
}
}
附:上述Util中使用到了我们自定义的两个Util,分别为CalculatorUtil、VerifyCodeUtil,附上相关方法源码:
CalculatorUtil(将数据包装到json中):
package com.coder.calculator.Util;
import com.alibaba.fastjson.JSONObject;
import java.security.MessageDigest;
import java.util.Map;
public class CalculatorUtil {
public static String getJSONString(int code){
JSONObject json = new JSONObject();
json.put("code", code);
return json.toJSONString();
}
public static String getJSONString(int code, String msg){
JSONObject json = new JSONObject();
json.put("code", code);
json.put("msg", msg);
return json.toJSONString();
}
}
VerifyCodeUtil(生成验证码):
package com.coder.calculator.Util;
import java.util.Random;
public class VerifyCodeUtil{
//验证码生成范围
//public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
public static final String VERIFY_CODES = "0123456789";
/**
* 使用系统默认字符源生成验证码
* @param verifySize 验证码长度
* @return
*/
public static String generateVerifyCode(int verifySize){
return generateVerifyCode(verifySize, VERIFY_CODES);
}
/**
* 使用指定源生成验证码
* @param verifySize 验证码长度
* @param sources 验证码字符源
* @return
*/
public static String generateVerifyCode(int verifySize, String sources){
if(sources == null || sources.length() == 0){
sources = VERIFY_CODES;
}
int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize);
for(int i = 0; i < verifySize; i++){
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
}
return verifyCode.toString();
}
}
5、前台调用该Controller方法:
5.1、发送自由编辑的邮件:
//收件人邮箱
var toEmailAddress="[email protected]";
//邮件主题
var emailTitle="我是邮件主题";
//邮件内容
var emailContent="我是邮件的内容,我要说一大串话,巴拉巴拉……";
$.ajax({
type:"post",
url:"/sendEmailOwn/",
data:{
emailTitle: emailTitle,
emailContent: emailContent,
toEmailAddress: toEmailAddress
},
dataType:"json",
success:function(data){
if(0 == data.code){
alert("邮件发送成功!");
} else {
alert(data.msg);
}
},
error:function(){
alert("数据传送失败!");
}
});
5.2、发送系统验证码:
//收件人邮箱
var toEmailAddress="[email protected]";
$.ajax({
type:"post",
url:"/sendEmailSystem/",
data:{
toEmailAddress: toEmailAddress
},
dataType:"json",
success:function(data){
if(0 == data.code){
alert("邮件发送成功,验证码为:" + data.msg);
} else {
alert(data.msg);
}
},
error:function(){
alert("数据传送失败!");
}
});
6、效果(我使用发送系统验证码测试一下):
7、邮件发送成功,验证码一致,大功告成!
▍我是尾巴
除了发送邮件以外,还搞定了发送短信验证码。
不过发邮件是免费的,发短信是收费的,需要向一些提供短信服务的代理商购买短信服务,比如:阿里云短信、腾讯云短信等。