近况
最近马上要报名考试了,上一次过了一门科一,运气还算好的,要是一科都没过,真的不想考了
纵使如此,想一次性过科二和科三也是非常难的,况且笔试过后还有面试,而我好像是有点社恐
不过也算是个锻炼自己的机会吧,总要锻炼一下自己的,加油加油,今年下半年一定要一次性过掉笔试
再失败的话,真的很累人,另外最近又有了考个摩托车证的想法,花费大概1500左右,考个摩托车证
以后攒钱买个摩托车也是挺好的,虽然没有钱买小轿车,但是也意味着不用背车贷不是,而且自己非常穷了
能开个摩托车也挺好的~
回归正题,今天记录一下配置发送邮件的功能
导入依赖
<!--邮件发送依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
Jeecg中对消息发送功能的设计
Jeecg中认为发送短信,发送邮件,发送微信消息,都可以抽象成一个体系,即发送消息的体系 所以我们可以看到消息发送功能的接口的设计如下: ISendMsgHandle接口 EmailSendMsgHandle实现类,处理邮件发送的功能 SmsSendMsgHandle实现类,处理短信发送的功能 WxSendMsgHandle实现类,处理微信消息发送的功能 除此之外,还配合MVC的设计理念,增加SysMessage实体类,SysMessageController,ISysMessageService 那么前端用户,只需要传递参数,然后SysMessage封装各个类型的参数,例如邮箱属性,短信属性,微信消息属性 然后Controller根据消息类型调用不同的Handle实现类进行处理,最后处理完了使用ISysMessageService进行处理保存数据到数据库。 注意:你可能注意到了,整个处理流程:各个消息类型参数->同一个SysMessage对象 ->同一个SysMessageController->各自的Handle实现类->调用同一个SysMessageServiceImpl 你可能会问为什么需要Handle呢?如果把Handle直接写成service的三个方法呢?如果写三个service实现类呢? 实际上我也不太懂,但我觉得可能是因为解耦,我并不想跟你模块相关联,把本模块的service使用spring自动注入 的方式去导入到其他类中使用,可能过于耦合了,而如果我直接在其他类的方法中使用handle实现类是不是更好? 我不知道是不是这个原因。 需要注意的是:其实短信,邮箱和微信消息这三个功能还是有些差异的,例如短信有消息模板的概念 那本文就不去描述非常完整的功能是如何设计的,主要是我也非常菜,就只针对邮箱功能进行记录吧。 以上是一些碎碎念,描述一下功能的结构是什么样的,下面是邮箱功能实现的具体代码
SysMessage
@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName("sys_sms") public class SysMessage extends JeecgEntity { /** * id */ @TableId(type = IdType.ASSIGN_ID) private String id; /**接收人*/ @Excel(name = "接收人", width = 15) private java.lang.String esReceiver; /**消息标题*/ @Excel(name = "消息标题", width = 15) private java.lang.String esTitle; /**推送内容*/ @Excel(name = "推送内容", width = 15) private java.lang.String esContent; /**推送所需参数Json格式*/ @Excel(name = "推送所需参数Json格式", width = 15) private java.lang.String esParam; /**推送失败原因*/ @Excel(name = "推送失败原因", width = 15) private java.lang.String esResult; /**发送次数*/ @Excel(name = "发送次数", width = 15) private java.lang.Integer esSendNum; /**推送状态 0未推送 1推送成功 2推送失败*/ @Excel(name = "推送状态 0未推送 1推送成功 2推送失败", width = 15) @Dict(dicCode = "msgSendStatus") private java.lang.String esSendStatus; /**推送时间*/ @Excel(name = "推送时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private java.util.Date esSendTime; /**推送方式:1短信 2邮件 3微信*/ @Excel(name = "推送方式:1短信 2邮件 3微信", width = 15) @Dict(dicCode = "msgType") private java.lang.String esType; /**备注*/ @Excel(name = "备注", width = 15) private java.lang.String remark; /** * 附件文件,前端传递的文件用该属性封装 */ @JsonIgnore @TableField(exist = false) private MultipartFile[] multipartFiles; /** * 附件文件,后端发送邮箱需要的文件用该属性封装 */ @JsonIgnore @TableField(exist = false) private File[] files; } /* 用两个对象封装文件,是感觉这两者转换起来很麻烦,干脆直接分别存了, 之后在handle实现类中分别判断哪个里面有文件 */
所需的枚举类
/** * 推送状态枚举 */ public enum SendMsgStatusEnum { //推送状态 0未推送 1推送成功 2推送失败 WAIT("0"), SUCCESS("1"), FAIL("2"); private String code; private SendMsgStatusEnum(String code) { this.code = code; } public String getCode() { return code; } public void setStatusCode(String code) { this.code = code; } } /** * 发送消息类型枚举 */ public enum SendMsgTypeEnum { //推送方式:1短信 2邮件 3微信 SMS("1", "SmsSendMsgHandle"), EMAIL("2", "EmailSendMsgHandle"), WX("3","WxSendMsgHandle"); private String type; private String implClass; private SendMsgTypeEnum(String type, String implClass) { this.type = type; this.implClass = implClass; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getImplClass() { return implClass; } public void setImplClass(String implClass) { this.implClass = implClass; } public static SendMsgTypeEnum getByType(String type) { if (oConvertUtils.isEmpty(type)) { return null; } for (SendMsgTypeEnum val : values()) { if (val.getType().equals(type)) { return val; } } return null; } }
Controller
@Slf4j @RestController @RequestMapping("/sys/message/sysMessage") public class SysMessageController extends JeecgController<SysMessage, ISysMessageService> { @Autowired private ISysMessageService sysMessageService; @Autowired private EmailSendMsgHandle emailSendMsgHandle; @PostMapping(value = "/send") public Result<?> send(SysMessage sysMessage) { String esType = sysMessage.getEsType(); if (ObjectUtil.isNotEmpty(esType)) { if (ObjectUtil.equals(esType, SendMsgTypeEnum.EMAIL.getType())){ SysMessage message = emailSendMsgHandle.sendMail(sysMessage); return Result.OK(message); }else { return Result.error("其他方式尚在开发中"); } }else { return Result.error("发送消息的类型不能为空"); } } }
EmailSendMsgHandle
@Component public class EmailSendMsgHandle implements ISendMsgHandle { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private JavaMailSenderImpl mailSender; @Autowired private ISysMessageService sysMessageService; static String emailFrom; public static void setEmailFrom(String emailFrom) { EmailSendMsgHandle.emailFrom = emailFrom; } /** * 发送邮件,新方法,包括检测,发送,和保存邮件发送日志等流程 */ public SysMessage sendMail(SysMessage sysMessage) { try { //1.检测邮件 checkMail(sysMessage); //2.发送邮件 sendMimeMail(sysMessage); //3.保存邮件 return saveMail(sysMessage); } catch (Exception e) { logger.error("发送邮件失败:", e); sysMessage.setEsSendStatus(SendMsgStatusEnum.FAIL.getCode()); sysMessage.setEsResult(e.getMessage()); return sysMessage; } } /** * 检测邮件信息类 * @param sysMessage */ private void checkMail(SysMessage sysMessage) { if (ObjectUtil.isEmpty(sysMessage.getEsReceiver())) { throw new RuntimeException("邮件收信人不能为空"); } if (ObjectUtil.isEmpty(sysMessage.getEsTitle())) { throw new RuntimeException("邮件主题不能为空"); } if (ObjectUtil.isEmpty(sysMessage.getEsContent())) { throw new RuntimeException("邮件内容不能为空"); } } /** * 构建复杂邮件信息类 * @param sysMessage */ private void sendMimeMail(SysMessage sysMessage) { try { MimeMessageHelper messageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true); sysMessage.setEsType(SendMsgTypeEnum.EMAIL.getType()); //邮件发信人 messageHelper.setFrom(getMailSendFrom()); //邮件收信人 messageHelper.setTo(sysMessage.getEsReceiver().split(",")); //邮件主题 messageHelper.setSubject(sysMessage.getEsTitle()); //邮件内容 messageHelper.setText(sysMessage.getEsContent()); //添加邮件附件,前端 if (sysMessage.getMultipartFiles() != null) { for (MultipartFile multipartFile : sysMessage.getMultipartFiles()) { messageHelper.addAttachment(multipartFile.getOriginalFilename(), multipartFile); } } //添加邮件附件,后端 if (sysMessage.getFiles() != null) { Arrays.stream(sysMessage.getFiles()).forEach(file -> { try { messageHelper.addAttachment(file.getName(), file); } catch (MessagingException e) { e.printStackTrace(); } }); } //发送时间 if (ObjectUtil.isEmpty(sysMessage.getEsSendTime())) { sysMessage.setEsSendTime(new Date()); messageHelper.setSentDate(sysMessage.getEsSendTime()); } //正式发送邮件 mailSender.send(messageHelper.getMimeMessage()); sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode()); logger.info("发送邮件成功:{}->{}", getMailSendFrom(), sysMessage.getEsReceiver()); } catch (Exception e) { throw new RuntimeException("发送邮件失败",e); } } /** * 保存邮件 * @param sysMessage * @return */ private SysMessage saveMail(SysMessage sysMessage) { sysMessageService.save(sysMessage); return sysMessage; } /** * 获取邮件发信人 * @return */ public String getMailSendFrom() { return mailSender.getJavaMailProperties().getProperty("from"); } }
文章推荐
其实上面的逻辑也是网上的代码逻辑,来看看别人的代码怎么写的吧