1,邮件模板
2,代码
2.1)调用方
/**
* 发送邮件
*
* @param request
*/
private void sendEmail(BaseRequestModel request, AddressEntity addressEntity) {
// 发送信息
Long belongTo = request.getBelongTo();
CompanyEntity companyEntity = new CompanyEntity();
companyEntity.setIsDel(DeleteStatusE.USEFUL.getValue());
companyEntity.setId(belongTo);
List<CompanyEntity> comList = companyManageMapper.select(companyEntity);
CompanyEntity entity = null;
if (comList != null && !comList.isEmpty()) {
entity = comList.get(0);
String conpanyName = entity.getName();
String orgCode = entity.getOrgCode();
String contact = entity.getContact();
String email = entity.getEmail();
String mobile = entity.getMobile();//手机
String telephone = entity.getTelephone();//座机
if (conpanyName == null) {
conpanyName = "";
}
if (orgCode == null) {
orgCode = "";
}
if (contact == null) {
contact = "";
}
if (email == null) {
email = "";
}
if (mobile == null) {
mobile = "";
}
if (telephone == null) {
telephone = "";
}
// 发送人
String userName = request.getUserName();
// 主题
String subject = conpanyName + "办公地址新增通知";
// 内容 String content = "<p>尊敬的用户,</p><p> 你好,打发士大夫犯得上地方是</p>";
String content = "<p>尊敬的用户,</p><p> 您好,"
+ conpanyName + ",新增了" + addressEntity.getAddressName() + "办公点," +
"具体地址:" + addressEntity.getProvince() + addressEntity.getCity() + addressEntity.getDistrict() + "," + addressEntity.getDetailAddress() +
",联系人:" + contact + ",邮箱:" + email + ",座机:" + telephone + ",手机:" + mobile +
",请核实该地址是否在经销商服务范围内,如不在服务范围内,请协调处理。</p>"+"<br/><br/>";
// 目标邮箱
List<String> toEmail = new ArrayList<>();
List<Long> branIdList = companyManageMapper.selectBrandIdByOrgId(entity.getApprovalCompany().longValue());
if (branIdList != null && !branIdList.isEmpty()) {
Map<String, Object> map = new HashMap<>();
map.put("branIdList", branIdList);
List<Long> orgIds = orgMapper.selectOrgByBrand(map);
orgIds.forEach(v -> {
OrgEntity org = orgMapper.selectByPrimaryKey(v);
toEmail.add(org.getEmail());
});
}
//收件信息
Map<String, Object> map = new HashMap<>();
map.put("subject", subject);
map.put("content", content);
map.put("name", userName);
map.put("type", EmailTypeE.ADDADRESS.getValue());
map.put("code", conpanyName);
logger.error("{toEmail的数量 :--- }" + toEmail.size());
if(!CollectionUtils.isEmpty(toEmail)){
authServiceClient.sendEmail(toEmail, map);
}
}
}
内容格式说明,与模板略有不同,<p></p>分段,
缩进两个空格,<br/> 段落之间间隔
// 内容 String content = "<p>尊敬的用户,</p><p> 你好,打发士大夫犯得上地方是</p>";
String content = "<p>尊敬的用户,</p><p> 您好,"
+ conpanyName + ",新增了" + addressEntity.getAddressName() + "办公点," +
"具体地址:" + addressEntity.getProvince() + addressEntity.getCity() + addressEntity.getDistrict() + "," + addressEntity.getDetailAddress() +
",联系人:" + contact + ",邮箱:" + email + ",座机:" + telephone + ",手机:" + mobile +
",请核实该地址是否在经销商服务范围内,如不在服务范围内,请协调处理。</p>"+"<br/><br/>";
2.2)由于当前调用方与邮件接口不在同一个服务,需要跨服务调用
/**
* @param toEmail 要发送的邮箱
* @param map
* content:内容(必填)
* subject:主题(必填)
* name:发送人(必填)
* type:类型(必填),0:开通账号 1:发布内购方案 2:新增办公地址
* code:类型所属编码(必填),type=0,传公司名称,type=1,传内够方案编号 type=2,传公司名称
* attAddress:附件地址,非必填,多个附件以“,”隔开
*/
@RequestMapping(value = "/csms/auth/email/send", consumes = "application/json")
void sendEmail(@RequestParam("toEmail") List<String> toEmail,@RequestBody() Map<String,Object> map) ;
2.2)邮件服务接口
Controller
@RestController
@RequestMapping("/csms/auth/email")
public class EmailController {
@Autowired
private EmailService emailService;
/**
* @param toEmail 要发送的邮箱
* @param map
* content:内容(必填)
* subject:主题(必填)
* name:发送人(必填)
* type:类型(必填),0:开通账号 1:发布内购方案 2:新增办公地址
* code:类型所属编码(必填),type=0,传公司名称,type=1,传内够方案编号 type=2,传公司名称
* attAddress:附件地址,非必填,多个附件以“,”隔开
*/
@RequestMapping("/send")
public void sendEmail(@RequestParam List<String> toEmail,@RequestBody Map<String,Object> map) {
emailService.sendMail(toEmail,map);
}
}
ServiceImp
@Service
public class EmailService {
private static Logger logger = LoggerFactory.getLogger(EmailService.class);
private static final String EMAIL_SENDER_DEFAULT_NICK = "集团应用系统邮箱";
private ExecutorService executor = Executors.newFixedThreadPool(5);
private static final String FILE_PATH = "/data/nfs/upload/";
private static final String FROM_MAIL = "systemadmin@saicmotor.com";
private static final String MAIL_SMTP_HOST= "smtp.saicmotor.com";
@Autowired
private EmailLogMapper emailLogMapper;
public void sendMail(List<String> toEmail, Map<String, Object> map) {
executor.execute(new Runnable() {
@Override
public void run() {
for (String email : toEmail) {
try {
send(email, map);
} catch (Exception e) {
e.printStackTrace();
sendError(map.get("name").toString(), email, e.toString(), map);
}
}
}
});
}
private void send(String email, Map<String, Object> map) throws Exception {
logger.info("开始给{}发送邮件.....", email);
System.setProperty("mail.mime.splitlongparameters","false");
Properties props = System.getProperties();
props.put("mail.smtp.host", MAIL_SMTP_HOST);
props.put("mail.smtp.port", 25);
props.put("mail.smtp.auth", "false");
props.put("mail.mime.splitlongparameters","false");
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true, "UTF-8");
mimeMessageHelper.setTo(email);
mimeMessageHelper.setFrom(new InternetAddress(MimeUtility.encodeText(EMAIL_SENDER_DEFAULT_NICK) + "<" + FROM_MAIL + ">"));
mimeMessageHelper.setText(map.get("content").toString(), true);// 设置邮件主题内容
mimeMessageHelper.setSubject(map.get("subject").toString());
if (map.get("attAddress") != null) {
List<String> attAddresss = Splitter.on(",").splitToList(map.get("attAddress").toString());
logger.info("发送的附件:{}", attAddresss);
for (String attachment : attAddresss) {
FileSystemResource file = new FileSystemResource(new File(FILE_PATH + attachment));
String fileName = MimeUtility.encodeText(file.getFilename());
logger.info("FileName is {},fileName={}",file.getFilename(),fileName);
mimeMessageHelper.addAttachment(fileName, file);
// mimeMessageHelper.addAttachment(MimeUtility.encodeWord(file.getFilename(), "B", "UTF-8"), file);
}
}
Transport.send(message);
logger.info("给{}发送邮件成功!", email);
}
private void sendError(String name,String email, String error,Map<String, Object> map){
logger.error("发送人:{},给{}发送邮件失败!", name, email);
EmailLogEntity entity = new EmailLogEntity();
entity.setName(name);
entity.setAttachment(map.get("attAddress") != null ? map.get("attAddress").toString() : null);
entity.setContent(map.get("content").toString());
entity.setSubject(map.get("subject").toString());
entity.setType(Integer.valueOf(map.get("type").toString()));
entity.setToEmail(email);
entity.setCode(map.get("code").toString());
entity.setCreateTime(new Date());
entity.setCreateUser(name);
entity.setUpdateTime(new Date());
entity.setUpdateUser(name);
entity.setIsDel(DeleteStatusE.USEFUL.getValue());
entity.setDescription(error);
emailLogMapper.insert(entity);
}
}
说明
2.2.1)发送邮件接口使用固定大小的线程池,重新启动一个线程异步执行,发送邮件功能,这样调用方主线程可以快速响应,不用等到发送邮件线程完全执行结束,因为如果附件比较大,发送邮件耗时比较长。
类似启用异步线程的业务场景还有上传功能,业务流程为:导入数据,数据落表,上传数据到服务器,查看导入数据
上传过程比较耗时,通过线程异步执行。
2.2.2)这两个邮件地址如何理解
private static final String FROM_MAIL = "systemadmin@saicmotor.com";
private static final String MAIL_SMTP_HOST= "smtp.saicmotor.com";
mimeMessageHelper.setFrom(new InternetAddress(MimeUtility.encodeText(EMAIL_SENDER_DEFAULT_NICK) + "<" + FROM_MAIL + ">"));
2.2.3)上传附件
FILE_PATH:服务器路径
attAdress:文件服务器相对路径
new File("文件全路径")
private static final String FILE_PATH = "/data/nfs/upload/";
if (map.get("attAddress") != null) {
List<String> attAddresss = Splitter.on(",").splitToList(map.get("attAddress").toString());
logger.info("发送的附件:{}", attAddresss);
for (String attachment : attAddresss) {
FileSystemResource file = new FileSystemResource(new File(FILE_PATH + attachment));
String fileName = MimeUtility.encodeText(file.getFilename());
logger.info("FileName is {},fileName={}",file.getFilename(),fileName);
mimeMessageHelper.addAttachment(fileName, file);
// mimeMessageHelper.addAttachment(MimeUtility.encodeWord(file.getFilename(), "B", "UTF-8"), file);
}
}