9 changed files with 438 additions and 3 deletions
@ -0,0 +1,139 @@ |
|||
package com.ccsens.util.notice; |
|||
|
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.ccsens.util.notice.dto.MailDto; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import javax.activation.DataHandler; |
|||
import javax.activation.DataSource; |
|||
import javax.mail.Session; |
|||
import javax.mail.Transport; |
|||
import javax.mail.internet.*; |
|||
import javax.mail.util.ByteArrayDataSource; |
|||
import java.util.Date; |
|||
import java.util.Properties; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2021/8/11 16:10 |
|||
*/ |
|||
@Slf4j |
|||
public class MailSendUtil { |
|||
|
|||
public static void main(String[] args) throws Exception { |
|||
MailDto.Sender sender = new MailDto.Sender(); |
|||
MailDto.Receive receive = new MailDto.Receive(); |
|||
sendMail(sender, receive); |
|||
} |
|||
|
|||
public static void sendMail(MailDto.Receive receive ) throws Exception { |
|||
log.info("发送邮件,接收者:{}", receive); |
|||
MailDto.Sender sender = new MailDto.Sender(); |
|||
sendMail(sender, receive); |
|||
} |
|||
|
|||
public static void sendMail(MailDto.Sender sender, MailDto.Receive receive ) throws Exception { |
|||
log.info("发送邮件,发送者:{},接收者:{}", sender, receive); |
|||
if (sender == null || receive == null || !sender.check() || !receive.check()) { |
|||
return; |
|||
} |
|||
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
|
|||
Properties props = new Properties(); |
|||
props.setProperty("mail.transport.protocol", sender.getProtocol()); |
|||
props.setProperty("mail.smtp.host", sender.getHost()); |
|||
props.setProperty("mail.smtp.auth", "true"); |
|||
props.setProperty("mail.smtp.port", sender.getPort()); |
|||
props.setProperty("mail.smtp.ssl.enable", sender.getSsl()); |
|||
|
|||
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
|
|||
Session session = Session.getInstance(props); |
|||
// 设置为debug模式, 可以查看详细的发送 log
|
|||
session.setDebug(true); |
|||
|
|||
// 3. 创建一封邮件
|
|||
MimeMessage message = createMimeMessage(session, sender.getSender(), receive); |
|||
|
|||
// 4. 根据 Session 获取邮件传输对象
|
|||
Transport transport = session.getTransport(); |
|||
|
|||
// 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
|
|||
//
|
|||
// PS_01: 如果连接服务器失败, 都会在控制台输出相应失败原因的log。
|
|||
// 仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接,
|
|||
// 根据给出的错误类型到对应邮件服务器的帮助网站上查看具体失败原因。
|
|||
//
|
|||
// PS_02: 连接失败的原因通常为以下几点, 仔细检查代码:
|
|||
// (1) 邮箱没有开启 SMTP 服务;
|
|||
// (2) 邮箱密码错误, 例如某些邮箱开启了独立密码;
|
|||
// (3) 邮箱服务器要求必须要使用 SSL 安全连接;
|
|||
// (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务;
|
|||
// (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。
|
|||
//
|
|||
transport.connect(sender.getSender(), sender.getPassword()); |
|||
|
|||
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
|
|||
transport.sendMessage(message, message.getAllRecipients()); |
|||
|
|||
// 7. 关闭连接
|
|||
transport.close(); |
|||
} |
|||
|
|||
/** |
|||
* 创建一封只包含文本的简单邮件 |
|||
* |
|||
* @param session 和服务器交互的会话 |
|||
* @param sender 发送者账号 |
|||
* @param receive 收件人 |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static MimeMessage createMimeMessage(Session session, String sender, MailDto.Receive receive) throws Exception { |
|||
// 1. 创建一封邮件
|
|||
MimeMessage message = new MimeMessage(session); |
|||
|
|||
// 2. From: 发件人
|
|||
message.setFrom(new InternetAddress(sender)); |
|||
|
|||
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
|
|||
message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(receive.getTos())); |
|||
if (StrUtil.isNotBlank(receive.getCcs())) { |
|||
// 抄送
|
|||
message.setRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(receive.getCcs())); |
|||
} |
|||
if (StrUtil.isNotBlank(receive.getBccs())) { |
|||
// 密送
|
|||
message.setRecipients(MimeMessage.RecipientType.BCC, InternetAddress.parse(receive.getBccs())); |
|||
} |
|||
|
|||
// 4. Subject: 邮件主题
|
|||
message.setSubject(receive.getSubject(), "UTF-8"); |
|||
|
|||
// 5. Content: 邮件正文(可以使用html标签)判断有无附件
|
|||
if (receive.getAttachmentFiles() == null || receive.getAttachmentFiles().length <= 0) { |
|||
message.setContent(receive.getContent(), "text/html;charset=UTF-8"); |
|||
} else { |
|||
//一个Multipart对象包含一个或多个bodypart对象,组成邮件正文
|
|||
MimeMultipart multipart = new MimeMultipart(); |
|||
MimeBodyPart text = new MimeBodyPart(); |
|||
text.setContent(receive.getContent(),"text/html;charset=UTF-8"); |
|||
multipart.addBodyPart(text); |
|||
for (MailDto.AttachmentFile file: receive.getAttachmentFiles()) { |
|||
MimeBodyPart fileBody = new MimeBodyPart(); |
|||
DataSource source = new ByteArrayDataSource(file.getIn(), "application/msexcel"); |
|||
fileBody.setDataHandler(new DataHandler(source)); |
|||
fileBody.setFileName(MimeUtility.encodeText(file.getName())); |
|||
multipart.addBodyPart(fileBody); |
|||
} |
|||
message.setContent(multipart); |
|||
} |
|||
|
|||
// 6. 设置发件时间
|
|||
message.setSentDate(new Date()); |
|||
|
|||
// 7. 保存设置
|
|||
message.saveChanges(); |
|||
|
|||
return message; |
|||
} |
|||
} |
@ -0,0 +1,81 @@ |
|||
package com.ccsens.util.notice; |
|||
|
|||
import com.ccsens.util.config.MyPropertySourceFactory; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Getter; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.context.annotation.PropertySource; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* @program: ptpro |
|||
* @description: |
|||
* @author: wu huijuan |
|||
* @create: 2019/10/21 10:37 |
|||
*/ |
|||
@PropertySource(name="noticePropUtil",value = {"classpath:notice/notice.yml"}, factory = MyPropertySourceFactory.class) |
|||
@Component |
|||
public class NoticePropUtil { |
|||
@ApiModelProperty("host") |
|||
public static String host; |
|||
@ApiModelProperty("端口") |
|||
public static String port; |
|||
@ApiModelProperty("协议") |
|||
public static String protocol; |
|||
@ApiModelProperty("发送账号") |
|||
public static String sender; |
|||
@ApiModelProperty("密码或授权码") |
|||
public static String password; |
|||
@ApiModelProperty("ssl") |
|||
public static String ssl; |
|||
@ApiModelProperty("短信appId") |
|||
public static String sms_app_id; |
|||
@ApiModelProperty("短信appKey") |
|||
public static String sms_app_key; |
|||
@ApiModelProperty("短信签名") |
|||
public static String sms_sign; |
|||
@ApiModelProperty("发送短信 tx:腾讯") |
|||
public static String sms_type; |
|||
|
|||
@Value("${util.mail.host:smtp.qiye.aliyun.com}") |
|||
public void setHost(String host) { |
|||
NoticePropUtil.host = host; |
|||
} |
|||
@Value("${util.mail.port:465}") |
|||
public void setPort(String port) { |
|||
NoticePropUtil.port = port; |
|||
} |
|||
@Value("${util.mail.protocol:smtp}") |
|||
public void setProtocol(String protocol) { |
|||
NoticePropUtil.protocol = protocol; |
|||
} |
|||
@Value("${util.mail.sender:admin@ccsens.com}") |
|||
public void setSender(String sender) { |
|||
NoticePropUtil.sender = sender; |
|||
} |
|||
@Value("${util.mail.password:111111aA!}") |
|||
public void setPassword(String password) { |
|||
NoticePropUtil.password = password; |
|||
} |
|||
@Value("${util.mail.ssl:true}") |
|||
public void setSsl(String ssl) { |
|||
NoticePropUtil.ssl = ssl; |
|||
} |
|||
@Value("${util.sms.appId:}") |
|||
public void setSms_app_id(String sms_tx_app_id) { |
|||
NoticePropUtil.sms_app_id = sms_tx_app_id; |
|||
} |
|||
@Value("${util.sms.appKey:}") |
|||
public void setSms_app_key(String sms_tx_app_key) { |
|||
NoticePropUtil.sms_app_key = sms_tx_app_key; |
|||
} |
|||
@Value("${util.sms.sign:}") |
|||
public void setSms_sign(String sms_tx_sign) { |
|||
NoticePropUtil.sms_sign = sms_tx_sign; |
|||
} |
|||
@Value("${util.sms.type:}") |
|||
public void setSms_type(String sms_type) { |
|||
NoticePropUtil.sms_type = sms_type; |
|||
} |
|||
} |
@ -0,0 +1,62 @@ |
|||
package com.ccsens.util.notice; |
|||
|
|||
import com.ccsens.util.notice.dto.SmsDto; |
|||
import com.github.qcloudsms.SmsSingleSender; |
|||
import com.github.qcloudsms.SmsSingleSenderResult; |
|||
import com.github.qcloudsms.httpclient.HTTPException; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.io.IOException; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2021/8/12 9:53 |
|||
*/ |
|||
@Slf4j |
|||
public class SmsSendUtil { |
|||
|
|||
public static void sendTxSms(SmsDto.Sms sms, String phone, int templateId, String[] params) throws HTTPException, IOException { |
|||
|
|||
|
|||
//数组具体的元素个数和模板中变量个数必须一致,例如事例中templateId:5678对应一个变量,参数数组中元素个数也必须是一个
|
|||
|
|||
SmsSingleSender sender = new SmsSingleSender(Integer.parseInt(sms.getAppId()), sms.getAppkey()); |
|||
// 签名参数未提供或者为空时,会使用默认签名发送短信
|
|||
SmsSingleSenderResult result = sender.sendWithParam("86", phone, |
|||
templateId, params, sms.getSmsSign(), "", ""); |
|||
log.info(String.valueOf(result)); |
|||
|
|||
} |
|||
|
|||
public static void sendSms(SmsDto.Receive receive) throws HTTPException, IOException { |
|||
|
|||
SmsDto.Sms sms = new SmsDto.Sms(); |
|||
switch (sms.getSmsType()) { |
|||
case Type.TX: |
|||
sendTxSms(sms, receive.getPhone(), receive.getTemplateId(), receive.getParams()); |
|||
break; |
|||
default: |
|||
log.info("暂不支持其他类型"); |
|||
break; |
|||
} |
|||
|
|||
} |
|||
|
|||
public static void sendSms(SmsDto.Sms sms, SmsDto.Receive receive) throws HTTPException, IOException { |
|||
|
|||
switch (sms.getSmsType()) { |
|||
case Type.TX: |
|||
sendTxSms(sms, receive.getPhone(), receive.getTemplateId(), receive.getParams()); |
|||
break; |
|||
default: |
|||
log.info("暂不支持其他类型"); |
|||
break; |
|||
} |
|||
|
|||
} |
|||
|
|||
public static class Type{ |
|||
public final static String TX = "tx"; |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
package com.ccsens.util.notice.dto; |
|||
|
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.ccsens.util.notice.NoticePropUtil; |
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
|
|||
import java.io.InputStream; |
|||
|
|||
/** |
|||
* @description:发送邮件入参 |
|||
* @author: whj |
|||
* @time: 2021/8/11 16:52 |
|||
*/ |
|||
@Data |
|||
public class MailDto { |
|||
|
|||
@ApiModel("邮件发件人") |
|||
@Data |
|||
public static class Sender{ |
|||
@ApiModelProperty("host") |
|||
private String host = NoticePropUtil.host; |
|||
@ApiModelProperty("端口") |
|||
private String port = NoticePropUtil.port; |
|||
@ApiModelProperty("协议") |
|||
private String protocol = NoticePropUtil.protocol; |
|||
@ApiModelProperty("发送账号") |
|||
private String sender = NoticePropUtil.sender; |
|||
@ApiModelProperty("密码或授权码") |
|||
private String password = NoticePropUtil.password; |
|||
@ApiModelProperty("ssl") |
|||
private String ssl = NoticePropUtil.ssl; |
|||
|
|||
public boolean check(){ |
|||
return StrUtil.isNotBlank(host) && StrUtil.isNotBlank(port) |
|||
&& StrUtil.isNotBlank(protocol) && StrUtil.isNotBlank(sender) |
|||
&& StrUtil.isNotBlank(password) && StrUtil.isNotBlank(ssl); |
|||
} |
|||
} |
|||
|
|||
@Data |
|||
@ApiModel("邮件收件人") |
|||
public static class Receive{ |
|||
@ApiModelProperty("To收件人,多个收件人之间用,分割") |
|||
private String tos; |
|||
@ApiModelProperty("CC 抄送人,多个抄送人之间用,分割") |
|||
private String ccs; |
|||
@ApiModelProperty("BCC密送,多个抄送人之间用,分割") |
|||
private String bccs; |
|||
@ApiModelProperty("主题") |
|||
private String subject; |
|||
@ApiModelProperty("正文") |
|||
private String content; |
|||
@ApiModelProperty("附件") |
|||
private AttachmentFile[] attachmentFiles; |
|||
|
|||
public boolean check(){ |
|||
return StrUtil.isNotBlank(tos); |
|||
} |
|||
} |
|||
|
|||
|
|||
@Data |
|||
@ApiModel("附件") |
|||
public static class AttachmentFile { |
|||
|
|||
@ApiModelProperty("文件输入流") |
|||
private InputStream in; |
|||
@ApiModelProperty("附件名,含后缀") |
|||
private String name; |
|||
} |
|||
} |
@ -0,0 +1,37 @@ |
|||
package com.ccsens.util.notice.dto; |
|||
|
|||
import com.ccsens.util.notice.NoticePropUtil; |
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @description: 短信 |
|||
* @author: whj |
|||
* @time: 2021/8/12 9:37 |
|||
*/ |
|||
public class SmsDto { |
|||
@Data |
|||
@ApiModel("短信") |
|||
public static class Sms { |
|||
@ApiModelProperty("appId") |
|||
private String appId = NoticePropUtil.sms_app_id; |
|||
@ApiModelProperty("appkey") |
|||
private String appkey = NoticePropUtil.sms_app_key; |
|||
@ApiModelProperty("短信签名") |
|||
private String smsSign = NoticePropUtil.sms_sign; |
|||
@ApiModelProperty("短信类型,tx:腾讯") |
|||
private String smsType = NoticePropUtil.sms_type; |
|||
} |
|||
|
|||
@Data |
|||
@ApiModel("短信接收信息") |
|||
public static class Receive{ |
|||
@ApiModelProperty("手机号") |
|||
private String phone; |
|||
@ApiModelProperty("模板ID") |
|||
private int templateId; |
|||
@ApiModelProperty("参数") |
|||
private String[] params; |
|||
} |
|||
} |
Loading…
Reference in new issue