springboot添加邮件发送及压缩功能

时间:2021-12-30 13:20:26
springboot添加邮件发送及文件压缩功能

转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9190233.html

  先来一段诗

```

  就这样吧

  忍受折磨

  然后,躺进医院

  然后,死去

  化作一抔土

  从此,这世界没有烦恼

  没有病痛

  没有我

  也没有这个世界

```

  以上是在半睡半醒中想到的,写的不好,读者可直接略过。

  这次本来只讲讲邮件发送功能的,惮于内容比较贫乏,故加了点儿文件压缩的功能讲解。

  首先邮件发送,邮件功能在springboot里面是有对应的依赖组件,这个:

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

邮件功能开发在springboot里面相当简单,这里我大致总结下开发内容:

    A>添加依赖包

    B>配置Mail基本参数(ymal或propertie里面)

    C>Service中注入JavaMailSender,调用相关方法即可

但是这里面可能会有个问题,就是在具体服务器部署的时候服务器会封堵邮件服务端口,以及普通邮件安全问题,这里讲解的时候我会顺道给出解决之道。

  首先,需要在工程的pom.xml中引入邮件组件,组件的版本需对应springboot的版本(可不写,这里我略去):

  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

  

  接下来就是在配置文件中配置邮件的基本参数:

 spring:
mail:
host: smtp.exmail.qq.com
username: username@hostname.com
password: 密码
default-encoding: UTF-8
7 ssl:
8 trust: smtp.exmail.qq.com
properties:
mail:
smtp:
auth: true #是否需要认证
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,配置完成,这里就开始写具体的实现类:

 import XXX.common.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service; import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.List;
import java.util.Map; @Service
public class MailService {
private static final Logger LOG = LoggerFactory.getLogger(MailService.class); @Value("${spring.mail.username}")
private String SEND_USER_ADDR; @Autowired
private JavaMailSender mailSender; /**
* 发送简单邮件
* @param receive 收件人
* @param obj 发送主题
* @param content 邮件内容
*/
public void sendSimpleMail(String receive,String obj,String content) {
if(!StringUtils.isNotBlank(content) || !StringUtils.isNotBlank(receive))
return;//不发送空邮件
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(SEND_USER_ADDR);
if(receive.contains(";"))
message.setTo(receive.split(";"));
else
message.setTo(receive);
message.setSubject(obj);
message.setText(content);
try {
mailSender.send(message);
LOG.info("Simple mail send success!");
} catch (Exception e) {
LOG.error("sendSimpleMail ERROR!", e);
} } private StringBuilder strBuilder;
/**
* 发送html邮件 多列表单的形式
* @param receive 收件人
* @param obj 发送主题(题目)
* @param content 邮件内容
*/
public void sendHtmlMailByList(String receive,String obj,List<Map> content){
if(content.isEmpty() || !StringUtils.isNotBlank(receive) || null==obj)
return;
MimeMessage msg = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8"); //解决乱码问题
helper.setFrom(SEND_USER_ADDR);
if(receive.contains(";"))
helper.setTo(receive.split(";"));
else
helper.setTo(receive);
helper.setSubject(obj);
strBuilder=new StringBuilder();
strBuilder.append("<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body style=\"padding:3% 2%;\">");
strBuilder.append("<h2>This message is automatically sent to the system.</h2>");
strBuilder.append("<h2>Send Date by "+DateUtil.getDateFormat(new Date(),DateUtil.DATETIME_DEFAULT_FORMAT) +"</h2>");
strBuilder.append("<h2>The following is the details:</h2>");
strBuilder.append("<table border=\"2px solid red\" width=\"100%\">"); //头
strBuilder.append("<thead style=\"background-color: #aea2e2;\">");
strBuilder.append("<tr>");
Object[] st=content.get(0).keySet().toArray();
for(int i=0;i<st.length;i++)
strBuilder.append("<th>"+st[i]+"</th>");
strBuilder.append("</tr>");
strBuilder.append("</thead>"); //体
strBuilder.append("<tbody>");
for(Map item:content){
strBuilder.append("<tr>");
for(Object str:st)
strBuilder.append("<td>"+item.get(str)+"</td>");
strBuilder.append("</tr>");
}
strBuilder.append("</tbody>"); strBuilder.append("</table>");
strBuilder.append("<h3 style=\"text-align:right\">Best wishes</h3>");
strBuilder.append("</body></html>");
//LOG.info(strBuilder.toString());
helper.setText(strBuilder.toString(),true);
}catch (Exception e){
LOG.error("sendHtmlMail ERROR:",e);
}
mailSender.send(msg);
} /**
* 发送html邮件 单列记录形式
* @param receive 收件人
* @param obj 发送主题(题目)
* @param content 邮件内容
*/
public void sendHtmlMailByItem(String receive,String obj,List<String> content){
if(content.isEmpty() || !StringUtils.isNotBlank(receive) || null==obj)
return;
MimeMessage msg = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8"); //解决乱码问题
helper.setFrom(SEND_USER_ADDR);
if(receive.contains(";"))
helper.setTo(receive.split(";"));
else
helper.setTo(receive);
helper.setSubject(obj);
strBuilder=new StringBuilder();
strBuilder.append("<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body style=\"padding:3% 2%;\">");
strBuilder.append("<h3>This message is automatically sent to the system.</h3>");
strBuilder.append("<h3>Send Date by "+DateUtil.getDateFormat(new Date(),DateUtil.DATETIME_DEFAULT_FORMAT) +"</h3>");
strBuilder.append("<h3>The following is the details:</h3>");
strBuilder.append("<table border=\"2px solid red\" width=\"100%\">"); //头
strBuilder.append("<thead style=\"background-color: #aea2e2;\">"); strBuilder.append("<th>"+obj.toUpperCase()+" DETAIL</th>");
strBuilder.append("</thead>"); //体
strBuilder.append("<tbody>");
for(String item:content){
strBuilder.append("<tr><td>"+item+"</td></tr>");
}
strBuilder.append("</tbody>"); strBuilder.append("</table>");
strBuilder.append("<h3 style=\"text-align:right;font-weight:normal;\">Best wishes</h3>");
strBuilder.append("</body></html>");
LOG.info(strBuilder.toString());
helper.setText(strBuilder.toString(),true);
}catch (Exception e){
LOG.error("sendHtmlMail ERROR:",e);
}
mailSender.send(msg);
}
}

以上我是将邮件功能封装成一个服务类,使用的时候只需要将当前类注入 然后直接调用即可,以上封装了两个方法:一个是简单邮件发送,一个是带html table的邮件,如果需要发送附件,需将附件放入到MimeMessageHelper里面(调用addAttachment("文件名", 文件))方法即可,这里因为无实际需求,遂就略去了,好了,邮件发送功能已经完成,这里看下实际效果:

springboot添加邮件发送及压缩功能

邮件功能实现完毕,现在我讲讲文件压缩功能,压缩功能的实现大致有四种,分别是:

  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的压缩实现做讲解。

  先,需要引入依赖包:

       <!--压缩:支持加密压缩-->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>

  再,封装一个压缩/解压缩工具类以方便使用:

 import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.springframework.util.StringUtils; import java.io.File; /**
* 本工具类使用Zip4j来进行压缩以及解压缩
*/
public class ZipUtil { //声明压缩对象
private static ZipParameters parameters; //解压文件对象
private static ZipFile zipFile; /**
*
* @param sourceFilePath 被压缩的文件的路径(单文件,文件夹)
* @param zipFilePath 压缩文件路径
* @param password 压缩密码
* @return 压缩成功:true ,压缩失败:false
*/
public static Boolean singleFileCompress(String sourceFilePath,String zipFilePath,String password){
parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // 压缩方式(默认方式)
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // 压缩级别(默认级别)
//压缩加密设置
if (!StringUtils.isEmpty(password)) {
parameters.setEncryptFiles(true);//是否设置文件加密(默认为否)
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); // 加密方式(此处是标准压缩)
parameters.setPassword(password.toCharArray());
}
try {
ZipFile zipFile = new ZipFile(zipFilePath);
//如果是文件则直接压缩,若是文件夹,遍历文件全部压缩
if(new File(sourceFilePath).isFile()) {
zipFile.setFileNameCharset("GBK");
zipFile.addFile(new File(sourceFilePath), parameters);
return true;
}
//File ff=new File(sourceFilePath);
File[] flst=new File(sourceFilePath).listFiles();
System.out.println("文件个数=>"+flst.length);
for(File f:flst){
zipFile.setFileNameCharset("GBK");
zipFile.addFile(f, parameters);
} return true;
} catch (ZipException e) {
e.printStackTrace();
return false;
}catch (Exception id){
id.printStackTrace();
return false;
}
}
public static Boolean unZip(String zipFile,String unZipDir){
try {
ZipUtil.zipFile = new ZipFile(zipFile);
ZipUtil.zipFile.setFileNameCharset("GBK");//设置编码格式
//用自带的方法检测一下zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等
if (!ZipUtil.zipFile.isValidZipFile()) {
throw new ZipException("文件不合法或不存在");
}
// 跟java自带相比,这里文件路径会自动生成,不用判断
ZipUtil.zipFile.extractAll(unZipDir);
return true;
}catch(ZipException e){
return false;
}
}

以上压缩方法自带密码压缩功能,可以压缩单文件也可以压缩目录文件,相对于原生的实现,一下子清爽了许多,这里唯一需要说明的是,压缩的目标文件在压缩前一定不能穿件,否则会报错!另外对于解压缩一定要注意文件编码和判断文件是否存在。

  OK,本章的功能已尽数分享,希望各位在开发功能的时候能避免这其中的

  现在是2018-07-14 22:16:12 ,各位晚安springboot添加邮件发送及压缩功能

springboot添加邮件发送及压缩功能的更多相关文章

  1. SpringBoot集成邮件发送

    一:简述 在日常中的工作中难免会遇到程序集成邮件发送功能.接收功能:此篇文章我将使用SpringBoot集成邮件发送功能和接收功能:若对邮件一些基本协议和发送流程不懂的请务必参考我之前写的博客或者浏览 ...

  2. 补习系列&lpar;12&rpar;-springboot 与邮件发送

    目录 一.邮件协议 关于数据传输 二.SpringBoot 与邮件 A. 添加依赖 B. 配置文件 C. 发送文本邮件 D.发送附件 E. 发送Html邮件 三.CID与图片 参考文档 一.邮件协议 ...

  3. SpringBoot整合邮件发送

    本节介绍SpringBoot项目如何快速配置和发送邮件,包括简单的邮件配置.发送简单邮件.发送HTML邮件.发送携带附件的邮件等. 示例源码在:https://github.com/laolunsi/ ...

  4. 补习系列&lpar;12&rpar;-springboot 与邮件发送【华为云技术分享】

    目录 一.邮件协议 关于数据传输 二.SpringBoot 与邮件 A. 添加依赖 B. 配置文件 C. 发送文本邮件 D.发送附件 E. 发送Html邮件 三.CID与图片 参考文档 一.邮件协议 ...

  5. springboot实现邮件发送

    1.创建springboot项目. 2.创建好的项目如图: 在static目录下新建index.html. 3.点击启动项目 在浏览器的地址栏中访问:http://localhost:8080/ 访问 ...

  6. springboot&plus;kafka&plus;邮件发送(最佳实践)

    导读 集成spring-kafka,生产者生产邮件message,消费者负责发送 引入线程池,多线程发送消息 多邮件服务器配置 定时任务生产消息:计划邮件发送 实现过程 导入依赖 <proper ...

  7. springboot 简单邮件发送

    写作原因: 项目接近尾声,需求一变再变,其实技术点从未改变,只是业务逻辑的变更,发送邮件提醒的功能,两个月变更七次.我想把技术点记录下来,这里无关乎业务,只有发送邮件的功能. 邮件发送准备说明: 由于 ...

  8. springboot做邮件发送功能时报错No qualifying bean of type &&num;39&semi;org&period;springframework&period;mail&period;javamail&period;JavaMailSender&&num;39&semi; available&colon;的问题解决方案

    1.检查application.yml中的配置是否正确 spring.mail.host=smtp.xxx.comspring.mail.username=xxx@xxx.comspring.mail ...

  9. SpringBoot 整合邮件oh-my-email 实现发送邮件功能

    导读 最近手头上要负责整个Message Gateway服务的搭建,涉及到:微信推送(点我直达).短信.邮件等等,到github上发现有个微型的开源邮件框架,整理下来,以备项目中使用到,到时候应该会使 ...

随机推荐

  1. 《Web开发中块级元素与行内元素的区分》

    一.块级元素的特性: 占据一整行,总是重起一行并且后面的元素也必须另起一行显示. HTML中块级元素列举如下: address(联系方式信息) article(文章内容) aside(伴随内容) au ...

  2. jdbc java数据库连接 6)类路径读取——JdbcUtil的配置文件

    之前的代码中,以下代码很多时候并不是固定的: private static String url = "jdbc:mysql://localhost:3306/day1029?useUnic ...

  3. Java--笔记(4)

    31.中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源.中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯.是连接两个独立应用程序或独立系统的软 ...

  4. 理解jar

    对于大多数 Java 开发人员来说,JAR 文件及其 “近亲” WAR 和 EAR 都只不过是漫长的 Ant 或 Maven 流程的最终结果.标准步骤是将一个 JAR 复制到服务器(或者,少数情况下是 ...

  5. Python学习教程&lpar;learning Python&rpar;--3&period;3&period;4 Python的if-elif-else语句

    Python的if-elif-else语句用于多种条件判断后选择某个语句块执行.该语句可以利用一系列条件表达式进行检查,并在某个表达式为真的情况下执行相应的代码.需要注意的是,虽然if/elif/el ...

  6. CORREL

    CORREL Show All Returns the correlation coefficient of the array1 and array2 cell ranges. Use the co ...

  7. 基于粒子滤波的物体跟踪 Particle Filter Object Tracking

    Video来源地址 一直都觉得粒子滤波是个挺牛的东西,每次试图看文献都被复杂的数学符号搞得看不下去.一个偶然的机会发现了Rob Hess(http://web.engr.oregonstate.edu ...

  8. ●POJ 2794 Double Patience

    题链: http://poj.org/problem?id=2794题解: 状压DP,概率 9元组表示每一堆还剩几张牌.可以用5进制状压,共5^9=1953124个状态. 令P(S)表示S这个状态被取 ...

  9. Coroutine协同程序介绍(Unity3D开发之三)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=496 Coroutine在Uni ...

  10. 使用Js进行linq处理

    需要引用的文件 <script src="~/js/linq/jquery.linq-vsdoc.js"></script><script src=& ...