springboot添加郵件發送及壓縮功能

来源:https://www.cnblogs.com/funnyzpc/archive/2018/07/14/9190233.html
-Advertisement-
Play Games

轉載請註明出處:https://www.cnblogs.com/funnyzpc/p/9190233.html 先來一段詩 ``` 就這樣吧 忍受折磨 然後,躺進醫院 然後,死去 化作一抔土 從此,這世界沒有煩惱 沒有病痛 沒有我 也沒有這個世界 ``` 以上是在半睡半醒中想到的,寫的不好,讀者可直 ...


springboot添加郵件發送及文件壓縮功能

轉載請註明出處https://www.cnblogs.com/funnyzpc/p/9190233.html

  先來一段詩

```

  就這樣吧

  忍受折磨

  然後,躺進醫院

  然後,死去

  化作一抔土

  從此,這世界沒有煩惱

  沒有病痛

  沒有我

  也沒有這個世界

```

  以上是在半睡半醒中想到的,寫的不好,讀者可直接略過。

  這次本來只講講郵件發送功能的,憚於內容比較貧乏,故加了點兒文件壓縮的功能講解。

  首先郵件發送,郵件功能在springboot裡面是有對應的依賴組件,這個:

1 <dependency>
2     <groupId>org.springframework.boot</groupId>
3     <artifactId>spring-boot-starter-mail</artifactId>
4 </dependency>

郵件功能開發在springboot裡面相當簡單,這裡我大致總結下開發內容:

    A>添加依賴包

    B>配置Mail基本參數(ymal或propertie裡面)

    C>Service中註入JavaMailSender,調用相關方法即可

但是這裡面可能會有個問題,就是在具體伺服器部署的時候伺服器會封堵郵件服務埠,以及普通郵件安全問題,這裡講解的時候我會順道給出解決之道。

  首先,需要在工程的pom.xml中引入郵件組件,組件的版本需對應springboot的版本(可不寫,這裡我略去):

1  <dependency>
2      <groupId>org.springframework.boot</groupId>
3      <artifactId>spring-boot-starter-mail</artifactId>
4  </dependency>

  

  接下來就是在配置文件中配置郵件的基本參數:

 1 spring:
 2     mail:
 3       host: smtp.exmail.qq.com
 4       username: [email protected]
 5       password: 密碼
 6       default-encoding: UTF-8
 7       ssl:
 8         trust: smtp.exmail.qq.com
 9       properties:
10         mail:
11           smtp:
12             auth: true  #是否需要認證
13             socketFactory:
14               class: javax.net.ssl.SSLSocketFactory #SSL證書Socket工廠
15               port: 465 #使用SMTP465埠

  

配置參數的時候一定要註意縮進,因為我給的是yaml的配置格式,若是properties配置,大致是這樣子(例子):spring.mail.host:smtp.exmail.qq.com,每一個子項都是完整的格式,一開始我是省略了properties項以下的配置(是否認真,SSL,埠),後來發現伺服器將郵件的25埠封了,所以在本地可以但是在伺服器就行不通了,所以需要指定郵件服務埠為465,我這裡使用的是qq郵箱,如果使用163或其他郵箱需自行查閱服務商支持的埠,至於郵件安全問題,在這裡需要聲明兩個,一個是ssl信任,以及mail的socket工廠,具體請見以上紅色部分,以上配置僅對qq郵箱有效,不保證其他郵箱也適用。

  ok,配置完成,這裡就開始寫具體的實現類:

  1 import XXX.common.util.DateUtil;
  2 import org.apache.commons.lang3.StringUtils;
  3 import org.slf4j.Logger;
  4 import org.slf4j.LoggerFactory;
  5 import org.springframework.beans.factory.annotation.Autowired;
  6 import org.springframework.beans.factory.annotation.Value;
  7 import org.springframework.mail.SimpleMailMessage;
  8 import org.springframework.mail.javamail.JavaMailSender;
  9 import org.springframework.mail.javamail.MimeMessageHelper;
 10 import org.springframework.stereotype.Service;
 11 
 12 import javax.mail.internet.MimeMessage;
 13 import java.util.Date;
 14 import java.util.List;
 15 import java.util.Map;
 16 
 17 @Service
 18 public class MailService {
 19     private static final Logger LOG = LoggerFactory.getLogger(MailService.class);
 20 
 21     @Value("${spring.mail.username}")
 22     private String SEND_USER_ADDR;
 23 
 24     @Autowired
 25     private JavaMailSender mailSender;
 26 
 27     /**
 28      *      發送簡單郵件
 29      * @param receive   收件人
 30      * @param obj       發送主題
 31      * @param content   郵件內容
 32      */
 33     public void sendSimpleMail(String receive,String obj,String content) {
 34         if(!StringUtils.isNotBlank(content) || !StringUtils.isNotBlank(receive))
 35             return;//不發送空郵件
 36         SimpleMailMessage message = new SimpleMailMessage();
 37         message.setFrom(SEND_USER_ADDR);
 38         if(receive.contains(";"))
 39             message.setTo(receive.split(";"));
 40         else
 41             message.setTo(receive);
 42         message.setSubject(obj);
 43         message.setText(content);
 44         try {
 45             mailSender.send(message);
 46             LOG.info("Simple mail send success!");
 47         } catch (Exception e) {
 48             LOG.error("sendSimpleMail ERROR!", e);
 49         }
 50 
 51     }
 52 
 53     private StringBuilder strBuilder;
 54     /**
 55      *  發送html郵件 多列表單的形式
 56      * @param receive   收件人
 57      * @param obj       發送主題(題目)
 58      * @param content   郵件內容
 59      */
 60     public void sendHtmlMailByList(String receive,String obj,List<Map> content){
 61             if(content.isEmpty() || !StringUtils.isNotBlank(receive) || null==obj)
 62                 return;
 63             MimeMessage msg = mailSender.createMimeMessage();
 64             try {
 65                 MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8"); //解決亂碼問題
 66                 helper.setFrom(SEND_USER_ADDR);
 67                 if(receive.contains(";"))
 68                     helper.setTo(receive.split(";"));
 69                 else
 70                     helper.setTo(receive);
 71                 helper.setSubject(obj);
 72                 strBuilder=new StringBuilder();
 73                 strBuilder.append("<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body style=\"padding:3% 2%;\">");
 74                 strBuilder.append("<h2>This message is automatically sent to the system.</h2>");
 75                 strBuilder.append("<h2>Send Date by "+DateUtil.getDateFormat(new Date(),DateUtil.DATETIME_DEFAULT_FORMAT) +"</h2>");
 76                 strBuilder.append("<h2>The following is the details:</h2>");
 77                 strBuilder.append("<table border=\"2px solid red\" width=\"100%\">");
 78 
 79                 //
 80                 strBuilder.append("<thead style=\"background-color: #aea2e2;\">");
 81                 strBuilder.append("<tr>");
 82                 Object[] st=content.get(0).keySet().toArray();
 83                 for(int i=0;i<st.length;i++)
 84                     strBuilder.append("<th>"+st[i]+"</th>");
 85                 strBuilder.append("</tr>");
 86                 strBuilder.append("</thead>");
 87 
 88                 //
 89                 strBuilder.append("<tbody>");
 90                 for(Map item:content){
 91                     strBuilder.append("<tr>");
 92                     for(Object str:st)
 93                         strBuilder.append("<td>"+item.get(str)+"</td>");
 94                     strBuilder.append("</tr>");
 95                 }
 96                 strBuilder.append("</tbody>");
 97 
 98                 strBuilder.append("</table>");
 99                 strBuilder.append("<h3 style=\"text-align:right\">Best wishes</h3>");
100                 strBuilder.append("</body></html>");
101                 //LOG.info(strBuilder.toString());
102                 helper.setText(strBuilder.toString(),true);
103             }catch (Exception e){
104                 LOG.error("sendHtmlMail ERROR:",e);
105             }
106             mailSender.send(msg);
107         }
108 
109 
110     /**
111      *  發送html郵件 單列記錄形式
112      * @param receive   收件人
113      * @param obj       發送主題(題目)
114      * @param content   郵件內容
115      */
116     public void sendHtmlMailByItem(String receive,String obj,List<String> content){
117         if(content.isEmpty() || !StringUtils.isNotBlank(receive) || null==obj)
118             return;
119         MimeMessage msg = mailSender.createMimeMessage();
120         try {
121             MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8"); //解決亂碼問題
122             helper.setFrom(SEND_USER_ADDR);
123             if(receive.contains(";"))
124                 helper.setTo(receive.split(";"));
125             else
126                 helper.setTo(receive);
127             helper.setSubject(obj);
128             strBuilder=new StringBuilder();
129             strBuilder.append("<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body style=\"padding:3% 2%;\">");
130             strBuilder.append("<h3>This message is automatically sent to the system.</h3>");
131             strBuilder.append("<h3>Send Date by "+DateUtil.getDateFormat(new Date(),DateUtil.DATETIME_DEFAULT_FORMAT) +"</h3>");
132             strBuilder.append("<h3>The following is the details:</h3>");
133             strBuilder.append("<table border=\"2px solid red\" width=\"100%\">");
134 
135             //
136             strBuilder.append("<thead style=\"background-color: #aea2e2;\">");
137 
138             strBuilder.append("<th>"+obj.toUpperCase()+" DETAIL</th>");
139             strBuilder.append("</thead>");
140 
141             //
142             strBuilder.append("<tbody>");
143             for(String item:content){
144                 strBuilder.append("<tr><td>"+item+"</td></tr>");
145             }
146             strBuilder.append("</tbody>");
147 
148             strBuilder.append("</table>");
149             strBuilder.append("<h3 style=\"text-align:right;font-weight:normal;\">Best wishes</h3>");
150             strBuilder.append("</body></html>");
151             LOG.info(strBuilder.toString());
152             helper.setText(strBuilder.toString(),true);
153         }catch (Exception e){
154             LOG.error("sendHtmlMail ERROR:",e);
155         }
156         mailSender.send(msg);
157     }
158 }

以上我是將郵件功能封裝成一個服務類,使用的時候只需要將當前類註入 然後直接調用即可,以上封裝了兩個方法:一個是簡單郵件發送,一個是帶html table的郵件,如果需要發送附件,需將附件放入到MimeMessageHelper裡面(調用addAttachment("文件名", 文件))方法即可,這裡因為無實際需求,遂就略去了,好了,郵件發送功能已經完成,這裡看下實際效果:

郵件功能實現完畢,現在我講講文件壓縮功能,壓縮功能的實現大致有四種,分別是:

  A>利用java.util.zip提供的api壓縮

  B>利用apache的ant包提供的api壓縮(org.apache.tools.ant.taskdefs.Zip)

  C>使用zip4j提供的api壓縮(net.lingala.zip4j)

  D>調用宿主機的shell命令壓縮

這裡需要特別提到三個問題:

  A>普通郵件壓縮中文亂碼(不支持中文)

  B>壓縮後無法解壓(解壓錯誤)

  C>文件壓縮添加壓縮密碼問題

實際開發過壓縮功能,以上三點兒對於新手來說尤其的頭痛,這裡我分享下以前在開發壓縮功能中碰到的問題。

  使用原生java.util包提供的壓縮,如果被壓縮文件使用到中文,則會亂碼(據說是jdk的一個bug),而且壓縮實現的代碼較為複雜(尤其是設置密碼),尤其是對於跨目錄壓縮和多文件壓縮尤其麻煩。

  使用apache提供的zip工具雖避免了以上會出現的問題,但是需要提醒一點兒的是這個ant包與webLogic衝突(部署的時候會報錯)且無法實現壓縮設置密碼,如果使用的是webLogic而不是tomocat的情況下,一定要註意到這個問題。

  使用java調用宿主機的shell命令也是個不錯的選擇,但是,需要編寫shell命令,同時對於部署在windows平臺就不太友好了,移植比較麻煩

  最後,對於以上問題,我這裡推薦zip4j,以下也是針對zip4j的壓縮實現做講解。

  先,需要引入依賴包

1       <!--壓縮:支持加密壓縮-->
2         <dependency>
3             <groupId>net.lingala.zip4j</groupId>
4             <artifactId>zip4j</artifactId>
5             <version>1.3.2</version>
6         </dependency>

  再,封裝一個壓縮/解壓縮工具類以方便使用

 1 import net.lingala.zip4j.core.ZipFile;
 2 import net.lingala.zip4j.exception.ZipException;
 3 import net.lingala.zip4j.model.ZipParameters;
 4 import net.lingala.zip4j.util.Zip4jConstants;
 5 import org.springframework.util.StringUtils;
 6 
 7 import java.io.File;
 8 
 9 
10 /**
11  * 本工具類使用Zip4j來進行壓縮以及解壓縮
12  */
13 public class ZipUtil {
14 
15     //聲明壓縮對象
16     private static ZipParameters parameters;
17 
18     //解壓文件對象
19     private static ZipFile zipFile;
20 
21     /**
22      *
23      * @param sourceFilePath    被壓縮的文件的路徑(單文件,文件夾)
24      * @param zipFilePath       壓縮文件路徑
25      * @param password          壓縮密碼
26      * @return                  壓縮成功:true ,壓縮失敗:false
27      */
28     public static Boolean singleFileCompress(String sourceFilePath,String zipFilePath,String password){
29         parameters = new ZipParameters();
30         parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // 壓縮方式(預設方式)
31         parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // 壓縮級別(預設級別)
32         //壓縮加密設置
33         if (!StringUtils.isEmpty(password)) {
34             parameters.setEncryptFiles(true);//是否設置文件加密(預設為否)
35             parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); // 加密方式(此處是標準壓縮)
36             parameters.setPassword(password.toCharArray());
37         }
38         try {
39             ZipFile zipFile = new ZipFile(zipFilePath);
40             //如果是文件則直接壓縮,若是文件夾,遍歷文件全部壓縮
41             if(new File(sourceFilePath).isFile()) {
42                 zipFile.setFileNameCharset("GBK");
43                 zipFile.addFile(new File(sourceFilePath), parameters);
44                 return true;
45             }
46             //File ff=new File(sourceFilePath);
47             File[] flst=new File(sourceFilePath).listFiles();
48             System.out.println("文件個數=>"+flst.length);
49             for(File f:flst){
50                 zipFile.setFileNameCharset("GBK");
51                 zipFile.addFile(f, parameters);
52             }
53 
54             return true;
55         } catch (ZipException e) {
56             e.printStackTrace();
57             return false;
58         }catch (Exception id){
59             id.printStackTrace();
60             return false;
61         }
62     }
63     public static Boolean unZip(String zipFile,String unZipDir){
64         try {
65             ZipUtil.zipFile = new ZipFile(zipFile);
66             ZipUtil.zipFile.setFileNameCharset("GBK");//設置編碼格式
67             //用自帶的方法檢測一下zip文件是否合法,包括文件是否存在、是否為zip文件、是否被損壞等
68             if (!ZipUtil.zipFile.isValidZipFile()) {
69                 throw new ZipException("文件不合法或不存在");
70             }
71             // 跟java自帶相比,這裡文件路徑會自動生成,不用判斷
72             ZipUtil.zipFile.extractAll(unZipDir);
73             return true;
74         }catch(ZipException e){
75             return false;
76         }
77     }
78

 

以上壓縮方法自帶密碼壓縮功能,可以壓縮單文件也可以壓縮目錄文件,相對於原生的實現,一下子清爽了許多,這裡唯一需要說明的是,壓縮的目標文件在壓縮前一定不能穿件,否則會報錯!另外對於解壓縮一定要註意文件編碼和判斷文件是否存在。

  OK,本章的功能已盡數分享,希望各位在開發功能的時候能避免這其中的

  現在是2018-07-14 22:16:12 ,各位晚安


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Spring Security是什麼 Spring Security是一個能夠為基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean(註:包括認證與許可權獲取、配置、處理相關實例),充分利用了Spring IoC,DI(控制 ...
  • 本文內容: Listener Filter 首發日期:2018-07-15 Listener 監聽器Listener負責監聽事件的發生。我們能在事件發生後執行一些自定義的操作,這就是監聽器的意義。 監聽器的本質是介面回調。 分類: 監聽域對象的創建:監聽三個域(request,session,con... ...
  • 關於環境變數的配置,在百度上有很多教程,但對於我來說完成這步操作確實不簡單,所以決定在這裡分享一下配置方法。 1.安裝好jdk/jre。 官網都有安裝文件,仔細一些,就能安裝成功,可以自定義安裝路徑,但是要註意安裝時候不能有中文路徑,否則會報錯。 2.打開此電腦,選擇屬性。 3.選擇高級系統設置。 ...
  • 剛開始接觸這個概念的時候真的是完全不夠理解什麼叫做面向對象,即使到了現在人就是不能夠完全可以說明白。 程式員之路的設計理念分為:面向過程和麵向對象; 面向過程:要想得到一個結果需要一步一步的去設計出來,一步一步的敲代碼去實現這是一個過程。 比如說要比較兩個數的大小有以下程式: int a=3; in ...
  • 一,五大核心組件 1.DispatcherServlet 請求入口 2.HandlerMapping 請求派發,負責請求和控制器建立一一對應的關係 3.Controller 處理器 4.ModelAndView 封裝模型信息和視圖信息 5.ViewResolver 視圖處理器,定位頁面 二,Spri ...
  • JavaDay04總結 1、實現介面VS繼承類 : 1. 實現介面是繼承的補充 2. 實現介面可以在不打破繼承關係的前提下,對某個功能擴展 2、綁定 : 1. 前期綁定:在程式運行前進行綁定,由編譯器和連接程式實現,又叫靜態綁定 2. 後期綁定:在運行時根據對象的類型進行綁定,由方法調用機制實現,又 ...
  • 跟昨天那個自己寫的,沒有按照模板來的一看風格就不相類似,今天模擬賽的時候就是用的我的那個自己YY的代碼,才拿了10分。個人認為關鍵的問題應該在於對於數據的處理太過繁瑣了,所以回來之後,就拿了大佬的程式對照著改。在這裡不得不吐槽一下c++的讀入,cin40分,scanf滿分。還是模板的線段樹比較清晰, ...
  • 在Spring中通過註解@EnableScheduling 來開啟對計劃任務的支持,然後再執行集合任務的方法上註解@Scheduled,聲明這是一個計劃任務。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...