本文小编为大家详细介绍“SpringBoot集成短信和邮件的配置方法”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot集成短信和邮件的配置方法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
准备工作
1、集成邮件
以QQ邮箱为例
在发送邮件之前,要开启POP3和SMTP协议,需要获得邮件服务器的授权码,获取授权码:
设置>账户
在账户的下面有一个开启SMTP协议的开关并进行密码验证:
获取成功的授权码
2、集成短信
以阿里云短信服务为例
登陆阿里云—>进入控制台—>开通短信服务
进入后根据提示开通短信服务即可。
充值
后期发短信测试需要,暂时可以跳过此步骤。
获取AccessKey和AccessSercet
API
依赖
邮件
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency>
短信
<dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <version>2.0.4</version></dependency>
配置
配置邮箱基本信息
spring: mail: # 配置 SMTP 服务器地址 host: smtp.qq.com # 发送者邮箱 username: 742354529@qq.com # 配置密码,注意不是真正的密码,而是申请的授权码 password: vjstfghblprwbdbd # 端口号465或587 port: 587 # 默认的邮件编码为UTF-8 default-encoding: UTF-8 # 配置SSL 加密工厂 properties: mail: smtp: socketFactoryClass: javax.net.ssl.SSLSocketFactory # 表示开启DEBUG模式,邮件发送过程的日志会在控制台打印出来 debug: true
SMTP 服务器地址
126邮箱SMTP服务器地址:smtp.126.com,端口号:465或者994
2163邮箱SMTP服务器地址:smtp.163.com,端口号:465或者994
yeah邮箱SMTP服务器地址:smtp.yeah.net,端口号:465或者994
qq邮箱SMTP服务器地址:smtp.qq.com,端口号465或587*
短信配置
# 阿里云短信配置sms: access-id: LTAI5tDP3SDQC9yvCguiiFDr access-key: EGSDQsLxCVS5dwjS8DCxmYQ124XySV sign-name: endpoint: dysmsapi.aliyuncs.com
编码
1、邮件
1、MailService.java
package com.tanersci.service;import com.tanersci.dto.MailMessageDto;import com.tanersci.vo.MessageVo;public interface MailService {MessageVo sendSimple(MailMessageDto dto); * @MonthName: sendAttachFile * @Description: 带附件的邮件MessageVo sendAttachFile(MailMessageDto dto); * @MonthName: sendImgRes * @Description: 带图片资源的邮件MessageVo sendImgRes(MailMessageDto dto);}
2、MailServiceImpl.java
package com.tanersci.service.impl;import com.alibaba.fastjson.JSON;import com.tanersci.dto.MailMessageDto;import com.tanersci.vo.MessageVo;import com.tanersci.constant.Constants;import com.tanersci.service.MailService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.io.FileSystemResource;import org.springframework.mail.MailException;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.time.LocalDateTime;import java.util.Date;import java.util.Objects;@Slf4j@Servicepublic class MailServiceImpl implements MailService {@Value("${spring.mail.username}")private String sender;@Autowiredprivate JavaMailSender javaMailSender;@Overridepublic MessageVo sendSimple(MailMessageDto dto) {try {log.info("=======普通邮件发送开始,请求参数:{}", JSON.toJSON(dto));// 构建一个邮件对象SimpleMailMessage message = new SimpleMailMessage();// 设置邮件主题message.setSubject(dto.getSubject());// 设置邮件发送者,这个跟application.yml中设置的要一致message.setFrom(sender);// 设置邮件接收者,可以有多个接收者,中间用逗号隔开,以下类似// message.setTo("10*****16@qq.com","12****32*qq.com");message.setTo(dto.getRecipient());// 设置邮件抄送人,可以有多个抄送人if (Objects.nonNull(dto.getCc())) {message.setCc(dto.getCc());}// 设置隐秘抄送人,可以有多个if (Objects.nonNull(dto.getBcc())) {message.setBcc(dto.getBcc());// 设置邮件发送日期message.setSentDate(new Date());// 设置邮件的正文message.setText(dto.getText());// 发送邮件javaMailSender.send(message);log.info("=======普通邮件发送结束");return MessageVo.builder().code(Constants.NEWS_SUCCESS_CODE).message(Constants.NEWS_SUCCESS_MESSAGE).build();} catch (MailException e) {log.error("====邮件====sendSimple=====异常:{}", e);return MessageVo.builder().code(Constants.NEWS_FAIL_CODE).message(Constants.NEWS_FAIL_MESSAGE).build();}} * @MonthName: sendAttachFile * @Description: 带附件的邮件public MessageVo sendAttachFile(MailMessageDto dto) {log.info("=======带附件的邮件开始,请求参数:{}", JSON.toJSON(dto));MimeMessage mimeMessage = javaMailSender.createMimeMessage();// true表示构建一个可以带附件的邮件对象MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);// 第一个参数是自定义的名称,后缀需要加上,第二个参数是文件的位置dto.getAttachments().forEach(file -> {try {message.addAttachment(file.getName(), file);} catch (MessagingException e) {log.error("=========邮件附件解析异常:{}", e);}});javaMailSender.send(mimeMessage);log.info("=======带附件的邮件结束");} catch (MessagingException e) {log.error("==========邮件====sendAttachFile=====异常:{}", e); * @MonthName: sendImgRes * @Description: 带图片资源的邮件public MessageVo sendImgRes(MailMessageDto dto) {log.info("=======带图片资源的邮件开始,请求参数:{}", JSON.toJSON(dto));// 第一个参数指的是html中占位符的名字,第二个参数就是文件的位置message.addInline(file.getName(), new FileSystemResource(file));log.error("=========邮件图片解析异常:{}", e);log.info("=======带图片资源的邮件结束");log.error("====邮件====sendImgRes=====异常:{}", e);}
3、VO、DTO及常量类
MailMessageDto.java
package com.tanersci.dto;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.File;import java.io.Serializable;import java.util.List;@Data@AllArgsConstructor@NoArgsConstructor@Builder@ApiModel(value = "邮件消息")public class MailMessageDto implements Serializable {private static final long serialVersionUID = 5483400172436286831L;@ApiModelProperty(value = "邮件主题")private String subject;@ApiModelProperty(value = "接收者:可以有多个接收者,中间用逗号隔开")private String recipient;@ApiModelProperty(value = "抄送人:可以有多个抄送人,中间用逗号隔开")private String cc;@ApiModelProperty(value = "隐秘抄送人:可以有多个抄送人,中间用逗号隔开")private String bcc;@ApiModelProperty(value = "正文")private String text;@ApiModelProperty(value = "模板编码")private String code;@ApiModelProperty(value = "附件、图片")private List<File> attachments;}
MessageVo.java
package com.tanersci.vo;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;@Data@AllArgsConstructor@NoArgsConstructor@Builder@ApiModel(value = "短信、邮件消息返回值")public class MessageVo implements Serializable {private static final long serialVersionUID = 5287525465339500144L;@ApiModelProperty(value = "状态码")private String code;@ApiModelProperty(value = "状态码的描述")private String message;@ApiModelProperty(value = "请求ID")private String requestId;@ApiModelProperty(value = "发送回执ID")private String bizId;@ApiModelProperty(value = "模板编码")private String templateCode;}
Constants.java
package com.tanersci.constant;public class Constants {public final static String NEWS_SUCCESS_CODE = "OK";public final static String NEWS_SUCCESS_MESSAGE = "发送成功";public final static String NEWS_FAIL_CODE = "FAIL";public final static String NEWS_FAIL_MESSAGE = "发送失败";}
2、短信
1、SmsService.java
package com.tanersci.service;import com.tanersci.dto.SmsMessageDto;import com.tanersci.dto.SmsTemplateDto;import com.tanersci.vo.MessageVo;public interface SmsService {MessageVo send(SmsMessageDto dto); * @MonthName: addSmsTemplate * @Description: 申请短信模板 * @Param: [template]MessageVo addSmsTemplate(SmsTemplateDto template); * @MonthName: deleteSmsTemplate * @Description: 删除短信模板MessageVo deleteSmsTemplate(SmsTemplateDto template); * @MonthName: modifySmsTemplate * @Description: 修改未通过审核的短信模板MessageVo modifySmsTemplate(SmsTemplateDto template); * @MonthName: querySmsTemplate * @Description: 查询短信模板的审核状态MessageVo querySmsTemplate(SmsTemplateDto template);}
2、SmsServiceImpl.java
package com.tanersci.service.impl;import com.alibaba.fastjson.JSON;import com.aliyun.dysmsapi20170525.Client;import com.aliyun.dysmsapi20170525.models.*;import com.aliyun.teaopenapi.models.Config;import com.tanersci.dto.SmsMessageDto;import com.tanersci.dto.SmsTemplateDto;import com.tanersci.vo.MessageVo;import com.tanersci.config.SmsConfig;import com.tanersci.constant.Constants;import com.tanersci.service.SmsService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.time.LocalDateTime;import java.util.Objects;import java.util.UUID;@Slf4j@Servicepublic class SmsServiceImpl implements SmsService {@Autowiredprivate SmsConfig smsConfig;public Client createClient() throws Exception {Config config = new Config();config.accessKeyId = smsConfig.getAccessId();config.accessKeySecret = smsConfig.getAccessKey();config.endpoint = smsConfig.getEndpoint();return new Client(config);} * @MonthName: send * @Description: 发短信 * @Date: 2021/6/7 14:50 * @Param: [dto] * @return: com.tanersci.vo.MessageVo@Overridepublic MessageVo send(SmsMessageDto dto) {try {log.info("======发送短信开始,请求参数:{}", JSON.toJSON(dto));Client client = createClient();// 组装请求对象SendSmsRequest request = new SendSmsRequest();// 外部流水扩展字段String outId = UUID.randomUUID().toString();request.setOutId(outId);// 支持对多个手机号码发送短信,手机号码之间以英文逗号(,)分隔。上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。request.setPhoneNumbers(dto.getPhone());// 短信签名名称request.setSignName(smsConfig.getSignName());// 短信模板IDrequest.setTemplateCode(dto.getTemplateCode());// 短信模板变量对应的实际值,JSON格式。如果JSON中需要带换行符,请参照标准的JSON协议处理。request.setTemplateParam(JSON.toJSONString(dto.getParam()));// 发送短信SendSmsResponse res = client.sendSms(request);MessageVo message = MessageVo.builder().build();if (Objects.equals(Constants.NEWS_SUCCESS_CODE, res.body.getCode())) {log.info("======发送短信成功,返回值:{}", JSON.toJSON(res.body));message.setCode(Constants.NEWS_SUCCESS_CODE);message.setMessage(Constants.NEWS_SUCCESS_MESSAGE);} else {log.info("======发送短信失败,返回值:{}", JSON.toJSON(res.body));message.setCode(Constants.NEWS_FAIL_CODE);message.setMessage(Constants.NEWS_FAIL_MESSAGE);}return message;} catch (Exception e) {log.error("======发送短信异常:{}", e.getMessage());e.printStackTrace();return MessageVo.builder().code(Constants.NEWS_FAIL_CODE).message(Constants.NEWS_FAIL_MESSAGE).build();} * @MonthName: addSmsTemplate * @Description: 申请短信模板 * @Param: [template]public MessageVo addSmsTemplate(SmsTemplateDto template) {log.info("======申请短信模板,请求参数:{}", JSON.toJSON(template));AddSmsTemplateRequest request = new AddSmsTemplateRequest();request.setTemplateType(template.getTemplateType());request.setTemplateName(template.getTemplateName());request.setTemplateContent(template.getTemplateContent());request.setRemark(template.getRemark());AddSmsTemplateResponse res = client.addSmsTemplate(request);if (Objects.equals(TeamConstants.NEWS_SUCCESS_CODE, res.body.getCode())) {log.info("======申请短信模板,返回值:{}", JSON.toJSON(res.body));return MessageVo.builder().code(Constants.NEWS_SUCCESS_CODE).message(Constants.NEWS_SUCCESS_MESSAGE).templateCode(res.getBody().templateCode).build();return MessageVo.builder().code(Constants.NEWS_FAIL_CODE).message(Constants.NEWS_FAIL_MESSAGE).build();log.error("======申请短信模板,异常:{}", e.getMessage()); * @MonthName: deleteSmsTemplate * @Description: 删除短信模板public MessageVo deleteSmsTemplate(SmsTemplateDto template) {log.info("======删除短信模板,请求参数:{}", JSON.toJSON(template));DeleteSmsTemplateRequest request = new DeleteSmsTemplateRequest();request.setTemplateCode(template.getTemplateCode());DeleteSmsTemplateResponse res = client.deleteSmsTemplate(request);log.info("======删除短信模板,返回值:{}", JSON.toJSON(res.body));return MessageVo.builder().code(Constants.NEWS_SUCCESS_CODE).message(Constants.NEWS_SUCCESS_MESSAGE).build();log.error("======删除短信模板,异常:{}", e); * @MonthName: modifySmsTemplate * @Description: 修改未通过审核的短信模板public MessageVo modifySmsTemplate(SmsTemplateDto template) {log.info("======修改未通过审核的短信模板,请求参数:{}", JSON.toJSON(template));ModifySmsTemplateRequest request = new ModifySmsTemplateRequest();ModifySmsTemplateResponse res = client.modifySmsTemplate(request);log.info("======修改未通过审核的短信模板,返回值:{}", JSON.toJSON(res.body));log.error("======修改未通过审核的短信模板,异常:{}", e.getMessage()); * @MonthName: querySmsTemplate * @Description: 查询短信模板的审核状态public MessageVo querySmsTemplate(SmsTemplateDto template) {log.info("======查询短信模板的审核状态,请求参数:{}", JSON.toJSON(template));QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();QuerySmsTemplateResponse res = client.querySmsTemplate(request);log.info("======查询短信模板的审核状态,返回值:{}", JSON.toJSON(res.body));log.error("======查询短信模板的审核状态,异常:{}", e.getMessage());}
3、SmsConfig.java
package com.tanersci.config;import lombok.Data;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;@Data@Componentpublic class SmsConfig {@Value("${sms.access-id}")private String accessId;@Value("${sms.access-key}")private String accessKey;@Value("${sms.sign-name}")private String signName;@Value("${sms.endpoint}")private String endpoint;}
4、VO、DTO类
MessageVo 同用邮件的
MailMessageDto.java
package com.tanersci.dto;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;@Data@AllArgsConstructor@NoArgsConstructor@Builder@ApiModel(value = "短信消息")public class SmsMessageDto implements Serializable {private static final long serialVersionUID = 3427970548460798908L;@ApiModelProperty(value = "手机号,多个以逗号隔开")private String phone;@ApiModelProperty(value = "模板编码")private String templateCode;@ApiModelProperty(value = "模板参数")private TemplateParamDto param;private String code;}
SmsTemplate.java
package com.tanersci.dto;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;@Data@AllArgsConstructor@NoArgsConstructor@Builderpublic class SmsTemplateDto implements Serializable {private static final long serialVersionUID = -8909531614461840038L;private Integer templateType; * 模板名称,长度为1~30个字符private String templateName; * 模板内容,长度为1~500个字符private String templateContent; * 短信模板CODEprivate String templateCode; * 短信模板申请说明。请在申请说明中描述您的业务使用场景,长度为1~100个字符private String remark;}
注意
项目中使用lombok插件和swagger依赖,无相关依赖的请自行修改。
读到这里,这篇“SpringBoot集成短信和邮件的配置方法”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。