个人博客项目地址
希望各位帮忙点个star,给我加个小星星:sparkles:
有时候代码执行完之后,需要邮件进行通知,所以通过工作中的项目和网上的资料,特地去学习了如何使用Java发送邮件。Demo使用的是QQ邮箱进行邮件发送,可以先了解一下基础文档协议 RFC882、MIME、SMTP等 。
看了孤傲苍狼的文章,关于邮件协议,他解释的很好,这边进行记录了一下
RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两个部分,邮件头和邮件体之间使用空行分隔。
在我们的实际开发当中,一封邮件既可能包含图片,又可能包含有附件,在这样的情况下,RFC882文档规定的邮件格式就无法满足要求了。
MIME协议是对RFC822文档的升级和补充,它描述了如何生产一封复杂的邮件。通常我们把MIME协议描述的邮件称之为MIME邮件。MIME协议描述的数据称之为MIME消息。 对于一封复杂邮件,如果包含了多个不同的数据,MIME协议规定了要使用分隔线对多段数据进行分隔,并使用 Content-Type头字段 对数据的类型、以及多个数据之间的关系进行描述。
要使用QQ邮箱发送邮件,就要遵守SMTP协议。 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议 ,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
需要在QQ邮箱中 打开SMTP服务和生成授权码
demo使用的是Velocity模板引擎进行html渲染,其它渲染方式类似,最后都是生成context内容。
java mail/spring-context-support/velocity
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.1' compile group: 'org.springframework', name: 'spring-context-support', version: '5.0.8.RELEASE' compile group: 'org.apache.velocity', name: 'velocity', version: '1.7' 复制代码
public class MailBean { /** 邮件发送人地址,非空 */ private String from; /** 邮件发送人姓名,非空 */ private String fromName; /** 邮件接收人地址列表,非空 */ private String[] toList; /** 邮件抄送人地址列表 */ private String[] ccList; /** 邮件主题,非空 */ private String subject; /** 邮件内容velocity上下文参数 */ private Map<String, Object> mailContext; /** 邮件内容velocity模板,非空 */ private String mailVmName; ··· } 复制代码
public class VelocityUtils { private static final Logger LOGGER = LoggerFactory.getLogger(VelocityUtils.class); private static final VelocityEngine VE = new VelocityEngine(); static { initVelocity(); } private static void initVelocity() { try { VE.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); VE.setProperty( "classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); VE.setProperty(RuntimeConstants.RUNTIME_LOG, "logs/velocity.log"); VE.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogChute"); VE.init(); } catch (Exception e) { LOGGER.warn("初始化velocity模板引擎失败", e); } } /** 实际渲染的代码,map里面的字段与编写的模板相对应 **/ public static String render(String vmName, Map<String, Object> context) { String renderStr = ""; try { Template template = VE.getTemplate(vmName, "UTF-8"); VelocityContext velocityContext = new VelocityContext(); for (Map.Entry<String, Object> entry : context.entrySet()) { velocityContext.put(entry.getKey(), entry.getValue()); } StringWriter sw = new StringWriter(); template.merge(velocityContext, sw); renderStr = sw.toString(); } catch (Exception e) { LOGGER.warn("渲染vm模板失败", e); } return renderStr; } } 复制代码
我们使用spring进行依赖注入,帮我们托管mailSender
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <!-- <property name="host" value="smtp.qq.com"/> --> <property name="host" value="smtp.qq.com"/> <property name="port" value="587"/> <!-- <property name="username" value="xxxxx@qq.com"/> --> <property name="username" value="xxxxxx@qq.com"/> <!-- qq邮箱的授权码,如果是企业邮箱,则使用登录密码 --> <property name="password" value="xxxxxxxxxxx"/> <property name="javaMailProperties"> <props > <prop key="mail.smtp.auth">true</prop> </props> </property> </bean> 复制代码
public interface MailService { /** * 发送邮件 * * @param mailBean 邮件bean */ void sendMail(MailBean mailBean); } @Service public class MailServiceImpl implements MailService { @Autowired @Qualifier("javaMailSender") private JavaMailSender mailSender; @Override public void sendMail(MailBean mailBean) { // 省略了校验 try { // 工具类进行内容渲染,传入的是模板名称和具体内容MAP String mailContent = VelocityUtils.render( mailBean.getMailVmName(), mailBean.getMailContext()); MimeMessage msg = mailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(msg, true, "UTF-8"); mimeMessageHelper.setFrom(mailBean.getFrom(), mailBean.getFromName()); mimeMessageHelper.setSubject(mailBean.getSubject()); mimeMessageHelper.setTo(mailBean.getToList()); mimeMessageHelper.setText(mailContent, true); mailSender.send(msg); } catch (Exception e) { log.warn("邮件发送失败,mailBean={}", mailBean, e); } } } 复制代码
<html xmlns="http://www.w3.org/1999/xhtml "> <body class="word-style"> <div class="title" align="center">DEMO</div> <br/> <div class="indent">$!{msg}</div> </body> </html> 复制代码
最后通过调用 MailService 进行邮件发送
MailBean mailBean = new MailBean(); mailBean.setFrom("xxxxxx@qq.com"); mailBean.setFromName("DEMO"); mailBean.setSubject("Are you ok"); //模板 mailBean.setMailVmName("demo.vm"); //收件人地址 String[] toList = {"xxxxx@xxxx.com"}; mailBean.setToList(toList); Map<String, Object> context = new HashMap<>(); context.put("msg", "I'm fine, thank you~"); mailBean.setMailContext(context); mailService.sendMail(mailBean); 复制代码
当然,你可以制作更加好看的html邮件~