700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java spring-boot-starter-mail邮件和阿里云华为云短信发送全套

java spring-boot-starter-mail邮件和阿里云华为云短信发送全套

时间:2023-07-02 02:51:21

相关推荐

java spring-boot-starter-mail邮件和阿里云华为云短信发送全套

短信API都是需要对接平台的,平台会提供参考代码比较简单,但是邮件是免费的,除了springboot,还能用javaxmail(我记得是,大家可以查查资料)

文章目录

前言

一、spring-boot-starter-mail发邮件

1.开发前准备

2.需要导入的包

3.发送邮件和html

4.线程池/新线程群发邮件

5.结果

二、短信发送(需要收费)

1.阿里云

2.华为云

3.结果

总结

前言

文章记录开发中的学习心得,以及遇到的各种问题,以便后续回顾,也供大家学习参考。

一、spring-boot-starter-mail发邮件

1.开发前准备

目前探索过腾讯的个人邮箱和企业邮箱。两类邮箱配置过程比较类似:开通邮箱的客户端服务,获取授权码。

个人QQ邮箱:

(1)开通客户端服务(设置-账户,根据系统操作提示)

(2)获取授权码(上一步完成后,点击“管理服务“进入)

这里需要注意,授权码最好记住,后续查看可能比较麻烦(密文)。

腾讯企业邮箱(一般默认是开通了客户端服务的,可以直接用账号密码用于授权,为避免泄露,可绑定微信生成授权码,此处不再赘述)

2.需要导入的包

(1)spring-boot-starter-mail包

<!-- /artifact/org.springframework.boot/spring-boot-starter-mail --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><version>2.7.1</version></dependency>

(2)thymeleaf(需要发送html时需要模板引擎)

<!-- SpringBoot集成thymeleaf模板 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

3.发送邮件和html

这里先简单介绍一下单发邮件的方法。发送邮件需要以下参数:

#邮箱配置mail:host: port: 465username: xxx@# 授权密码, 非邮箱密码,授权码是用于登录第三方邮件客户端的专用密码。password: xxxxdefault-encoding: UTF-8protocol: smtps # 这个必须特殊声明为smtps,不然会报异常#邮箱验证码有效时间/秒code:expiration: 300

(1)邮箱配置的相关参数写在配置文件yml中

类似上述的配置写在邮箱中,需要取出才能生效,参考以下代码:

这里不需要自己设置主机、端口、协议和编码等,只需要用JavaMailSender类即可,邮件实体自己设计,主要是收件人邮箱、主题、内容等。

@Autowiredprivate JavaMailSender mailSender;@Autowiredprivate TemplateEngine templateEngine;@Value("${spring.mail.host}")private String host;@Value("${spring.mail.port}")private String port;@Value("${spring.mail.username}")private String username;@Value("${spring.mail.password}")private String password;@Value("${code.expiration}")private Long expiration;private Date sendTime;@Overridepublic void send(Email emailDto) throws MessagingException {MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);helper.setFrom(username); // 发送者helper.setTo(emailDto.getTo()); // 接收者sendTime = new Date();helper.setSentDate(sendTime); //时间// helper.setText("测试"); //可以发送纯文字的,如果不设置text属性会报错// 这里引入的是Template的ContextContext context = new Context();Random random = new Random();//生成六位的随机数作为验证码authCode = String.valueOf(random.nextInt(1000000));//设置模板中的变量context.setVariable("verifyCode", Arrays.asList(authCode.split("")));// 第一个参数为模板的名称String process = templateEngine.process("email-template", context); //这里不用写全路径,email-template需要放在静态资源里// // 第二个参数true表示这是一个html文本helper.setText(process,true);try {mailSender.send(mimeMessage);log.info("邮件已经发送。");} catch (Exception e) {log.info("邮件发送失败",e);}}

(2)邮箱配置的相关参数自定义(存数据库中)

此类设置可以和前端联动,实现参数可配置的效果(切换邮箱发送时比较方便,不要改代码)

这里因为从数据库取数据,就需要自己设置主机、端口、协议和编码规则等,需要用JavaMailSender的实现类JavaMailSenderImpl,注意区分。

/*** 发送验证码* @param request* @param emailDto 邮箱列表* @return* @throws MessagingException*/@Overridepublic String send(HttpServletRequest request, Email emailDto) throws MessagingException {JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();//需要把mailSenderImpl传入配置参数,new出来的是空的emailSettings(mailSenderImpl,null);MimeMessage mimeMessage = mailSenderImpl.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);helper.setFrom(mailSenderImpl.getUsername()); // 发送者helper.setTo(emailDto.getTo()); // 接收者Date sendTime = new Date();helper.setSentDate(sendTime); //时间// helper.setText("测试");// 这里引入的是Template的ContextContext context = new Context();Random random = new Random();String authCode = "";//生成六位的随机数作为验证码for(int i=0;i<6;i++) {authCode += String.valueOf(random.nextInt(10));}HttpSession session = request.getSession();String sub = emailDto.getSubject();helper.setSubject(sub);context.setVariable("operation",sub);//设置模板中的变量context.setVariable("verifyCode", Arrays.asList(authCode.split("")));//存储验证码发送时的信息(用session存比较方便)session.setAttribute("sendTime",sendTime);session.setAttribute("verifyCode",authCode);// 第一个参数为模板的名称String process = templateEngine.process("email-template", context); //这里不用写全路径// // 第二个参数true表示这是一个html文本helper.setText(process,true);try {mailSenderImpl.send(mimeMessage);log.info("邮件已经发送。");return "邮件发送成功!";} catch (Exception e) {log.info("邮件发送失败",e);return e.getMessage();}}/*** 配置邮箱的基本信息*/@Overridepublic void emailSettings(JavaMailSenderImpl mailSenderImpl,EmailSetting emailSet) {//判断emailSet是否为空,不为空就是测试邮箱配置if(StringUtils.isNotNull(emailSet)) {mailSenderImpl.setHost(emailSet.getHost());mailSenderImpl.setUsername(emailSet.getUserName());mailSenderImpl.setPort(emailSet.getPort());mailSenderImpl.setProtocol(emailSet.getProtocol());mailSenderImpl.setPassword(emailSet.getPassword());}else {//为空就是正常发邮件,需要查询数据库中的信息LambdaQueryWrapper<EmailSetting> emailSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();EmailSetting emailSetting = emailMapper.selectOne(emailSettingLambdaQueryWrapper);mailSenderImpl.setHost(emailSetting.getHost());mailSenderImpl.setPassword(emailSetting.getPassword());mailSenderImpl.setUsername(emailSetting.getUserName());mailSenderImpl.setPort(emailSetting.getPort());mailSenderImpl.setProtocol(emailSetting.getProtocol());}mailSenderImpl.setDefaultEncoding("UTF-8");}

4.线程池/新线程群发邮件

该方法适用于群发邮件,比如通知等,耗时较长,为了不阻塞主线程,可以创建新线程或者线程池的方式发送。注意群发邮件时不要重复给一个收件人发送,否则会报错(当作垃圾邮件处理)。

(1)线程池

该方法是合理利用线程池的能力,一个线程负责一封邮件,博主之前写过一遍,但是业务不需要,就删掉代码了,具体的可以参考网上资料(就是线程池的配置,然后把发邮件的业务放入线程池即可)

(2)新线程

该方法比较简单,主要是创建新线程,然后for循环发邮件。参考创建线程的方式(我记得有五种),我这里采用的是实现Runnable()接口重写run()方法。代码如下:

@Slf4jpublic class EmailThreadTask implements Callable<Boolean> {private IEmailService emailService;private List<Send> sendList;private JavaMailSenderImpl mailSender;private MimeMessage mimeMessage;private SendMapper sendMapper;public EmailThreadTask(IEmailService emailService, List<Send> sendList, JavaMailSenderImpl mailSender, MimeMessage mimeMessage,SendMapper sendMapper) {this.emailService = emailService;this.sendList = sendList;this.mailSender = mailSender;this.mimeMessage = mimeMessage;this.sendMapper = sendMapper;}//这里传入很多参数(注入service和mapper好像要加@Service注解,我一开始写的时候没加,大家可以试试,加了以后直接注入看看,就不需要传入这么多参数了),是因为循环发送时,公共部分只需要进行一次即可,比如配置邮箱,这里的mapper是因为博主需要根据邮件发送状态更新消息发送的情况,大家可以按需编写。@Overridepublic Boolean call() throws Exception {//将群发邮件操作放入线程//循环发送String status;List<String> results = new ArrayList<>();String result = "";for(Send send : sendList) {//循环发邮件status = emailService.sendNotice(send,mailSender,mimeMessage);result = send.getEmail() + ":" + status;results.add(result);//根据结果更新数据表状态send.setStatus(status);sendMapper.updateById(send);Thread.sleep(2000);//线程休眠2s}// log.info(results.toString());return null;}}/*** 群发邮件* @param sendList*/@Overridepublic void batchSendNotice(List<Send> sendList) {JavaMailSenderImpl mailSender = new JavaMailSenderImpl();emailService.emailSettings(mailSender,null);MimeMessage mimeMessage = mailSender.createMimeMessage();EmailThreadTask emailThreadTask = new EmailThreadTask(emailService,sendList,mailSender,mimeMessage,sendMapper);FutureTask<Boolean> futureTask = new FutureTask<>(emailThreadTask);new Thread(futureTask).start();//.start()才代表线程启动。

这里我写复杂了,其实只要匿名线程即可:

new Thread() {@Overriderun(){//循环放里面}}.start()

5.结果

这里的样式我是看了好几个资料(好像都是csdn上的,但是不记得哪里看的了,没有要抄袭的意思,大家看着设计就行,验证码需要传入用模板取值)

二、短信发送(需要收费)

1.阿里云

个人觉得阿里云平台比华为云平台要友好一点,尤其是对于新手来说,因为阿里云提供可视化界面,支持java异步发送短信,ui界面填入你的参数,它会自动生成相关的代码。

(1)开发准备

这里需要账号的授权key和secret。

开发者门户中有很详细的教程,大家自行参考,这里就不赘述啦~

(2)申请签名

发送短信需要签名和模板,签名就是:【中国移动】尊敬的用户您好,截至目前您的账号余额为:xxx。这里”中国移动“就是签名。

(3)申请模板

模板就是需要发送的内容,需要先申请签名才可以申请模板,具体要求看官方稳定,签名申请为通用类型可用于验证码和其他类型的模板,如果是验证码类的签名,则只可以用于验证码模板。

(4)需要的包(官方文档已经说的很清楚):

我这里的是异步的,所以是:

<!-- 阿里云短信异步发送 --><dependency><groupId>com.aliyun</groupId><artifactId>alibabacloud-dysmsapi0525</artifactId><version>2.0.23</version></dependency>

(5)示例代码(官方文档上很全)

2.华为云

(1)开发准备

华为云开通短信服务以后,需要创建应用,生成应用key和secret,即appKey和appSecret,还有app接入地址,详细的参考官方文档。

(2)申请签名和模板(和阿里云类似)

(3)示例代码:

但是官方文档的方法好像不是异步的,而且我也没有引用官方说的这些包,需要群发的小伙伴还是一样的考虑异步调用和新线程哈。

(4)群发短信

我这里还是采用循环发送的方法,所以设计客户端或者参数配置的,我都是群发之前就配置好了,大家懂吧。

阿里云的配置:

/*** 阿里云授权并创建客户端* @return*/private AsyncClient SmsConfig(SmsSet smsSet) {//授权StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder().accessKeyId(smsSet.getAccessKey()).accessKeySecret(smsSet.getAccessSecret()).build());// 配置客户端AsyncClient client = AsyncClient.builder().region(SmsConfigConstants.REGION_ID) // Region ID.credentialsProvider(provider).overrideConfiguration(ClientOverrideConfiguration.create().setEndpointOverride(SmsConfigConstants.END_POINT_OVERRIDE)//.setConnectTimeout(Duration.ofSeconds(30))).build();return client;}

华为云的配置:

华为云的代码比较多,其实就是一个思想,循环时只查一次数据库就可以,只配置一次。

这里参考官方代码就行,因为我也是这么写的。

3.结果

总结

以上就是今天要讲的内容,本文仅仅简单介绍了邮件和短信API的使用,以及在业务中实现参数动态配置的功能,大家按需参考哈,欢迎指出不足,共同进步。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。