您好,登錄后才能下訂單哦!
這篇文章主要介紹了Spring boot如何搭建郵件服務,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
前言:
發送郵件,肯定是每個公司都會有的基本業務。很多公司都會選擇把發送郵件作為一個基礎服務,對外提供接口。直接調用就可發郵件了。但是我們都知道發送郵件耗時都比較長。那么今天就介紹下使用Spring boot+eventbus來打造一個簡單郵件服務
規劃接口列表
發送郵件的類型準備的有三種
發送普通郵件
發送html郵件
發送圖文郵件
還有一個細節,如果我們同步的取發送郵件會有兩個問題。
接口響應時間比較長
遇到并發的情況,容易導致服務器壓力過大或者郵箱服務封ip
所以我們準備使用隊列來執行發送郵件的操作。可以解決這個問題。隊列我選用的是Google的eventbus。是一款很輕量的隊列。直接走的內存
準備工作
首先要在pom.xml中引入 需要使用的包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
spring-boot-starter-mail :spring-boot提供的發郵件的maven庫
guava:google提供的開源庫。里面包含來很多工具
lombok:可以幫你省去編寫實體類的工具
引入之后,我們還需要配置發送郵件所需要的必要配置
在application.properties中配置郵箱
spring.mail.host=smtp.mail.me.com //郵箱發送服務器 spring.mail.port=587//服務器端口 spring.mail.username=xxx6666@icloud.com//發件人郵箱 spring.mail.password=password//客戶端專用密碼 //如果和我一樣使用的icloud郵箱 還需要下列兩個配置,別的有的郵箱不需要 spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true
做到這里其實就已經完成了,發郵件所需要的配置了。但是我們是要用隊列來發送,所以還需要配置下隊列
@Configuration public class AsyncEventBusConfig { //實例化bean,采用單例形式注入容器 @Bean @Scope("singleton") public AsyncEventBus asyncEventBus(){ //創建線程池對象 final ThreadPoolExecutor executor=executor(); return new AsyncEventBus(executor); } //創建線程池方法 private ThreadPoolExecutor executor(){ return new ThreadPoolExecutor(2, 2,0L, TimeUnit.MICROSECONDS, new LinkedBlockingQueue<>()); } }
封裝EmailService
準備好了之后,就可以直接來封裝發送郵件的業務了。之前有提到我們需要三個接口,同樣的,我們也需要三個service方法
@Service public class EmailService { @Autowired private JavaMailSender javaMailSender; /** * 發件人。這里發件人一般是同使用的發件郵箱一致 */ @Value("${spring.mail.username}") private String from; /** * 發送文本郵件 * @param to 收件人郵箱地址 * @param subject 主題 * @param content 內容 */ public void sendTextMail(String to, String subject, String content) { SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); simpleMailMessage.setTo(to); simpleMailMessage.setSubject(subject); simpleMailMessage.setText(content); simpleMailMessage.setFrom(from); javaMailSender.send(simpleMailMessage); } /** * 發送html內容的郵件 * @param to 收件人 * @param htmlContent html內容 * @param subject 主題 * @throws MessagingException */ public void sendHtmlMail(String to, String htmlContent, String subject) throws MessagingException { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(message, true); messageHelper.setTo(to); messageHelper.setSubject(subject); messageHelper.setFrom(from); messageHelper.setText(htmlContent, true); javaMailSender.send(message); } /** * 發送圖文郵件 * @param to 收件人 * @param imgContent 圖文內容 * @param subject 主題 * @param rscId 資源id * @param imgPath 資源路徑 * @throws MessagingException */ public void sendImgMail(String to, String imgContent, String subject, String rscId, String imgPath) throws MessagingException { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(message, true); messageHelper.setTo(to); messageHelper.setSubject(subject); messageHelper.setFrom(from); messageHelper.setText(imgContent, true); messageHelper.addInline(rscId, new File(imgPath)); javaMailSender.send(message); } }
隊列監聽
既然封裝好了方法,那么就需要調用。調用的方式,其實就是將接口傳來的數據傳到隊列里。隊列的消費者接收到了消息就將消息拿來調用發送郵件的方法
我們首先創建一個消費類,用來接受消息,處理消息。
@Service public class EventBusListener { /** * 引入bean */ @Autowired private AsyncEventBus asyncEventBus; @Autowired private EmailService emailService; /** * 注冊服務類 */ @PostConstruct public void init(){ asyncEventBus.register(this); } /** * 線程安全,消費 文本消息 * @param textEmailDTO */ @AllowConcurrentEvents @Subscribe public void sendTextMail(TextEmailDTO textEmailDTO){ emailService.sendTextMail( textEmailDTO.getTo(), textEmailDTO.getSubject(), textEmailDTO.getContent() ); } /** * 線程安全 消費 html消息 * @param htmlEmailDTO */ @AllowConcurrentEvents @Subscribe public void sendHtmlMail(HtmlEmailDTO htmlEmailDTO){ try { emailService.sendHtmlMail( htmlEmailDTO.getTo(), htmlEmailDTO.getHtmlContent(), htmlEmailDTO.getSubject() ); } catch (MessagingException e) { // nothing to do } } /** * 線程安全 消費 圖文消息 * @param imgEmailDTO */ @AllowConcurrentEvents @Subscribe public void sendImgMail(ImgEmailDTO imgEmailDTO){ try { emailService.sendImgMail( imgEmailDTO.getTo(), imgEmailDTO.getImgContent(), imgEmailDTO.getSubject(), imgEmailDTO.getRscId(), imgEmailDTO.getImgPath() ); } catch (MessagingException e) { // nothing to do } } }
其實eventbus拋消息都是使用的post方法來拋消息。走到不同的方法里面是利用了類的多態,拋入不同的實體類就可以進行區分了。走進了不同的方法,就調用相應Service方法。
控制器與測試
控制器部分,沒什么好說的,我就貼出圖文的代碼。其余代碼可以在我的github上面看
先看眼實體類
@Data public class ImgEmailDTO implements Serializable { public ImgEmailDTO() { } /** * 圖片路徑 */ private String imgPath; /** * 資源id */ private String rscId; /** * 主題 */ private String subject; /** * 圖片正文(同樣可以使用html) */ private String imgContent; /** * 收件人 */ private String to; }
/** * 發送圖文郵件 * @param request * @return */ @RequestMapping(value = "/sendImgMail", method = RequestMethod.POST) public Result<Integer> sendImgMail(@RequestBody Request<ImgEmailDTO> request) { Result<Integer> result = Result.create(); ImgEmailDTO imgEmailDTO=request.getData(); StringBuilder sb=new StringBuilder(); sb.append(imgEmailDTO.getImgContent()); //cid:資源id。在spring中會自動綁定 sb.append("<img src=\'cid:").append(imgEmailDTO.getRscId()).append("\'></img>"); imgEmailDTO.setImgContent(sb.toString()); asyncEventBus.post(imgEmailDTO); return result.success(1); }
圖文要稍微特殊一點,需要拼接下正文內容。然后將實體類中的content替換。最后將實體類拋入隊列。直接返回接口請求。隊列那邊就會排著隊搞定所有的郵件
下面來做個測試
請求很迅速的返回了結果
然后去郵箱中查看結果
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Spring boot如何搭建郵件服務”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。