发送邮件和短信都需要做好准备工作,本文的邮件使用了QQ邮箱作为发送者,要开启SMTP;短信用的是阿里云,要有创建好的签名和审核通过的短信模板,本文的主要内容的代码模块,这两个服务的准备工作就不多介绍了。
本来邮箱用的是163,但是163邮箱发送邮件一直提示554,不管怎么修改都不行,只好改用qq。
导入Maven依赖
<!--发送邮件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--发送短信-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>.5.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>.1.0</version>
</dependency>
然后是配置文件application:
server:
port:
spring:
mail:
host: smtp.qq.com # 邮件服务地址
username: 自己填 # 发送者邮箱
password: 自己填 # 授权码
default-encoding: UTF- # 默认的邮件编码为UTF-8
properties:
mail:
smtp:
auth: true
# 如果是用 SSL 方式,需要配置如下属性,使用qq邮箱的话需要开启
starttls:
enable: true
required: true
sms:
accessKeyId: 自己填
accessSecret: 自己填
signName: 自己填
templateCode: 自己填
发送邮件
邮件有多种类型:普通的纯文本、html格式、带附件、内容带图片。
package com.cc.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Map;
/**
* 邮件服务
* @author cc
* @date-12-07 10:37
*/@Service
public class MailService {
private final JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String SENDER;
public MailService(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
// 发送普通邮件
public void sendSimpleMailMessage(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(SENDER);
message.setTo(to);
message.setSubject(subject);
message.setText(content);
mailSender.send(message);
}
// 发送html邮件
public void sendMimeMessage(String to, String subject, String content) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();;
// true表示需要创建一个multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(SENDER);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
mailSender.send(message);
}
// 发送带附件的邮件
public void sendMimeMessage(String to, String subject, String content, String filePath) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();;
// true表示需要创建一个multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(SENDER);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = file.getFilename();
helper.addAttachment(fileName, file);
mailSender.send(message);
}
// 发送带静态文件的邮件
public void sendMimeMessage(String to, String subject, String content, Map<String,String> rscIdMap) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
// true表示需要创建一个multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(SENDER);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
for (Map.Entry<String, String> entry : rscIdMap.entrySet()) {
FileSystemResource file = new FileSystemResource(new File(entry.getValue()));
helper.addInline(entry.getKey(), file);
}
mailSender.send(message);
}
}
发送短信
package com.cc.service;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* 短信服务
*
* @author cc
* @date-12-07 9:50
*/@Service
public class SmsService {
@Value("${sms.accessKeyId}")
private String accessKeyId;
@Value("${sms.accessSecret}")
private String accessSecret;
@Value("${sms.signName}")
private String signName;
@Value("${sms.templateCode}")
private String templateCode;
public void send(String phone, String code) throws ClientException {
if (StringUtils.isEmpty(phone)) {
throw new RuntimeException("手机号码不能为空");
}
if (StringUtils.isEmpty(code)) {
throw new RuntimeException("验证码不能为空");
}
// 初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou",
accessKeyId, accessSecret);
IAcsClient acsClient = new DefaultAcsClient(profile);
// 组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
// 必填:待发送手机号
request.setPhoneNumbers(phone);
// 必填:短信签名-可在短信控制台中找到
request.setSignName(signName);
// 必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCode);
request.setTemplateParam("{\"code\":\"" + code + "\"}");
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if(sendSmsResponse.getCode()!= null && "OK".equals(sendSmsResponse.getCode())){
System.out.println("短信发送成功!");
}else {
throw new RuntimeException("短信发送失败:" + sendSmsResponse.getMessage());
}
}
}
生成验证码
package com.cc.utils;
import java.util.Random;
/**
* 验证码生成器
* @author cc
* @date-12-07 10:32
*/public class VerifyCodeGenerator {
public static String make(int length) {
if (length <=) {
throw new RuntimeException("验证码长度不能小于");
}
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i =; i < length; i++) {
sb.append(random.nextInt());
}
return sb.toString();
}
}
测试一下
在使用邮件的附件功能时,要提前在resources中添加pic01.png、pic02.png和test.txt文件,方便测试
测试类:
package com.cc;
import com.aliyuncs.exceptions.ClientException;
import com.cc.service.MailService;
import com.cc.service.SmsService;
import com.cc.utils.VerifyCodeGenerator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.SpringRunner;
import org.springframework.util.ResourceUtils;
import javax.mail.MessagingException;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTest {
// test中不能有有参构造函数
@Autowired
private MailService mailService;
@Autowired
private SmsService smsService;
private static final String TO = "xxx@qq.com";
private static final String SUBJECT = "出师表";
private static final String CONTENT = "先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。\n" +
"宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。";
// 测试发送普通邮件
@Test
public void sendSimpleMailMessage() {
mailService.sendSimpleMailMessage(TO, SUBJECT, CONTENT);
}
// 测试发送html邮件
@Test
public void sendHtmlMessage() throws MessagingException {
String htmlStr = "<h>Test</h1>";
mailService.sendMimeMessage(TO, SUBJECT, htmlStr);
}
// 测试发送带附件的邮件
@Test
public void sendAttachmentMessage() throws FileNotFoundException, MessagingException {
File file = ResourceUtils.getFile("classpath:test.txt");
System.out.println(file);
String filePath = file.getAbsolutePath();
mailService.sendMimeMessage(TO, SUBJECT, CONTENT, filePath);
}
// 测试发送带静态文件的邮件
@Test
public void sendStaticFileMessage() throws FileNotFoundException, MessagingException {
String htmlStr = "<html><body>测试:图片 <br> <img src=\'cid:pic1\'/><br>图片2 <br> <img src=\'cid:pic2\'/></body></html>";
Map<String, String> rscIdMap = new HashMap<>();
rscIdMap.put("pic", ResourceUtils.getFile("classpath:pic01.png").getAbsolutePath());
rscIdMap.put("pic", ResourceUtils.getFile("classpath:pic02.png").getAbsolutePath());
mailService.sendMimeMessage(TO, SUBJECT, htmlStr, rscIdMap);
}
// 测试发送短信
@Test
public void sendSms() throws ClientException {
smsService.send("your phone", VerifyCodeGenerator.make());
}
// 生成一段验证码
@Test
public void generatorVerifyCode() {
System.out.println(VerifyCodeGenerator.make());
}
}
邮件和短信的发送还是很简单的,都是调调接口。
使用短信的话要留意是收费的,当前的价格是0.045分一条。