From 518c105a13ef15131c1b750abff92423b34660c9 Mon Sep 17 00:00:00 2001 From: cicadasmile <1327880701@qq.com> Date: Tue, 11 Jun 2019 21:30:00 +0800 Subject: [PATCH] =?UTF-8?q?SpringBoot2.0=20=E6=95=B4=E5=90=88=20JavaMail?= =?UTF-8?q?=20,=E5=AE=9E=E7=8E=B0=E5=BC=82=E6=AD=A5=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 27 +++ pom.xml | 218 ++++++++++++++++++ ware-email-send/pom.xml | 57 +++++ ware-email-send/src/gzh.jpg | Bin 0 -> 24793 bytes ware-email-send/src/gzh.zip | Bin 0 -> 22227 bytes .../java/com/email/send/EmailApplication.java | 13 ++ .../send/controller/EmailController.java | 28 +++ .../com/email/send/model/SendEmailModel.java | 26 +++ .../java/com/email/send/param/BodyType.java | 41 ++++ .../java/com/email/send/param/EmailParam.java | 34 +++ .../java/com/email/send/param/EmailType.java | 44 ++++ .../com/email/send/service/EmailService.java | 7 + .../send/service/impl/EmailServiceImpl.java | 33 +++ .../java/com/email/send/util/EmailUtil.java | 160 +++++++++++++ .../com/email/send/util/TaskPoolConfig.java | 39 ++++ .../src/main/resources/application.yml | 21 ++ 16 files changed, 748 insertions(+) create mode 100644 README.md create mode 100644 pom.xml create mode 100644 ware-email-send/pom.xml create mode 100644 ware-email-send/src/gzh.jpg create mode 100644 ware-email-send/src/gzh.zip create mode 100644 ware-email-send/src/main/java/com/email/send/EmailApplication.java create mode 100644 ware-email-send/src/main/java/com/email/send/controller/EmailController.java create mode 100644 ware-email-send/src/main/java/com/email/send/model/SendEmailModel.java create mode 100644 ware-email-send/src/main/java/com/email/send/param/BodyType.java create mode 100644 ware-email-send/src/main/java/com/email/send/param/EmailParam.java create mode 100644 ware-email-send/src/main/java/com/email/send/param/EmailType.java create mode 100644 ware-email-send/src/main/java/com/email/send/service/EmailService.java create mode 100644 ware-email-send/src/main/java/com/email/send/service/impl/EmailServiceImpl.java create mode 100644 ware-email-send/src/main/java/com/email/send/util/EmailUtil.java create mode 100644 ware-email-send/src/main/java/com/email/send/util/TaskPoolConfig.java create mode 100644 ware-email-send/src/main/resources/application.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..1b08aaa --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +## 参考文章 + + +1、SpringBoot2.0 整合 shard-jdbc 中间件,实现数据分库分表
+ + +2、SpringBoot2.0 整合 JavaMail ,实现异步发送邮件功能
+ + +3、SpringBoot2.0 整合 RocketMQ ,实现请求异步处理
+ + +4、SpringBoot2.0 整合 Swagger2 ,构建接口管理界面
+ + +5、SpringBoot2.0 整合 QuartJob ,实现定时器实时管理
+ +## 项目简介 +SpringBoot 集成常用中间件 + +SpringBoot集成常用开发中间件,分库分表,缓存,消息队列,定时器,权限管理等组件 + +# 我的公众号 +关注公众号:知了一笑
+ + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e66d22a --- /dev/null +++ b/pom.xml @@ -0,0 +1,218 @@ + + + + + org.springframework.boot + spring-boot-starters + 2.1.3.RELEASE + + + 4.0.0 + com.boot.parent + middle-ware-parent + 1.0-SNAPSHOT + pom + + + + + ware-quart-job + + ware-rocket-queue + + ware-shard-jdbc + + + + ware-email-send + + ware-swagger-two + + + + + UTF-8 + UTF-8 + 1.8 + 2.1.3.RELEASE + 5.1.5.RELEASE + 3.0.7.1 + 5.1.38 + 4.0 + 1.1.13 + 2.3.0 + 2.6 + 1.2.2 + 2.5 + 1.10 + 1.10 + 2.6.1 + 2.9.9 + 1.2.47 + 4.1.1 + 1.18.4 + 1.2.5 + 1.0.3 + 3.8.1 + 4.3.0 + 3.1.0 + 2.9.1 + 1.5.0-b01 + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework + spring-context-support + + + org.springframework.boot + spring-boot-configuration-processor + true + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + com.baomidou + mybatis-plus-generator + + + + + com.baomidou + mybatis-plus + ${mybatisplus.version} + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.version} + + + mysql + mysql-connector-java + ${mysql.version} + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + org.quartz-scheduler + quartz + ${quartz.version} + + + com.mchange + c3p0 + + + + + commons-lang + commons-lang + ${commons.lang.version} + + + commons-fileupload + commons-fileupload + ${commons.fileupload.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + joda-time + joda-time + ${joda.time.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + cn.hutool + hutool-all + ${hutool.version} + + + org.projectlombok + lombok + ${lombok.version} + + + tool + common-util + ${common-util.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/ware-email-send/pom.xml b/ware-email-send/pom.xml new file mode 100644 index 0000000..e6e2de8 --- /dev/null +++ b/ware-email-send/pom.xml @@ -0,0 +1,57 @@ + + + + middle-ware-parent + com.boot.parent + 1.0-SNAPSHOT + + 4.0.0 + + com.email.send + ware-email-send + jar + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + org.springframework.boot + spring-boot-starter-aop + ${spring-boot.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring-boot.version} + true + + + org.springframework + spring-context-support + ${spring.version} + + + joda-time + joda-time + ${joda.time.version} + + + + javax.mail + mail + ${mail.version} + + + + \ No newline at end of file diff --git a/ware-email-send/src/gzh.jpg b/ware-email-send/src/gzh.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df52b1285c61fbc4c264b5f7c286a08a86c174e3 GIT binary patch literal 24793 zcmd?Q2{_d6`!7DSX5Yy+$y!2WNtQ`MDv64$Q%UxwNCsnugzO=NYD7|5CbDm1mnd1X zGiD~c$qX99EdKA$cRSzT?{}_qopb)zxvq0vXLzo;nD_gc=YBuWbHDEUb-$kdiT!zy z@C7RyD-atS8|WtR1KOVkS%BCN9Qf-OcyR!~oIISI92}gy+}vC|{Ji}9e7t;o0)nE# z0)irfe0;)^!Xjeg5)u;pLQ>L_;?knx65@Y#!p08V!@+rwlk=ds0H1*P|MF|U4J5+D zX31v3&UOTJK!lB5gl)eI1O|cFIDygrHQ;}|*bV?=;0-u98L^wqib~C=&c_6MEo&JVL>1<`Ygu@V7`Q+`O#|L>OrKAtZsHm!` zA3dh0Z(w-J=(NQ-ODpU1HW#j5yYA?8!`a32j@MmpA78)Vharzb;bGx1Ph#WZpC%+` zWIoTz&UulWS6KA6_+82S45#Vn=kNdBo4Azo~3LsC3eSEO9$%h*wfs53fS`%e22)_CIIXIe^g%D2jTfDS@T6K;U@5J-evXT z2NVD0e}#BY^gnJ(qn%wx)oTt6f8+nj z?u!5Un3oIjxA|nH*KchS@AVDG?0^0>a?`mm@tD=EzMbss47=v) z>WOp<4+>W_1O7vV)tTSKH$CVc4b8K_6wiH-%z=HJ^}x%VdgxlOS>Y-u)US*? zlDcFX-Fpf%h!vXg6JEyhuj8(bz8(D|pu2VX^ROpHppr1H0r^lL#%1WoM=jU#~=eLjExlnYlmp9g)BsE|7v^d9n*4@EG0>y%x-J)|_>c{DKN+Vq(jOs-HJR%zt?^+M zeWH`gk2tSaV4jAY*-&>+YPg-7+bi2edMAk%#NJq*07=|Aj4f%G=RNBRyAaEEeyCtoD*3E{K**I_~aIhY9%ES1_ zh@)K#mX8&VK)Z|JhW9}!t>OM9AtP5;pzMq*WK36D?LMgEWV!3=KIpc(mPu6S*W(A> zehJn?vO@H?!0SbVb>I|)ul#lu-+RlCenYEcIcS(KuTIR)XPg`24WHNjQ(l;oV{bER z5|Zxi@TwQSEhtP>2mLQLHmMEBF3BYv#Ryj$-3Og?PTD~;sO6>*mZ{h(D!1f^`$au_ zOT`yKkqgDe6T{~diOTTi@WEv+7F?g~ztM+s?CE5n!xH}BOv z%@(loyjNU7ygngnk(PUw64Pz$K)xJZ26ttNl+Mb0UFu{xm@{*gc>@{MhYQzxP8d{h z2k|dgaELc7K0V zW`Dc)5|8=^*1z|{#wh{$+aT5d{uDswmjB^~Gs5;)nTfF9$ilQrTjt>C6%O%hz;gNP zQ5CIUMFsy6|G%;aCus9NXsO0`WgkRYMqg!o^A7O&6>{q_q@(&F05RKkA6R$M<{`(2 zEXCuzT=qe|zo2QG`lZf}Sjw&xk&)sza@*We+(FvjQXKUEv$17`?1R9;Nbr~I-~O?v zKZZgnJBD~htlP*wh&W_cvYQvlIry6}`!c~0%%_i-0cfMaVy51vuO3CCosyZ~yOx(kFY9G}7>ZC1{3!bOiPz4qI zs#Wn&->r5s3+exqQETOUo8#!9w341l2w~QafLW&$!6Q0wLa=620_>^NN#Cg_uwp%7 z-yq3-kX?OlVk&QfL7mg!`y=(&N6n6bC6`-|*Hz_r=c#pwnB|0+xL8csRrD%_IUV7V z+x*e?)JB?r_3W=8U@mh~_xv|&YIfaw=e9OO2iGyWywH`hmw-I=+ zxMft60siQ-IDGzxbWY?*R^XB;H<_N;O=HsaeIUa30Mzl_bXhjIva-2)y1Syr^ZliJ z&pPt?raMhwvge*6&$SO;c`%s68dNw)j!$hh@O8{{OeuorcaA-(@{>9}ms{+g=kvKC zWuz}H}1BrydO ztJ&i&-=7^Zq}sRMsoN5-j))IzyW{vXXixA>=?r|jt9BeIo_1llz!g=w)*mXK^3m(y z{oD4fkmC%jkO7F!5%54S}Z3?wFLloP>L~YHw(Ietv8^&Vxy*%=n&|+b{oie)|Jzz92_z zlJ%`I6Y7f(FI&CqS|rSV`p>S@g>D!CEwv4)Xj57s)wqoFY8QXNqgj(XdzIy~UnxfyDSq@i# z#65$fu8e5HBq74DEJ!xW&q}`tWo?r9FB=of5jBQ!%@*Wpc)wLO&HDYyXLrWwhLL-u zYS-BMnncgwQ~t$aD#tzVvp+d>U-tJ7#LW*ZR*iXrW_jy9NaP=r#FXsyxxlQ^6J1dus1@vo-Z3xn&;|2e}L8 z@OA0QH_JiPR#lJX=)8FAzIDDc=%w(5PbOR6JRuCRoq4&`fw=?yI(?97nRvjNl^@fx zi7+LNV;O>7?OPR*n328Ja9lS`($9>W7Fw|uZk4H8_hHI4yS6GNEA-3x>&FMq@Vx!) zIe9$=5oSm-q9pcqs-0<}NJRxQuH+2*O?BmbYO7S%STY$7OIgqhR-GW;Vb2H+Jkk>3 z!OTHQFa*d>iOrUHQ)8BJY0rqq*qY;}R!v)W+45bh&so2muV+0%=S0~o3n1Q`aU(2S z#vpje4~7am?V>HT>KGWblAV{eu04<=yb|%KzxrdK?uj7T1-aT2^vi>F{dN5)6l4OuzUDK|6MZk|_W$HHR*3PP4)dS6Bd4<^Rt?RcurNXJJNm6tDW* z*)x2WhmDGXuRp5J=JS?cKocZxZ~6D;z{T~r?aBcFkpFvt`+opLJr2euO-+Tx-yl zq8+OT5ndTPr(gcAw8SEqpF``1y|RPU0x^0d5ya4A0^a7{(S49NI57|Vlo1g|NR#%J z3P0Y6FwpVH9SGJVpI4sNi?)(fJ0!=zxiI?x2tF`KsOv=W!w2nZUw`j}juea*)HO~o z_GA=JAJ(d2x9UF(m(l?d7+18K-(P#h$%! z;?VwjLdg7#0+ABjj?`lUtHsAo9691~jN-Nj1oqOuXQevA1Amc%u)gLng(H~(5RFfs zTMy-ep?45$w4q|w4=fJ@LgBWmY#w>|&FijDAgng5Z(&eb?a{EcsxI7=2a{j654wX( zY(31Z)E|_B6T7k%G-!$urd{c@lh;Nov;%u?O$!EiCAUA%= zTfJye20M{BkBXV{o|NhBV9Acd^e8?Rhoie3pMC7eFA04{y7g+HH^UNye9rKpeJEjw z&|C?2@_w~BhI^0V{iz?y%c#3mTJtBGo*r6izyMQ(r=s~F%a)XQ<`&>UdP^5DF}SKh zk}chhAsgRS3zqV3C1-ycaW%^)XiKbWERK4XGB)m)HmWmOgxL%liq0!%({I8z}7Z8zA!ZA%lC$&6e}~^0v@g zPHm5u)h$ta8FYI5tA{qwX%|Ceyji7uC3{ah#gRb$8sRgL7xL-Kpsc!bQf7}W=q9RN z65(D!``n3=$afp7k@uQ!8hK*--rdG1S-k%H>@VUedDCNHnxCE*?>Og9bH|t3JO3!~jRAWSv3~JzY zv+8e>O+7iHHio@~oo|3_a?_0WLGFKGOs?T5qevyz!Dza*zl?1b10|>FVEkS*#A!_b zc+^*E_RWyRa$sSWqI|)7T8=2%sZlH~aa)^q4AljbL>MvAEFpKeUAN45oYp;WkwJr$ z_qINp@2edok^_q4!rCzdY5yIsR*dz7{N+{GOUPr|GVpl7tF}DJq4*MTm;Umqn;M^B zFV)*N2ayEqHSDd~3mZ3>=`2YP+^lUxm_d?Q|APmL88)(N*|&r2##;56jWzzH2-ZO; zIn-fvLrY)YilWDtl;7Xr;`}bXO!@flb(_1&88$}B;}eiiP)6=}2b9j%$(V{V{rzvS z_!mU}5211KU*y}eR&kzs;j@8KD2iLt%z>OFejtqNRo8-pVc2U14vWXp4uoXu?IgZDsiv` zAw2g%92?}j#S~fA!6FKzBTu(yueHvguEe=)u#$gx^4!xyO#%Z(m@E|j2ew+9$<8nZ zwg`Y61b-~eiGG4LhvGo!&MA;hg5VLB{_%|l*?X(3 zeUN$nAVX#u$V|^D?9$m;{m9eI>{f2Z)#2t4&Sa_ZBGaFrDjUT9JinNy!N8|=TOaiu40il{Q za$qmC>uIavvi)+EzwXM$9i`UCO9LW&QTw3PSGB}}%k|&k1wvoIAchYG*FI};J-=Py z_)mnU=I+6Vd+z;b@ABMu9}v>B*gHBtij~(#P4iJh$#(IG>qMc%ycw6v&1>?R&TAVd zGd#Dr7Ua!b_JpXiz&`YHU*5x|++h}&$xX~o+R9_8hWQ_qCnAS;CnPt2-S?#9;=?J} zCy?rm=;lC*Qg^Eq^Fz%f!g5|-U?Hh9JY@FeaBG*ku4|@mX4u+p` zkJe5}>artec8#Bgrry(A`6FQGa5}v@gTPgv^les+BAG?JZJhr4=O1(%Fg+{?^D$Bv z$_Sc@~8`0KXXAGzj}Vv`UBkE{3}QmIvFXB9G=sorOqkD zU!*|^nv!I=->UJ%TV0pIFqmnrj~nkE#zW zZ)>SRdAl~AJ+(kHEH#>b0|EI7@zKB?fR}cOxwHB{ne>;?Le{-cDElhV?@L@I$=Sv9 z?NKf>^Dr!VKNR^ohJO~J8XL$0+dP0!-5zx7-Bcg?CCaE`5O)ggT4)avK}=3&4#GH$ zF39TkL5oXhx^~)zMZQOQ)lJoQt90s;dJN@G5nAE2;*ZE5;M&kc2>ur9o5HEl?X7;}74~&8Of9H$LQe352t)j_u`aOo zw5LwJc;@z$dupjqEf+@~{tvhF^8|v>fTr+Q%F1`Y9EQYR5AGVX#7tn){hVq|eP!w) z&j5Tn=KQVR_o`74T}=pa6}&UPJHCozNU5>T05gnQYXv5{V9K8U0NCQX8~Q21?Lo*v z0OA4ykKK3mwaTtM}9HJBVU+aON0c(Qn3(X|lgneX&A;>Zk>A4Ow0tDGzT zLn_;nb2qXAJ5c2zvuMpdZ|TLTPA2LU4zLe0;jXnE99NF0uAPcj?kbB%Od)qvaIPT?wjd+WLth(7oD zufoZ{`LPu+@r*o;I$F_FupV`ho-o4yW zy)(G@O^IMTAmci>hhFr1HO`3qMnfq&>HY8VlwsB+Ckmf4&7N*dqj$3uveos=!51@D zhi!^Pk9^^2KL%HN{hVzXh%l{k=F$ACbBbfX$2zTs%e`7!8bj_1cgp01Dw->Ea*z)a zT19CM^eYHQS}q0B`C5bd8gZs^qwSl@VW`xqBUQ51y*Yhgcs7oH={73+XCZ7hHGX0D zGgM#=Ot#;cQXhLK4X+aza%6W?-N$Kd&dyY=)lI$=K6iup(`<2+~#Sj5Z_*&jZa zMK<;rRwkFkH-~++U>245)$(e2*EQYwoK+P3_3_iMJj>VeK+NZ~Q2H6THgO|{Vey`! zO_4KGjx>^CKQ3$o&bjZYDMPsCwv=YS24E`BDzrMT*qeBgZef1>14CC=9h}*QQ6o0D9=r&V`dWDQEeh&|Ijm3n#%NwU(DjzoJVtcz_cDbVo zJsD4Jr0hHiY(9sri7WCXudasHnaSI_4C!q>in5_*L`5>+wxex{V^L;>w0`hW^ zzJ-`;Kk>(aglH+HI71*M0<%*Z4n*nKv@00Knwm;Q}y_j+wT?aUD6U&b@ zRGW;~Pi(YaenWr>gr|Dw?PSTh1x+VJ!Iz1ID_(t`qc0arYJLDjf6Li9V|41y2}{bm z>q5j+znXq}di@+Uyjfl;{9!AUBGt#7(}7yE2KGTBSRafSas(`_2TMRIA?ab$z%0-n~x9Snv!|dhK8&8$Zy1 zNn}Ye^l3!0e@7#fB!(9djnp_Z!jUlrf62`DAqtZ2_VzuiH1fW)Af#sYXM%<$7?PyI z=yJYDnK6W^9)!a)b;4ye{*tBDb@W5)!PQ_j1*XPt+yuG{&BZ!}>}utqaS|}%6Ekb! zWlr`pw4gb1cX*HSZpA2nkl8h-ebA#Qee4|=?PzEe49V>)hVY@i@|H>)*f~PEGoqZl zd)sldzAmPpo*#}h884=dP`8;`t%`7KXL3&qyXz8avWIFgfc`RifBK(bf!6q-| zjP4SEwC(kLFnC2EnHRd+Dnuf$*S`Rep0{O3_)G!!GWIigJ(nO9gFHd2Btxy;E$qpW zH4BUA((Vtd0kwHq<@F6uUsNbh(QkB3czGGMbEiXdP-0kLp+rcvcPc}_4F1_oW*?NG zx0pJ8F+Cu#oT~HuwARFsIOA93Jn9&8j)tP2MCdSIv3O{M?Tv1sr=ih*&SSLo<6Bz7 zc&$~cx{Y_^vks{DUVfq48brHFKgjB3ovzF8MskmOkFRgb#^yy#n?7$i(ulxXMY+a@PWIa9<&n;TA3^3~Hd9}8BV$?Zs7-I^LDV|8(3T%)r}3W|&_CXFE3m}hu+ClHh7y1T zD2%k*(!adMGFxOoo|WePvleVu(3tH5q))o#DB`Ae@2lud!~z^l0;+$ip%i~s+f|f)flxPi0$?8olay&gWMc0M{?)B! zzBjbOp0(=~-HERcr+IF^Hd4!oc-89WFM}8uXgjufUt?vErtZ|8#zDhTf6=rtw9xK7 z$(A?1)V&+cqua9=WRv`F=e_(+un|doH>#L=zU}Zf#*P`cu2lo2so3@SYiRglw6%^< zIIc`j_juU2SJOH^zW*IJOAqJ8UdFWf{ph$CR17UX{bW2?o;+E zySSzDjS5dK`r9yJiTSLyUos$O^bgi?IFz6k`=|V3o0-}W;x<*}lx88+5|Log@g-$J zr~Q;%h(4{HZa0Vg39TvbjlWC5wA+cc?TOB)V5oLa^m)w1r298!z>w7(>E3XrGczA` z2MFj`J!Wi_kerwhO{n|n82K|Pw~8KZc|MJ`6ghGqb($8>Qiz~CpoVw>exoDe8ju=R zvn@eB8)%8`R`oJ<^bss`w4vh`qWtJ$YIis?oY0}6{Mw`zP&asB3} zWTSe(>iPf&iSy|pWkQrmDKV5G9z%UebH?}^0=LEZK0>l(I=&vUpa{OfuhmqKYW9B_ z+mL8~Zmpdw3geIG*X>NCY)qB3VYy6f>1HdqLk|b#CRd>{2joR`vcSV$eTLR&k!ZVxNhXj}mG4M0sda?X!u311nr;_@ia=54 z*;nSGj0Y33QjCM|fnZ!2p+7%uCj&<=b^n-NSyPP>EMdnfy8am8XRAxrR!im9pGT4H zz?`%gU|&>wcVZLGlz#lt#WYLV!D~hhOun$ zKFHJzRt}1+QzO|^{JSAFtav<@4IVz&jXj|4{rD)t_w7pN+*ERBZe^s{3*C&zCG@v9 zx1d^pB^MBel#?Bh+Phg4Sck{KG5tX8jwuiH2ULJo=7R_CI#rr8&d)u3e<0TF0PaNF zZw)jp0$}tWqGHXY>c~q^T7_t+vqPG*a~c{K6CCxtZx5Uq46k}e(+GA zf2nWdqcr(nkFL6PJlxh1k8{4*;CmAo;SG`W8voV))e6B`nqFZQdXz z>L35!^958O`1Z99G!J>0CPESF43$arfGc&`x8EE-_&YTVlJW7$??}2%9q8qf^kT~h zRfSpKe2cD=O-996+X^{+q9}ZZsSHfL4A!g6o)npIu#`9YrQpN<8%$Fw=|Iacw8$IX z(#>9YfzXa14|iWuK;B%we(uX-m!%8Ro$kx#oLWiu0CG{zW6V#@A#`QH0}3sXZClgs z@2%JMg)qwlwm^!);*+)KdiTb@2T#>P?hQ^A5wPn^AK_*=d|lKVO4;c$LkExM#*o?Z z$ti>6!vp+Hq1>>RahSwzCEW!PNTbkixx#M?Ng$M3ho#O$#MhlRi$T7#IFW3y4?2Oh zJNh6wM33!HS_k$Z;{x!UQr+B^QPm}nLol2)n0a)FspQthVeet&h)KMskna5XDuI_# z^`=|y*mYUD6MTf=MB*euW5TOtF2L>DrUJjc%h9Z9DxOv;o-wElt8gm?AK!{~dktTK zo}#I-c!ww(S8LKNfwYUn?v`^YS~0^|Q8k_6U!P8D3sGO!grJohcCOYWr%Xbu>869P(BOTc=2 z1Ii&HL};~D?Gwecadx@Z<)xU1>x2xqmqHse#!|Ar8u1Q{vV}8crNHpVN+&q^;-;l^Mj`-YM)Z**rIWem9g9 z*b+|CW83W|q)kZyi1GN^S~^0IoEp#FrJ+&n9vLEUKgXA5F#lq}T!};2B({AuRA$$k zn#}xY;!8h+xKD<43)r=37P`Y-G_I$9=g2M0y4esB<(wO&>lU-j83~mHN>c);091hnOOk5Npf|grw6wJ<==ZZChJVR39^El zIL+^@+tUO4>2hldCt8!*R|uU1brMmh^=+U@+R?WGOJ6e|AqE3H=URg(s+fJyLGGtD zw%59U$*z64m+V>>Ft<><#C~ef?F#n>tPMSZ>4bd7_QIqYuCrq+(rsgl&y;tPM~@! zUeculcRCx>HK!QwwiWQODK|rXDN9&lW}xk+u)Wh6(|Jx15LIGyFIQ~4w)aT^DlL`^m=7y`xBF49D8#@ zjQ_R7=j2C9bFG`q3=>nz;DsTCZ78MAVdS^I?S&QZ5mLY%CrNvfVv(ZNjJI^Bp~bf_ z?>5||YZsOc74XWxr?IZf*0AdVZFraguz&*@7VtJ(@rHB8&)!qOBN+GFo(YRO{>{zpGm*TwtW)I^IKi`uB1Ux_9`Whd7*;Yln$ zPWjHh#p51FTpt=OmkLX>9s-2VNni$E!aw)Snf*la`^_B~c^IhO<&r!nk?9zb>v*I5 zx2pfuppR`w6>oeZrMozw+SSZt;gSXv6?FG>DZNDw<#M5?wMBS`s*;nx5bA&h;>hJ=gY0$WEzaclkbbi ziTH-Ur?u<1S2iZDeFc{JeJy6H>^u1SgRBrRU?p%&=AHo_r1R zCa{*%))VLoG;gZQcnC(mB>8R&x<}H!I(sV7lH-0h?9`Khg-@<>REf>OE->x*c#;X2 zh!b5lzzS{~PX}sWZKzCKz$^}Y5HCw)@CS)2nEC^1*{K++Q4+P6Wl9hb z&*$nKw7X(Tp&HogiN(Trcv%lAV;XL0Idxas_6?sqZsH zwL@!Xz_pMn!}Y#`We3tne>+A=mZ)LP36*{m(q5@3xe~ zH$ank_rF0%&A(|E4U_>SQH=d3M1?JpxXHD!6f`FTI`0~3uJ@s4jl0Tq@`!Gk%G2G% z$0tYLS%%Atv+X*0en^`XvPM%io0Dld*J&9tJP3C-x``xYDrVi!W#+f{=2zIM2la9f z##%2h-$1g29bxBPGxJ^S)Jk`xE!}S)^wrr6 z&@qk=#-p|gfBw{wbbw&yG|iYY-i{IieCHt(yK;D{EVODBaHM#sA z&Jb@{{=HuMtRZFe2lq+|=^I^ehBcn2{doN$PIQuH-waV1$S|qpLP5UWh+_Az&{;rx zRAXy)){TSdml0}YNX$CoqBp*QVSLO+tp~M28f+FHBHW)54r_#+iGSd^ur8?F$6S%7-1)7i7LGKHpw;8sC<%d zkfUkmknG_wWlwN737QYBQ%lf?aIZ_qlj5g%IB~+EH8_ z*2f*vCZipqY%C?emqy&O| zgu`%!)^?!Ps{G~2qO+b&(OEYF?>$k7rxXZ{LMC^JTL=hEn>=KuOKTz_4JmK?sXo6Y z9M7mg4&T&?We4m0so#>gmlZc?tG*oRz&|bp|FJrg z(rb5#myu2@p@aevh@=S+ogFkQ+c~l*kl@Ad*I|4 zM5AStPAZhyxKY=jSt!mwiWpS8{hLO|85N3qN8Fwybj8EEm^F!0c!(7K^$5kf}`x^xA;FDrMyi&PGuW(P~ zff=H(E=QDHS*s#A(Gla%ogn3YI+S`R>bdJ1!>p$7J@*Zkz_AfIqjI9G^U)mN_&Q|%Rd{z==V0;}gk1XvC+%(>QR4UP*i7+rl_v_W zvX~c$`C6&eNFTO3G}#pt9Zp z$Z06q!IqDjLUS&lLEG{SpEgT`y<4rEtLb#J=GEilsNA*aL;OjT>Bw(8_0j2xG_ z1F6i4t%7?x(;n0wWO$tr>qI`Rq#A16GpGuS-AQhkP7WT!S_0G!F1CsxM$?$z2OSuE zuUcvlb2HmELe5I%#Rtd3W&p7iPcPsiZ0Y;BNd+GW`Do zia@vcZfruHcRMzYrAVo*5t!}Cd^4rLFyN?;F+M_6WY_&*vUAHl@;*u)VTsq~MI50x zmJ?fyLSWoe&L)k;nbS$pdWVxgB$H?B_1Kp7K_KK2#8GBtGlaX_UAB$fvWP|oX#N3< ztVm*~PV{s2iN8%8mf*d^dH%ln-~p@|YQ7@RteBuZt%kpsRpibm;6b;jtf^|$)k9v| zct3L-)?)6}DICOQrF(3=n}f2{1>*q(R1#P((??5qY#WpPa-OY)^$14RT6J?)#`S~a zly+8bk&eJ*e;|7e!h0T?Xr@i8q+2p{f0}p`+^=@aq_j4@o3;%3IBVLKAlz)lb0|SE z^rT#P<{7X%K*1dZj)(cn#O6Fjgi!c8Uu)J5?SqEp{K9{~iBOLg+!ZmIzHJ0zG=N^$ zP_5T7#I(sKYD*18nZ-{tELvGBFl}@ffORxJv>fO-n{V=2^}&KcaB5L`q;G|r%hYn? zlbxa6TKnlQTRl#XmOC;!980vTq*Fd@? zV)n7|Yr9!o?_7aUDdaYG%6Pt{H_)|v40{m4ruMkv;d|1wL;AL>riq(I_2Ux)&B;(s z@P?;s{i;787@MyHZ(6bBf!Z$8j;R*D1D(hxEUg2Y*OLyEJ77+Pl29CM{Z{Si=5!y* z#4bM1T;YNkmh;Zqh}oa?zcDJ=3>f_?!kC2HZLM!Th=MVS!PUkV8F8vkRO?3_(uT|c^rJp zfeCD8?|eHExa*}K#RiS9DqaP8fACG8G3Pjr*(?-35dFzhUSsp*4Q4UYgrPa6-7Jkf zM*G-BdlWh>Q2zR}VY<-dM0b_RiCwM%!P9I|KUxg&9GH9sIvLZBJ?pC^j))v-FpDT&SP%=N&q4jErA!UE_Ks_odkR1vh)p zv-?I8eUYzs=&md&r`&yzv^n}DOV||GuvyE@2T!7b!26dHea0IzI2L8v*#$mSZ6}TF zW~tF|^I-nvu}_mz->J{mJis;1?A<34>IzTtd!O2U&rAk1l@~X}SzlUJX)Q!!4Ov%r zN&gj0AmZe^?tl^VK+!K}-_0NTWakLlOWeYVBF9kdNK=H=7{nX&}1zUtE0UU<{oAEHtj9|UFD6u^+SjT({WmM5+=k+F86LXF# zZR`Sd0-LXaOcg5yxaxB#Z`_n<2>Ev|neGaE8a@i1@KB%#R=$~ljZ`ci&#vN&HtrYg z)qAsJ#ixC|Adjj&=}o;#5ds!38x3vGEb#ilI_94p{L13;XvOTGT#{x{Qn0mLPP&Fw z=+T=WA7s8<#A?N_PZPnDq11Ys1s)}+=+1HNSlVTOdf4C-#V+}LNoGwofKP?gyxotF|tF@jCkKTwrGX z%kvlI!c?CC4Azqn{hHyC>(p9fIt0uRmRCOr(`kU(nJCm{=_NBIuU+-+*1zmQ2v1!*(AOsZa{=)%K_GAC0rg!c4KMH>}x54Wl;;!h1V;Xk;q9z|+ z)lu8YVeLYQmWsKx|2&8HKcFbv8IM}YcXP<`-A*Xsc~>+?=bdk*=O`x81z%=(O9mqD z8&z!9LsDbf1;|O=7b!|G#^HBB?on%)8%2l6R^4JQmCP(gLDckxruaI-mq<4ALa{h@ zeP^J?71gRfsz)+*BM&$Zn+JyP7@FA#JdjS}?<&3+^^mL4j> z%=!@+Zl?;LF@e=omGBqLKNd8Sm_b}%7GiIuB?CGNZCQ9z7c~!?sHY#RN8jSAJQ!uE zVJkf;bId^bE-d$Qa7=nP2>uvx0>F{SQ=js?6pl1ynkR3J3a`mTaMj9vJt1h<*A)HD zM(LKKN;*}g$Z&TTRjrXBG14kaTDW25GQT^S0PykG{ zE^fQU{T@jiw&oohAo&B1SGTjzhTM zNVU;z4TEG~!t4}E^Nx_8VmkKWL}%vsDL^Nlvo1^C!7q_a>Gu(CFfpG;a~kB9g^JSh z6^ch`LI3KNupko02{X5{6R2i*1&aEV`5LLq>H_j4FN$mXqYv|TT()I1zEh^u{78<} z+RXFc_|NJN%uAS$-to-qq$QBoh=UBVB?2U|^)TG-Qa*koPT$sX&3w4VlC~S7!^zlBtWJvZyGbX9Y?mC)}}vX6BIQW&+a)+ z-<627c{UGfomFT5+AIX*=ko$f>uGpY8d$+Z$GhBLrl#!V8d9}fMnfRcsw<5X7g;~`i~Pn?U$u>dY5czx#U6o4vB9*#h?0wCi_nNDNF0A4t`M7 z!i0>jIde`)*sZF4^J5ij(?rhubZ0@-)>ok8$MpY^=Zkw_`%H ziYiV44#z0I*V?$UWsN#gz z)87znvz|ua+}9^yC6`blx?CKah_WH$e2UL1dZrY&4`b^%Bp34*)_~X-EKWGLL9oLyIMnu3pG=PIaoj z0n^k%bSJ+@?A|2Gj$_IZ-Q*l1K=o)x>-q)3`MM2T4@F+Gs!O>mw$ouc%{Ei=j>=dY z1NPwx#AmJCzrB;1AQoBb)i%`CcN5#B34WDU#UHZC+QH9ZtyucVuh>r;>l>2kYF!Y% zX^i22@<$2J!lyg4YuB_A zVDBgU?tgNZ>`E@2HRmXiqd;%bwy1N=M3y>S+nSt{cu&@ay!dQLKNbC;5W0I`ny91b zcGyHo;@7tR79f1(qdL$UU>s{AAFqRR|mUZ;fQZK_nmCn+f>fo7lps<>Ksrc~phy!jpeOP6YuC{iUXGa}nUXf#mG%KtuV%gJKRVkQSXz?}Rn?Wr zd5cs2d}VgQqT-o2(S*P3=XfQ%PxgmFsl`}w9(vQzIfL=?!~(eE+dfO`Slgk~B-puG zSY@yZ=H80^h+dAOd9;`+;+th_rWG=5Vo$5lU8Z{9Yd`LN8~Ah~XBI|I+=YOQ3s`x( zzKLe-TP+47rYW+!AsVa;S5~sB{ZrUHx9=7)Z|y=VcHr!|Ff(x&`7>!ZZDF`xR61Pp%)t3HHghpZV{|cgf04qWs7|?tlYbH0QHY4~Fb>z=v7) zc&MOW$|;?%?1K$Ph-W^bZ`woD>=OhMU$pobdUWgk_Q3_q_(E&Km?E9$X$GCFD^t2M zwm7ChcixUHfz+wo-F2ICPH?y}J;eCa;HcUqWWsn9x~l2C5-dyLU!F z<6`iCFi1W0GB8I$F ze`t^P`(n@gazot12x$xmej(Z$x>(si53jr6?kXoSlMJSVhSAy_^Q>hpgiuLz1Q^h& z*}TfTkTXFPwg~;j25PyJ5yiX%z-La0%mm|tj-JDhtO(~yDSazxY|62@UhHL`wWm{o z%rWG&Xw@>9>MqT+V?cqy4q0{T{RW@*ltY+(-!}D!OCP=Qoe{Xbw_0YczFQia`}(y| zFDwOQ0@SAv;0Kqt$((V9h!zTP3Bsd}MU`8xobekbRc|MFkYlEirx5P`ti8Y#!y(!U zNTEr!-edQLWwTFG6}(THSVWYLx8Kj+koufF04dYgq@DZxAxV4MNDiZrA@&;654 zNSc)O=p_rk{61IzOOwmm@j`hqKBg|A3&~+C#vTksHeSL=jF8IK0-~?^K81_rEFg|o z$3t}sZhT$s?h8oITbd({Te0`ofdk?HyTgxG-72e1O}(N;lu;>3*jzjHs-FV!N?jw0 zo8}or4RPCnYw;?;qGD$UThU1_8aUD+zh;Gp$_|;md!MJSh@OEYyUIo0YS19QX)_95 z31G-Gm4OHe1W{D2K5oc&KcW z!VYr@>8F@lb*d}8mFowl>8!pr5iUI+a{@7dt%5I?(2iOUnH+r|Q3sPy+kA{}YY>g> z@44nO-SN22|CivHiq>&6@?n-35JF{G0GG(uC0b2oVr_#&tm<4{t-W3pd!^proBNDV zR@s8(WnKj~s6w+~ul{UhY=v$oEe@`N*Sjtr`i;T}NJ(vNi!l%CnaSwQ$1p%TH`;oP zt$`S9=Az{{sdrR;@OwHn#b@1jH&}tYaulpdyvCDf6He7!9 z%r@&rYt#T^pnDN}ANEV`g=#_|alo}aR6yZeTXfGKT}liLh9u|aP;g&D=;E{_Fg{BH zb5_(IAkJY-?ZnZ~V?isov-YnPKJH3US&AK3wC-AS1|@+j!4pt+NX)QU}gecSN9@lJp3ajxa zm;K}-?;N-g@D)tV6X*Wi>JWCR`56e+OcB7R2wG5uSfWT_Bv~DV^hTgnq~%Mm*`4~$ z$K%Xt;zhF@v)r{H!7A$aGeX{8e_5K+Z#ek+wV)K6SA*dR;OMYnra;(?jI#Nd0>P&- znH*r>FLzqF&B+IK{03T+V)#pSBbY7-!qz&B!04;A{<_pH8CNUYDD!faAKX`RJAg`j^EMcdNzkmTEn091Z+f^I zfBXIv%yBHxGuimLjl#i$Di&7WXQ$S;TI6mu7lDhz=@&5x2O}zxI%GAg>Zz6Sw`=&G z$GPEW0*v>&m>*14TTe(!fmlP=vw=RVXGs) z!)k&-dl6eF>MIh@hgB2xS<$o$WnjuKw0Kci{-FIOvc{`vBU2ItU;fk2Ej8v*rXl3+NB{G~QyhUIjnwt7@=FLk_iRW7$? z-TV3|Jzx{Pl6!~OgI4;mk^i*$2rL1D&<6MQ{s8L@6O4PeLhIPs(}YjpPx3djD0Ej~ zgkP)XQ+LF1g}Y_m-ufpY9HY|b^N#aXxs$(^(xdKY3)Ng!DRJOFp z@#7T687g^0%~Ub0Or)2(1pPEMzp=nK@+TWB_#slm6J?)vu;}I?vm&2BUI=p!jXNe9 zPBxwtqZuTH1`A?vw-Z7GB!kWuSbulwbI8=zN&icXC6C0N{*NyE~Jc7v(m(DOq!J^=SOUg4A~GnS@VL(^}hv0WeN*U8L^O6rf48#caWT zfgyLsOc0!!leVA-!hVFLt;qYQ&DF-L1zeh%o(H0m=h%CR;S@Hn%*+>&8EA*be$dl| zDwJ?P<)M=mLHCqVlwqY(f-qjuui|W#QH@R)V8Qi*>i`G$vO5t?HypzH2k!xFTX*o- zx4#}t%RIN?$7^-0X{^R0HE*WJnK(58Fx*E#qQyw?QLyUN>Ef%d3$%VYj=WoG9{hJZ ztgj7m_mK{<4>GxdI4TrJ;*7STxpi87Yf=hQcbFqA9~tE&o*g>g-y|jw8zvC^&a=J!&To!8@Xyvj!hp{x-0G zRcqd;A|mi^4rI-@w1a(1RWRN=?;m=_Kib9rb<=52^2u4!7U)>^s5~w7i{Ui9SDcPeI?>#E zQFAJKB2JSv-XW-c50|{vusuoNs7|qG<%b4%k8YK#md&S2*q^~od3}%D zaAV8MmJuxjCEE|D`u&{y-96lp($W6-n$MU)p>TLB-9@do+{iV&aA%g}a7Kh8Yz2Cz znBHi=Lpknr(!?o$3Z%e9nC3pz>|j1WHh0~#P9x8{Ai?^(_e=5Cak{B}uXrA8`wOXE zuSyMZYzmrzCJ@zvi`_vV#F8?%g<9J{jr-%F^+DH`r#{INOVk24%nj~OIf z@*+Y9^x{weeL{H0il`cogH1R~-s9SgP;}K7m&Xqqu2gX4N}eVsUS8XXj3&^W$nRa? zX$c9Gg!`qm^lGHfTfcSSPC)g5tm}B+vvXb^zSstlRfkwXO-Q8$K%mxYq`93Wm~fMg zVN$2xUUNeO)+ToE{S9cpi1!00e^|fHvT&Yw#Nlyy0`rJlI?l~{eQ_1cWJTFd*b+vp zUyt3d_gD#y4!qlgj9~9VtVi_(WUT{N-V2}VAsFmC zuk&&H<2wjt-o!(y6J6uewk8zKi*DC<;~NQ$=s+nh&@3OlYq?uuff-keRgv-X^0H@G z&NhBk_$YUe#Bu)+TM|f?;qGXbp>3M#QCWFyRf`7~4G253ANUsV;Ut0tmJef#%Y$6gi3)aTZ1#>t% zPjrS8oKW=N2kj(No3b>X_c=K7GsjPwb~Lg?Tt3p2GQ8d`ggLnT)qN~!$MmV!E2hO9 z|GIO)A{@HBfxKDFG{l3kSOBoCO`^aqR_2beXmF}$xJL3jgq@Dmpol~ZT;sYoUk_eW-&c7 z>_^&fumrjbF~t^{c+9=&><^yF=zt|Q%hU`9Q--!8-Wa|3e&_74&7mjh2PaxCiIcPd zi1PV-)t;KQ$y}G*InD)?X1Fj^0PGH*rO2MdXj#tR`*5s&Jthn+M5t-}OheU+tAUY8PLwa`07M{~;x%7Pj}YYTV$BHi8EiK_ zDELaZ@dI~t(j5D`47zBERQqWHsOxM%Jg1{*3!hSg^jrpJ!-JZ#(@rQi1%zffrrRj0 zh>uSy$zKqA^v-<`sGSRjhEKMm+@xsdenr}`SYs>AStEW%#kak#60P?U>eBU7{Hvqa zixaG-E(W9kPfEj+Eb*o){!VstQbEQpjpB(L&QxNGAOAhI2SZiBReuq~v zO8HfdZ1+xh{iHkmh-1Tppfg+NmUfk5wEkGB*4b)^HwXu$mTusg^4 z&5q(|d=C_*`c>KFRwKimIM;pv%)ty&F?@skr}fe0rH`|Tn6!apYX8sGXFoP7h~BcE z=MSD?mK`ztTKQt7SsWKJ`%py}DG-i!1;XAe4&G@#UPZO|(%bJ(tGDY`kL}gr4%E!- zK6FUV^TerYIJNdgF_W7no=cwcXg8p9x0jdu*JU?DQRXN+Ot`*v{<*foYijNfxHv;f z9XWcxlyze!3E^v#mRss?8LsLWF!5>rT{!ehcW~0FUBXoCBPPQY@Kb8gD=PRNP-g@d z!Y1OpnzE$I_H|7h4UxP`d*Sg)R&@~>-wf)0^EpShRIvwqO^-EZc2)bkNe1DCH6KWM z^ww`%ivE1krAK|!3XOMD!F&e73IcN6N*%xku9 zTj8;mfsdm+2tTe12t9REiN&CA{+i58hBSYN8s$CT-P=nZi8W$Z$> z-suNk^dY{@a$oriMj?Q;|6RzE1FKq@xdTFXyAYOtis`5iF*|M)#qfr2Z-MOOE@WpE z83;BuO|f7ivkP%49K=Y{i_HH2ivNEf|Ly#^lG%T>%gK9nV$gpG1YZ8rhju{V6+ZnR v&PF##UX0eg-^&;IW*8pySeY1% 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 literal 0 HcmV?d00001 diff --git a/ware-email-send/src/main/java/com/email/send/EmailApplication.java b/ware-email-send/src/main/java/com/email/send/EmailApplication.java new file mode 100644 index 0000000..678ded2 --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/EmailApplication.java @@ -0,0 +1,13 @@ +package com.email.send; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; + +@EnableAsync +@SpringBootApplication +public class EmailApplication { + public static void main(String[] args) { + SpringApplication.run(EmailApplication.class,args) ; + } +} diff --git a/ware-email-send/src/main/java/com/email/send/controller/EmailController.java b/ware-email-send/src/main/java/com/email/send/controller/EmailController.java new file mode 100644 index 0000000..83ca68e --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/controller/EmailController.java @@ -0,0 +1,28 @@ +package com.email.send.controller; + +import com.email.send.model.SendEmailModel; +import com.email.send.param.EmailType; +import com.email.send.service.EmailService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; + +@RestController +public class EmailController { + + private static final Logger LOGGER = LoggerFactory.getLogger(EmailController.class) ; + + @Resource + private EmailService emailService ; + + @RequestMapping("/sendEmail") + public String sendEmail (){ + SendEmailModel model = new SendEmailModel() ; + model.setReceiver("xxxxx@qq.com"); + emailService.sendEmail(EmailType.EMAIL_TEXT_KEY.getCode(),model); + LOGGER.info("执行结束====>>"); + return "success" ; + } +} diff --git a/ware-email-send/src/main/java/com/email/send/model/SendEmailModel.java b/ware-email-send/src/main/java/com/email/send/model/SendEmailModel.java new file mode 100644 index 0000000..503f385 --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/model/SendEmailModel.java @@ -0,0 +1,26 @@ +package com.email.send.model; + +/** + * 邮件发送参数封装 + */ +public class SendEmailModel { + + public static final String EMAIL_TEXT_KEY = "email_balance_key" ; + public static final String EMAIL_IMAGE_KEY = "email_req_num_key" ; + public static final String EMAIL_FILE_KEY = "email_open_account_key" ; + + /** + * 收件人邮箱 + */ + private String receiver ; + + + public String getReceiver() { + return receiver; + } + + public void setReceiver(String receiver) { + this.receiver = receiver; + } + +} diff --git a/ware-email-send/src/main/java/com/email/send/param/BodyType.java b/ware-email-send/src/main/java/com/email/send/param/BodyType.java new file mode 100644 index 0000000..53fd732 --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/param/BodyType.java @@ -0,0 +1,41 @@ +package com.email.send.param; + +public enum BodyType { + + EMAIL_TEXT_BODY("email_text_key","您好:%s,我是:%s"), + EMAIL_IMAGE_BODY("email_image_key","图片名称:%s"), + EMAIL_FILE_BODY("email_file_key","文件名称:%s"); + + private String code ; + private String value ; + BodyType (String code,String value){ + this.code = code ; + this.value = value ; + } + + public static String getByCode (String code){ + BodyType[] values = BodyType.values() ; + for (BodyType bodyType : values) { + if (bodyType.code.equalsIgnoreCase(code)){ + return bodyType.value ; + } + } + return null ; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/ware-email-send/src/main/java/com/email/send/param/EmailParam.java b/ware-email-send/src/main/java/com/email/send/param/EmailParam.java new file mode 100644 index 0000000..4810a7b --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/param/EmailParam.java @@ -0,0 +1,34 @@ +package com.email.send.param; + +/** + * 邮箱发送参数配置 + */ +public class EmailParam { + /** + * 邮箱服务器地址 + */ + // public static final String emailHost = "smtp.mxhichina.com" ; 阿里云企业邮箱配置(账号+密码) + // public static final String emailHost = "smtp.aliyun.com" ; 阿里云个人邮箱配置(账号+密码) + public static final String emailHost = "smtp.163.com" ; // 网易邮箱配置(账号+授权码) + /** + * 邮箱协议 + */ + public static final String emailProtocol = "smtp" ; + /** + * 邮箱发件人 + */ + public static final String emailSender = "xxxxxx@163.com" ; + /** + * 邮箱授权码 + */ + public static final String password = "authCode"; + /** + * 邮箱授权 + */ + public static final String emailAuth = "true" ; + /** + * 邮箱昵称 + */ + public static final String emailNick = "知了一笑" ; + +} diff --git a/ware-email-send/src/main/java/com/email/send/param/EmailType.java b/ware-email-send/src/main/java/com/email/send/param/EmailType.java new file mode 100644 index 0000000..3807693 --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/param/EmailType.java @@ -0,0 +1,44 @@ +package com.email.send.param; + +/** + * 邮件发送类型 + */ +public enum EmailType { + + EMAIL_TEXT_KEY("email_text_key","文本邮件"), + EMAIL_IMAGE_KEY("email_image_key","图片邮件"), + EMAIL_FILE_KEY("email_file_key","文件邮件"); + + private String code ; + private String value ; + EmailType (String code,String value){ + this.code = code ; + this.value = value ; + } + + public static String getByCode (String code){ + EmailType[] values = EmailType.values() ; + for (EmailType emailType : values) { + if (emailType.code.equalsIgnoreCase(code)){ + return emailType.value ; + } + } + return null ; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/ware-email-send/src/main/java/com/email/send/service/EmailService.java b/ware-email-send/src/main/java/com/email/send/service/EmailService.java new file mode 100644 index 0000000..332ae3a --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/service/EmailService.java @@ -0,0 +1,7 @@ +package com.email.send.service; + +import com.email.send.model.SendEmailModel; + +public interface EmailService { + void sendEmail (String emailKey, SendEmailModel model) ; +} diff --git a/ware-email-send/src/main/java/com/email/send/service/impl/EmailServiceImpl.java b/ware-email-send/src/main/java/com/email/send/service/impl/EmailServiceImpl.java new file mode 100644 index 0000000..3d4a95a --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/service/impl/EmailServiceImpl.java @@ -0,0 +1,33 @@ +package com.email.send.service.impl; + +import com.email.send.model.SendEmailModel; +import com.email.send.param.BodyType; +import com.email.send.param.EmailType; +import com.email.send.service.EmailService; +import com.email.send.util.EmailUtil; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +@Component +@Service +public class EmailServiceImpl implements EmailService { + + @Async("taskExecutor") + @Override + public void sendEmail(String emailKey, SendEmailModel model) { + try{ + // 异步执行 + Thread.sleep(1000); + String textBody = EmailUtil.convertTextModel(BodyType.getByCode(emailKey),"知了","一笑"); + // 发送文本邮件 + EmailUtil.sendEmail01(model.getReceiver(), EmailType.getByCode(emailKey),textBody); + // 发送复杂邮件:文本+图片+附件 + String body = "自定义图片:,网络图片:"; + // EmailUtil.sendEmail02(model.getReceiver(),"文本+图片+附件",body); + } catch (Exception e){ + e.printStackTrace(); + } + + } +} diff --git a/ware-email-send/src/main/java/com/email/send/util/EmailUtil.java b/ware-email-send/src/main/java/com/email/send/util/EmailUtil.java new file mode 100644 index 0000000..4b71732 --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/util/EmailUtil.java @@ -0,0 +1,160 @@ +package com.email.send.util; + +import com.email.send.param.EmailParam; + +import javax.activation.DataHandler; +import javax.activation.FileDataSource; +import javax.mail.Message; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import java.io.FileOutputStream; +import java.util.Properties; + +/** + * 邮箱发送工具类 + */ +public class EmailUtil { + + public static void main(String[] args) throws Exception { + sendEmail01("dzyaly@aliyun.com","复杂邮件","自定义图片:,网络图片:") ; + } + + /** + * 邮箱发送模式01:纯文本格式 + */ + public static void sendEmail01 (String receiver,String title,String body) throws Exception { + Properties prop = new Properties(); + prop.setProperty("mail.host", EmailParam.emailHost); + prop.setProperty("mail.transport.protocol", EmailParam.emailProtocol); + prop.setProperty("mail.smtp.auth", EmailParam.emailAuth); + //使用JavaMail发送邮件的5个步骤 + //1、创建session + Session session = Session.getInstance(prop); + //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态 + session.setDebug(true); + //2、通过session得到transport对象 + Transport ts = session.getTransport(); + //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给smtp服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。 + ts.connect(EmailParam.emailHost, EmailParam.emailSender, EmailParam.password); + //4、创建邮件 + // Message message = createEmail01(session,receiver,title,body); + Message message = createEmail01(session,receiver,title,body); + //5、发送邮件 + ts.sendMessage(message, message.getAllRecipients()); + ts.close(); + } + + /** + * 邮箱发送模式02:复杂格式 + */ + public static void sendEmail02 (String receiver,String title,String body) throws Exception { + Properties prop = new Properties(); + prop.setProperty("mail.host", EmailParam.emailHost); + prop.setProperty("mail.transport.protocol", EmailParam.emailProtocol); + prop.setProperty("mail.smtp.auth", EmailParam.emailAuth); + //使用JavaMail发送邮件的5个步骤 + //1、创建session + Session session = Session.getInstance(prop); + //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态 + session.setDebug(true); + //2、通过session得到transport对象 + Transport ts = session.getTransport(); + //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给smtp服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。 + ts.connect(EmailParam.emailHost, EmailParam.emailSender, EmailParam.password); + //4、创建邮件 + // Message message = createEmail01(session,receiver,title,body); + Message message = createEmail02(session,receiver,title,body); + //5、发送邮件 + ts.sendMessage(message, message.getAllRecipients()); + ts.close(); + } + + /** + * 创建文本邮件 + */ + private static MimeMessage createEmail01(Session session,String receiver,String title,String body) + throws Exception { + //创建邮件对象 + MimeMessage message = new MimeMessage(session); + //指明邮件的发件人 + String nick = javax.mail.internet.MimeUtility.encodeText(EmailParam.emailNick); + message.setFrom(new InternetAddress(nick+"<"+EmailParam.emailSender+">")); + //指明邮件的收件人 + message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver)); + //邮件的标题 + message.setSubject(title); + //邮件的文本内容 + message.setContent(body, "text/html;charset=UTF-8"); + //返回创建好的邮件对象 + return message; + } + + private static MimeMessage createEmail02 (Session session,String receiver,String title,String body) + throws Exception{ + //创建邮件对象 + MimeMessage message = new MimeMessage(session); + //指明邮件的发件人 + String nick = javax.mail.internet.MimeUtility.encodeText(EmailParam.emailNick); + message.setFrom(new InternetAddress(nick+"<"+EmailParam.emailSender+">")); + //指明邮件的收件人 + message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver)); + //邮件的标题 + message.setSubject(title); + //文本内容 + MimeBodyPart text = new MimeBodyPart() ; + text.setContent(body,"text/html;charset=UTF-8"); + //图片内容 + MimeBodyPart image = new MimeBodyPart(); + image.setDataHandler(new DataHandler(new FileDataSource("ware-email-send/src/gzh.jpg"))); + image.setContentID("gzh.jpg"); + //附件内容 + MimeBodyPart attach = new MimeBodyPart(); + DataHandler file = new DataHandler(new FileDataSource("ware-email-send/src/gzh.zip")); + attach.setDataHandler(file); + attach.setFileName(file.getName()); + //关系:正文和图片 + MimeMultipart multipart1 = new MimeMultipart(); + multipart1.addBodyPart(text); + multipart1.addBodyPart(image); + multipart1.setSubType("related"); + //关系:正文和附件 + MimeMultipart multipart2 = new MimeMultipart(); + multipart2.addBodyPart(attach); + // 全文内容 + MimeBodyPart content = new MimeBodyPart(); + content.setContent(multipart1); + multipart2.addBodyPart(content); + multipart2.setSubType("mixed"); + // 封装 MimeMessage 对象 + message.setContent(multipart2); + message.saveChanges(); + // 本地查看文件格式 + message.writeTo(new FileOutputStream("F:\\MixedMail.eml")); + //返回创建好的邮件对象 + return message; + } + + /** + * 文本邮箱模板 + */ + public static String convertTextModel (String body,String param1,String param2){ + return String.format(body,param1,param2) ; + } + /** + * 图片邮箱模板 + */ + public static String convertImageModel (String body,String param1){ + return String.format(body,param1) ; + } + /** + * 文件邮箱模板 + */ + public static String convertFileModel (String body,String param1){ + return String.format(body,param1) ; + } + +} diff --git a/ware-email-send/src/main/java/com/email/send/util/TaskPoolConfig.java b/ware-email-send/src/main/java/com/email/send/util/TaskPoolConfig.java new file mode 100644 index 0000000..c58dcde --- /dev/null +++ b/ware-email-send/src/main/java/com/email/send/util/TaskPoolConfig.java @@ -0,0 +1,39 @@ +package com.email.send.util; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 定义异步任务执行线程池 + */ +@Configuration +public class TaskPoolConfig { + @Bean("taskExecutor") + public Executor taskExecutor () { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + // 核心线程数10:线程池创建时候初始化的线程数 + executor.setCorePoolSize(10); + // 最大线程数20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程 + executor.setMaxPoolSize(15); + // 缓冲队列200:用来缓冲执行任务的队列 + executor.setQueueCapacity(200); + // 允许线程的空闲时间60秒:当超过了核心线程数之外的线程在空闲时间到达之后会被销毁 + executor.setKeepAliveSeconds(60); + // 线程池名的前缀:设置好了之后可以方便定位处理任务所在的线程池 + executor.setThreadNamePrefix("taskExecutor-"); + /* + 线程池对拒绝任务的处理策略:这里采用了CallerRunsPolicy策略, + 当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务; + 如果执行程序已关闭,则会丢弃该任务 + */ + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + // 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean + executor.setWaitForTasksToCompleteOnShutdown(true); + // 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。 + executor.setAwaitTerminationSeconds(600); + return executor; + } +} diff --git a/ware-email-send/src/main/resources/application.yml b/ware-email-send/src/main/resources/application.yml new file mode 100644 index 0000000..578a171 --- /dev/null +++ b/ware-email-send/src/main/resources/application.yml @@ -0,0 +1,21 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + max-threads: 1000 + min-spare-threads: 30 + port: 7005 + connection-timeout: 5000ms + servlet: + context-path: /email + +spring: + application: + name: email-send + profiles: + active: dev + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + enabled: true \ No newline at end of file