SpringBoot 集成短信和邮件的配置示例详解

网友投稿 248 2022-10-11

SpringBoot 集成短信和邮件的配置示例详解

目录依赖配置编码1、邮件2、短信

准备工作

1、集成邮件

以QQ邮箱为例

在发送邮件之前,要开启POP3和SMTP协议,需要获得邮件服务器的授权码,获取授权码:

1、设置>账户

在账户的下面有一个开启SMTP协议的开关并进行密码验证:

2、获取成功的授权码

2、集成短信

以阿里云短信服务为例

1、登陆阿里云—>进入控制台—>开通短信服务

进入后根据提示开通短信服务即可。

2、充值

后期发短信测试需要,暂时可以跳过此步骤。

3、获取AccessKey和AccessSercet

文档使用指引: https://help.aliyun.com/document_detail/59210.html?spm=a2c6h.13066369.0.0.4b3516b4kN0052

4、API

OpenAPI地址: https://next.api.aliyun.com/document/Dysmsapi/2017-05-25/overview

依赖

1、邮件

org.springframework.boot

spring-boot-starter-mail

2、短信

com.aliyun

dysmsapi20170525

2.0.4

配置

1、配置邮箱基本信息

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或者9942163邮箱SMTP服务器地址:smtp.163.com,端口号:465或者994yeah邮箱SMTP服务器地址:smtp.yeah.net,端口号:465或者994qq邮箱SMTP服务器地址:smtp.qq.com,端口号465或587*

2、短信配置

# 阿里云短信配置

sms:

access-id: LTAI5tDP3SDQC9yvCguiiFDr

access-key: EGSDQsLxCVS5dwjS8DCxmYQ124XySV

sign-name:

endpoint: dysmsapi.aliyuncs.com

编码

1、邮件

1.1、MailService.java

package com.tanersci.service;

import com.tanersci.dto.MailMessageDto;

import com.tanersci.vo.MessageVo;

/**

* @ClassName: MailService.java

* @ClassPath: com.tanersci.service.MailService.java

* @Description: 邮件

* @Author: tanyp

* @Date: 2021/6/7 9:18

**/

public interface MailService {

/**

* @MonthName: sendSimple

* @Description: 普通邮件发送

* @Author: tanyp

* @Date: 2021/6/7 9:30

* @Param: [dto]

* @return: void

**/

MessageVo sendSimple(MailMessageDto dto);

* @MonthName: sendAttachFile

* @Description: 带附件的邮件

MessageVo sendAttachFile(MailMessageDto dto);

* @MonthName: sendImgRes

* @Description: 带图片资源的邮件

MessageVo sendImgRes(MailMessageDto dto);

}

1.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;

/**

* @ClassName: MailServiceImpl.java

* @ClassPath: com.tanersci.service.impl.MailServiceImpl.java

* @Description: 邮件

* @Author: tanyp

* @Date: 2021/6/7 9:18

**/

@Slf4j

@Service

public class MailServiceImpl implements MailService {

@Value("${spring.mail.username}")

private String sender;

@Autowired

private JavaMailSender javaMailSender;

/**

* @MonthName: sendSimple

* @Description: 普通邮件发送

* @Author: tanyp

* @Date: 2021/6/7 9:30

* @Param: [dto]

* @return: void

**/

@Override

public 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);

}

1.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;

/**

* @ClassName: MailMessageDto.java

* @ClassPath: com.tanersci.dto.MailMessageDto.java

* @Description: 邮件消息

* @Author: tanyp

* @Date: 2021/6/7 9:20

**/

@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 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;

/**

* @ClassName: MessageVo.java

* @ClassPath: com.tanersci.vo.MessageVo.java

* @Description: 短信、邮件消息返回值

* @Author: tanyp

* @Date: 2021/6/7 11:35

**/

@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;

/**

* @ClassName: Constants.java

* @ClassPath: com.tanersci.constant.Constants.java

* @Description: 常量

* @Author: tanyp

* @Date: 2021/5/22 15:54

**/

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、短信

2.1、SmsService.java

package com.tanersci.service;

import com.tanersci.dto.SmsMessageDto;

import com.tanersci.dto.SmsTemplateDto;

import com.tanersci.vo.MessageVo;

/**

* @ClassName: SmsService.java

* @ClassPath: com.tanersci.service.SmsService.java

* @Description: 短信

* @Author: tanyp

* @Date: 2021/6/7 10:56

**/

public interface SmsService {

/**

* @MonthName: send

* @Description: 发短信

* @Author: tanyp

* @Date: 2021/6/7 14:50

* @Param: [dto]

* @return: com.tanersci.vo.MessageVo

**/

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.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;

/**

* @ClassName: SmsServiceImpl.java

* @ClassPath: com.tanersci.service.impl.SmsServiceImpl.java

* @Description: 短信

* @Author: tanyp

* @Date: 2021/6/7 10:57

**/

@Slf4j

@Service

public class SmsServiceImpl implements SmsService {

@Autowired

private SmsConfig smsConfig;

/**

* @MonthName: createClient

* @Description: SK初始化账号Client

* @Author: tanyp

* @Date: 2021/6/7 15:44

* @Param: [accessId, accessKey, endpoint]

* @return: com.aliyun.teaopenapi.Client

**/

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

@Override

public 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());

// 短信模板ID

request.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());

}

2.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;

/**

* @ClassName: SmsConfig.java

* @ClassPath: com.tanersci.config.SmsConfig.java

* @Description: 短信配置

* @Author: tanyp

* @Date: 2021/6/7 16:41

**/

@Data

@Component

public 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;

}

2.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;

/**

* @ClassName: MailMessageDto.java

* @ClassPath: com.tanersci.dto.SmsMessageDto.java

* @Description: 短信

* @Author: tanyp

* @Date: 2021/6/7 9:20

**/

@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;

/**

* @ClassName: SmsTemplate.java

* @ClassPath: com.tanersci.dto.SmsTemplateDto.java

* @Description: 短信模板

* @Author: tanyp

* @Date: 2021/6/7 15:02

**/

@Data

@AllArgsConstructor

@NoArgsConstructor

@Builder

public class SmsTemplateDto implements Serializable {

private static final long serialVersionUID = -8909531614461840038L;

/**

* 模板类型:0:验证码,1:短信通知,2:推广短信,3:国际/港澳台消息。

*/

private Integer templateType;

* 模板名称,长度为1~30个字符

private String templateName;

* 模板内容,长度为1~500个字符

private String templateContent;

* 短信模板CODE

private String templateCode;

* 短信模板申请说明。请在申请说明中描述您的业务使用场景,长度为1~100个字符

private String remark;

}

注意

项目中使用lombok插件和swagger依赖,无相关依赖的请自行修改。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Kubernetes + Knative :玩转云上弹幕部署 获取通关奖励
下一篇:AWS 大数据实战 Lab6 - 数据仓库和可视化(六)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~