spring boot傳送郵件,使用的velocity模板(html)
阿新 • • 發佈:2018-11-12
新增依賴:
<!--郵件依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!--velocity模板--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-velocity</artifactId> <version>1.4.7.RELEASE</version> </dependency>
application.properties的配置:注意,我使用的是163郵箱傳送郵件,如果使用qq郵箱傳送,配置會稍有不同
# JavaMailSender 郵件傳送的配置 spring.mail.host=smtp.163.com #郵件傳送者 [email protected] #郵件的接收者 [email protected] #設定的是客戶端授權密碼,不是郵箱的登入密碼 spring.mail.password=xxx spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true
qq郵箱傳送郵件發的配置:
######qq郵箱######## spring.mail.host=smtp.qq.com spring.mail.username=******@qq.com #QQ郵箱授權碼 spring.mail.password=xuojxtkdojvzbhjj spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true
注意密碼的配置,設定的是客戶端授權密碼,不是郵箱的登入密碼,以163郵箱為例,需要保證如下的設定
登入163郵箱,修改如下的操作
需要開啟如下的授權碼,在properties中配置的密碼就是這個開啟的授權碼,不能是密碼
編寫郵件傳送類
package com.tencent.springbootsendmail.service.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencent.springbootsendmail.model.ProductInfo;
import com.tencent.springbootsendmail.service.SendMailService;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.tools.generic.NumberTool;
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.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@Service
public class SendMailServiceImpl implements SendMailService {
@Autowired
private JavaMailSender javaMailSender;
static final Logger LOG = LoggerFactory.getLogger(SendMailServiceImpl.class);
private String mailFrom = "[email protected]";
private String mailTo = "[email protected]";
/**
velocity模板
*/
private Template template;
/**
*
* 郵件傳送者
*/
@Value("${spring.mail.username}")
private String Sender;
/**
* 郵件接收者
*/
@Value("${spring.mail.tomail}")
private String ToMail;
/**
* 模板路徑
*/
@Value("${template:templates/mail.vm}")
private String templateFile;
/**
* 初始化velocity模板
*/
@PostConstruct
private void init() {
Properties p = new Properties();
p.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
p.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
Velocity.init(p);
VelocityContext context = new VelocityContext();
context.put("numberTool", new NumberTool());
template = Velocity.getTemplate(templateFile, "UTF-8");
}
@Override
public List<ProductInfo> getMailData(){
/**
* 獲取json資料
*/
/* String url = "http://sms-agent-cloud.vpc.tencentyun.com/callLogAnalyze/logAnalyze/analyzeAll.do";
MultiValueMap<String,String> paramMap = new LinkedMultiValueMap<>();
List<String> list = new ArrayList<>();
HttpHeaders httpHeaders = new HttpHeaders();
String json = HttpClient.sendGetRequest(url, paramMap, httpHeaders);
*/
ArrayList<ProductInfo> productInfos = null;
String json = "[{\"period\":\"整個放音\",\"averageCostMsec\":9046.88,\"maxCostMsec\":14330,\"minCostSec\":4445,\"distributing\":[{\"from\":null,\"to\":1000,\"count\":0,\"desc\":\"1000毫秒以下\"},{\"from\":1000,\"to\":10000,\"count\":13,\"desc\":\"1000至10000毫秒\"},{\"from\":10000,\"to\":20000,\"count\":12,\"desc\":\"10000至20000毫秒\"},{\"from\":20000,\"to\":30000,\"count\":0,\"desc\":\"20000至30000毫秒\"},{\"from\":30000,\"to\":null,\"count\":0,\"desc\":\"30000毫秒以上\"}]},{\"period\":\"啟動識別到檢測到聲音\",\"averageCostMsec\":8115.895348837209,\"maxCostMsec\":23151,\"minCostSec\":992,\"distributing\":[{\"from\":null,\"to\":1000,\"count\":1,\"desc\":\"1000毫秒以下\"},{\"from\":1000,\"to\":5000,\"count\":36,\"desc\":\"1000至5000毫秒\"},{\"from\":5000,\"to\":10000,\"count\":20,\"desc\":\"5000至10000毫秒\"},{\"from\":10000,\"to\":20000,\"count\":26,\"desc\":\"10000至20000毫秒\"},{\"from\":20000,\"to\":null,\"count\":3,\"desc\":\"20000毫秒以上\"}]},{\"period\":\"整個呼叫\",\"averageCostMsec\":0,\"maxCostMsec\":0,\"minCostSec\":0,\"distributing\":[{\"from\":null,\"to\":10000,\"count\":9,\"desc\":\"10000毫秒以下\"},{\"from\":10000,\"to\":20000,\"count\":0,\"desc\":\"10000至20000毫秒\"},{\"from\":20000,\"to\":40000,\"count\":0,\"desc\":\"20000至40000毫秒\"},{\"from\":40000,\"to\":60000,\"count\":0,\"desc\":\"40000至60000毫秒\"},{\"from\":60000,\"to\":null,\"count\":0,\"desc\":\"60000毫秒以上\"}]},{\"period\":\"任務引擎呼叫\",\"averageCostMsec\":171.62790697674419,\"maxCostMsec\":200,\"minCostSec\":140,\"distributing\":[{\"from\":null,\"to\":100,\"count\":0,\"desc\":\"100毫秒以下\"},{\"from\":100,\"to\":200,\"count\":38,\"desc\":\"100至200毫秒\"},{\"from\":200,\"to\":300,\"count\":5,\"desc\":\"200至300毫秒\"},{\"from\":300,\"to\":400,\"count\":0,\"desc\":\"300至400毫秒\"},{\"from\":400,\"to\":null,\"count\":0,\"desc\":\"400毫秒以上\"}]},{\"period\":\"整個識別\",\"averageCostMsec\":8773.581395348838,\"maxCostMsec\":23301,\"minCostSec\":1912,\"distributing\":[{\"from\":null,\"to\":1000,\"count\":0,\"desc\":\"1000毫秒以下\"},{\"from\":1000,\"to\":5000,\"count\":18,\"desc\":\"1000至5000毫秒\"},{\"from\":5000,\"to\":15000,\"count\":18,\"desc\":\"5000至15000毫秒\"},{\"from\":15000,\"to\":25000,\"count\":7,\"desc\":\"15000至25000毫秒\"},{\"from\":25000,\"to\":null,\"count\":0,\"desc\":\"25000毫秒以上\"}]}]";
ObjectMapper mapper = new ObjectMapper();
try {
//解析json
JsonNode arrNode = new ObjectMapper().readTree(json);
productInfos = new ArrayList<>();
if(arrNode.isArray()){
for (JsonNode node : arrNode) {
ProductInfo productInfo = mapper.readValue(node.toString(), ProductInfo.class);
productInfos.add(productInfo);
}
}
} catch (IOException e) {
LOG.error("getMailData<|>resultJson:"+json,e.getMessage(),e);
}
return productInfos;
}
/**
* 傳送velocity模板(HTML)郵件
*/
@Override
public void sendMail() {
System.out.println("接收者:"+ToMail);
List<ProductInfo> mailData = getMailData();
//填充模板,作為內容
final String content = render(mailData);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(Sender);
helper.setTo(ToMail);
helper.setSubject("xx先生請查收!");
helper.setText(content, true);
javaMailSender.send(mimeMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 填充velocity模板內容
* @param productInfo
* 內容詳情
* @return
*/
@Override
public String render(List<ProductInfo> productInfo) {
VelocityContext context = new VelocityContext();
context.put("numberTool", new NumberTool());
context.put("appInfos", productInfo);
StringWriter sw = new StringWriter();
this.template.merge(context,sw);
return sw.toString();
}
}
我的mail.vm模板,如下
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>HTML Email郵件</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<style type="text/css">
caption.app-name {
font-size: xx-large;
}
#summary th {
text-align: center;
padding: 0 10px;
}
#summary td {
padding: 0 10px;
text-align: center;
}
table {
margin-top: 50px;
}
</style>
<body style="margin: 0; padding: 0;">
<table id="summary" align="center" border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse;">
<caption class="app-name">應用總體情況</caption>
<thead>
<th>序號</th>
<th>period(應用時期)</th>
<th>averageCostMsec(平均時間)</th>
<th>maxCostMsec(最大時間)</th>
<th>minCostSec(最小時間)</th>
</thead>
#set ($index = 0)
#foreach( $appInfo in $appInfos)
#set ($index = $index + 1)
<tr>
<td>$!index</td>
<td>$!appInfo.getPeriod()</td>
<td>$!appInfo.getAverageCostMsec()</td>
<td>$!appInfo.getMaxCostMsec()</td>
<td>$!appInfo.getMinCostSec()</td>
</tr>
#end
</table>
#foreach( $appInfo in $appInfos )
<table id="summary" align="center" border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse;">
<caption class="app-name">$!appInfo.getPeriod()</caption>
<thead>
<th>序號</th>
<th>from(開始)</th>
<th>to(終止)</th>
<th>count(次數)</th>
<th>desc(描述)</th>
</thead>
#set ($index = 0)
#foreach($ds in $appInfo.getDistributing())
#set ($index = $index + 1)
<tr>
<td>$!index</td>
#if( "$!ds.getFrom()" == "" )
<td>0</td>
#else
<td>$!ds.getFrom()</td>
#end
#if( "$!ds.getTo()" == "" )
<td>0</td>
#else
<td>$!ds.getTo()</td>
#end
<td>$!ds.getCount()</td>
<td>$!ds.getDesc()</td>
</tr>
#end
</table>
#end
</body>
</html>
controller編寫
package com.tencent.springbootsendmail.controller;
import com.tencent.springbootsendmail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class SendMailController {
@Autowired
private SendMailService sendMailService;
@RequestMapping("/send")
public void sendMail(){
sendMailService.sendMail();
}
}
訪問傳送郵件