关键要点
当使用Java发送电子邮件时,以下是一些关键要点:
- 导入依赖库:确保项目中包含JavaMail库的依赖项。通常使用Maven或Gradle等构建工具来管理依赖关系。
- 配置邮件服务器参数:提供邮件服务器的主机名、端口号、协议(如SMTP)以及可能需要的身份验证信息(如用户名和密码)。
- 创建邮件会话:使用javax.mail.Session类创建与邮件服务器的会话。在会话中,指定服务器参数和身份验证信息。
- 构造邮件对象:使用javax.mail.internet.MimeMessage类构造邮件对象。设置发件人、收件人、主题和正文等信息。
- 设置邮件内容:使用javax.mail.internet.MimeMessageHelper类或其他适当的方式设置邮件的内容。可以支持HTML内容、附件和其他邮件特性。
- 发送邮件:通过javax.mail.Transport类的send方法发送邮件。提供构建的邮件对象作为参数。
- 处理异常:使用try-catch块捕获javax.mail.MessagingException异常,并适当处理发送邮件过程中可能发生的异常情况。
- 附加操作(可选):根据需求,可能需要添加更多功能,如抄送、密送、回复地址、邮件优先级等。
请注意,发送邮件的具体实现方式可能因邮件服务器的不同而有所差异。在使用JavaMail发送邮件之前,需要先了解所使用的邮件服务器的要求和配置。另外,保护用户数据的安全性也是非常重要的,建议采取适当的安全措施,如使用SSL/TLS加密连接或使用授权码代替密码进行身份验证。
发送邮件原理
发件人【设置授权码】 - SMTP协议【Simple Mail TransferProtocol - 是一种提供可靠且有效的电子邮件传输的协议】 - 收件人
获取授权码
开通POP3/SMTP,获取授权码
SpringBoot中邮件发送
导入依赖
<!--对邮件的支持jar-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置邮箱
spring:
mail:
host: smtp.qq.com # 设置邮箱主机(服务商),这里使用QQ邮件服务器
username: 1184266892@qq.com # 设置用户名 - 发送方
password: xjirjxexiadciafb # 设置密码,该处的密码是QQ邮箱开启SMTP的授权码而非QQ密码
properties:
mail:
smtp:
auth: true # 必须进行授权认证,它的目的就是阻止他人任意乱发邮件
starttls: #SMTP加密方式:连接到一个TLS保护连接
enable: true
required: true
发送简单邮件
@SpringBootTest(classes = ApplicationStart.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class EmailTest {
@Autowired
private JavaMailSender javaMailSender;
@Test
public void send1(){
SimpleMailMessage mailMessage = new SimpleMailMessage();
//设置发送人
mailMessage.setFrom("1104829999@qq.com");
//邮件主题
mailMessage.setSubject("新型冠状病毒防护指南");
//邮件内容:普通文件无法解析html标签
mailMessage.setText("<h1>好好在家待着.....</h1>");
//收件人
mailMessage.setTo("659769499@qq.com");
//发送邮件
javaMailSender.send(mailMessage);
}
}
发送复杂邮件
@Test
public void send2() throws MessagingException {
//创建复杂邮件对象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//发送复杂邮件的工具类
//true - 能够添加附件
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");
helper.setFrom("1104829999@qq.com");
helper.setSubject("店铺激活邮件");
//true - 能够再内容中编写html标签 - 会解析
helper.setText("<h1>你的店铺已经注册!!!</h1><img src='http://dfs.java.itsource.cn/group1/M00/00/B9/rBE3kWD_fEuALou2AAB4rV4bI7c231.jpg' ><a href='http://localhost:8080/shop/active/22'>点击该链接激活</a>",true);
//添加附件
helper.addAttachment("p7.jpg",new File("C:\\Users\\Administrator\\Pictures\\photos\\p7.jpg"));
helper.addAttachment("g1.gif", new File("C:\\Users\\Administrator\\Pictures\\g1.gif"));
//收件人
helper.setTo("659769499@qq.com");
javaMailSender.send(mimeMessage);
}
抽取发送邮件工具类
这个地方有个问题, 就是非spring管理的类需要注入springIOC容器中的bean, 这个地方不细说了直接使用一个工具类SpringUtils帮助我们获取spring中的bean对象,getBean()方法
package com.noting.basic.utils;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
/**
* 发送邮件工具类
* 这里是非spring管理的类使用spring,ioc容器中的bean:JavaMailSender,
* 需要 使用另一个工具类SpringUtils获取bean对象
*/
public class EmailUtils {
/**
* 发送复杂邮件
* @param from 发件人
* @param to 收件人
* @param subject 邮件标题
* @param text 邮件内容
*/
public static void sendComplexMail(String from, String to, String subject, String text){
try {
// 调用SpringUtils工具类获取bean对象
JavaMailSender javaMailSender = SpringUtils.getBean(JavaMailSender.class);
//创建复杂邮件对象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//发送复杂邮件的工具类
//true - 能够添加附件
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");
// 发件人
helper.setFrom(from);
// 添加标题
helper.setSubject(subject);
//true - 能够再内容中编写html标签 - 会解析
helper.setText(text,true);
// 收件人
helper.setTo(to);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
/**
* 发送简单邮件
* @param from 发件人
* @param to 收件人
* @param subject 邮件标题
* @param text 邮件内容
*/
public static void sendSimpleMail(String from, String to, String subject, String text){
// 调用SpringUtils工具类获取bean对象
JavaMailSender javaMailSender = SpringUtils.getBean(JavaMailSender.class);
// 创建简单邮件对象
SimpleMailMessage mailMessage = new SimpleMailMessage();
// 发件人
mailMessage.setFrom(from);
// 添加标题
mailMessage.setSubject(subject);
// 添加文本
mailMessage.setText(text);
// 收件人
mailMessage.setTo(to);
javaMailSender.send(mailMessage);
}
}
获取IOC容器中bean的工具类SpringUtils
package com.noting.basic.utils;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Author:
* @Date:
* @Desc: spring工具类 方便在非spring管理环境中获取bean
* @Version 1.0
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
/**
* Spring应用上下文环境
*/
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext applicationContext;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
/**
* 通过名称获取对象
*
* @param name
* @return Object
* @throws org.springframework.beans.BeansException
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}
/**
* 通过类型获取对象
*
* @param clz
* @return requiredType
* @throws org.springframework.beans.BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory中,有与name相同名称的的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return beanFactory.containsBean(name);
}
/**
* 判断对应name名称注册的bean定义是一个singleton还是一个prototype。 找不到结果,抛出NoSuchBeanDefinitionException异常
* @param name
* @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isSingleton(name);
}
/**通过名称获取bean对象的类型
* @param name
* @return Class
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getType(name);
}
/**
* 通过名称获取该bean定义的别名
*
* @param name
* @return
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getAliases(name);
}
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
}
/**
* 获取当前的环境配置,如果无配置,则返回null
*
* @return 当前的环境配置
*/
public static String[] getActiveProfiles() {
return applicationContext.getEnvironment().getActiveProfiles();
}
/**
* 获取当前的环境配置,当有多个环境配置时,只获取第一个
*
* @return 当前的环境配置
*/
public static String getActiveProfile() {
final String[] activeProfiles = getActiveProfiles();
return ObjectUtil.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
}
}