服务器之家

服务器之家 > 正文

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

时间:2021-05-17 14:17     来源/作者:funnyZpC

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

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

?
1
2
3
4
5
<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的版本(可不写,这里我略去):

?
1
2
3
4
<dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-mail</artifactid>
</dependency>

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
 mail:
  host: smtp.exmail.qq.com
  username: username@hostname.com
  password: 密码
  default-encoding: utf-8
  ssl:
  trust: smtp.exmail.qq.com
  properties:
  mail:
   smtp:
   auth: true #是否需要认证
   socketfactory:
    class: javax.net.ssl.sslsocketfactory #ssl证书socket工厂
    port: 465 #使用smtp465端口

配置参数的时候一定要注意缩进,因为我给的是yaml的配置格式,若是properties配置,大致是这样子(例子):spring.mail.host:smtp.exmail.qq.com,每一个子项都是完整的格式,一开始我是省略了properties项以下的配置(是否认真,ssl,端口),后来发现服务器将邮件的25端口封了,所以在本地可以但是在服务器就行不通了,所以需要指定邮件服务端口为465,我这里使用的是qq邮箱,如果使用163或其他邮箱需自行查阅服务商支持的端口,至于邮件安全问题,在这里需要声明两个,一个是ssl信任,以及mail的socket工厂,具体请见以上红色部分,以上配置仅对qq邮箱有效,不保证其他邮箱也适用。

  ok,配置完成,这里就开始写具体的实现类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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的压缩实现做讲解。

  先,需要引入依赖包:

?
1
2
3
4
5
6
<!--压缩:支持加密压缩-->
<dependency>
  <groupid>net.lingala.zip4j</groupid>
  <artifactid>zip4j</artifactid>
  <version>1.3.2</version>
 </dependency>

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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;
  }
 }
}

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

总结

以上所述是小编给大家介绍的springboot实现添加邮件发送及压缩功能 ,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

原文链接:https://www.cnblogs.com/funnyzpc/archive/2018/07/14/9190233.html

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部