1.使用javax.mail, spring的JavaMailSender,springboot发送邮件
一、java发邮件
- 电子邮件服务器:这些邮件服务器就类似于邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中,按功能划分有两种类型
- SMTP邮件服务器:用户替用户发送邮件和接收外面发送给本地用户的邮件
- POP3/IMAP邮件服务器:用户帮助用户读取SMTP邮件服务器接收进来的邮件
- 邮件传输协议:电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行邮件传递,就需遵守一定的规则
- SMTP协议:全称为 Simple Mail Transfer Protocol,简单邮件传输协议。它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则
- POP3协议:全称为 Post Office Protocol,邮局协议。它定义了邮件客户端软件和POP3邮件服务器的通信规则
- IMAP协议:全称为 Internet Message Access Protocol,Internet消息访问协议,它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则
- 邮件格式:邮件内容的基本格式和具体细节分别是由 RFC822 文档和 MIME 协议定义的
- RFC822文档中定义的文件格式包括两个部分:邮件头和邮件体
- ME协议(Multipurpose Internet Mail Extensions )用于定义复杂邮件体的格式,使邮件的内容更加多样化
- 邮件发送与接收流程
-
- 邮件客户端软件写好一封邮件,交到SMTP的QQ邮件服务器
- QQ邮箱会解析用户发送的邮件,判断收件地址是否是自己的账户,如果收件也是QQ邮箱,会直接存放到自己的存储空间。如果不是QQ邮箱,而是163邮箱,那么QQ邮箱会将邮件转发到163邮箱服务器,转发协议也是SMTP
- 163邮箱服务器接收到QQ邮箱转发过来的邮件,会判断收件地址是否是自己的,如果是自己的账户,就会将QQ邮箱转发过来的邮件存放到自己的内部存储空间
- 用户A将邮件发送了之后,通知用户B去指定的邮箱收取邮件。用户B会通过邮件客户端软件先向163邮箱服务器请求,要求收取自己的邮件
- 163邮箱服务器收到用户B的请求后,会从自己的存储空间中取出B未收取的邮件
- 163邮箱服务器取出用户B未收取的邮件后,将邮件发给用户B,最后三步用户B收取邮件的过程,使用的协议是POP3
-
二、使用javax.mail发送邮件(简单,带图片,带附件,带图片和附件)
-
使用之前应该申请qq邮箱的授权码(第三方的使用时,替代密码)
-
qq邮箱邮件服务器地址和端口(smtp.qq.com 端口465或587)
-
导入依赖
-
<!--发送邮件的jar 1.4 版本会出现javamail.providers 文件找不见 与其他jar包中文件冲突--> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.4</version> </dependency>
-
邮件的基本信息类
@Data public class JavaMailInfo { /** * 使用java mail 发送邮件 邮件的协议有SMTP POP IMAP MIME 等 协议具体内容可自行百度 SMTP 为简单邮件传输协议 比较常用 */ // 邮件服务器地址 private String mailSeverHost; // 邮件服务器端口 private String mailServerPort; // 邮件发送者 private String fromAddress; // 发送者用户名 private String userName; // 发送者密码 private String password; // 收件人地址 private String toAddress; // 邮件主题 private String subject; // 邮件内容 private String content; // 图片地址集合 private List<String> photoUrlList; // 附件地址集合 private List<String> attachList; /** * 获取邮件会话属性 ,对邮件Session进行设置 此部分的内容可以通过加载配置文件的方式进行设置 * @return */ public Properties getProperties() { Properties properties = new Properties(); properties.put("mail.transport.protocol", "smtp");// 连接协议 properties.put("mail.smtp.host", this.mailSeverHost);// 主机名 properties.put("mail.smtp.port", this.mailServerPort);// 端口号 properties.put("mail.smtp.auth", "true");//设置smtp是否需要认证 properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用 properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息 properties.put("mail.smtp.timeout", 20000);// 超时时间 return properties; } }
-
权限认证类
@Data @NoArgsConstructor @AllArgsConstructor public class MyJavaMailAuthenticator extends Authenticator { private String userName = null; private String password = null; /** * 此类用于储存授权时使用的用户名和密码 用于构建邮件Session对象 便于需要认证时邮件Session知道需要使用哪个类验证 * 以用户名、密码的方式访问那些受到保护的资源,在这里“资源”就是指邮件服务器 * 自定义的类需要继承Authenticator类 重写getPasswordAuthentication() 方法 注意导包 需要使用javax.mail包下的相关类 */ @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(this.userName, this.password); } }
-
发送邮件工具类
public class JavaMailSendUtils { /** * 实际使用 * @param args */ public static void main(String[] args) { JavaMailInfo javaMailInfo = new JavaMailInfo(); javaMailInfo.setMailSeverHost("smtp.qq.com"); javaMailInfo.setMailServerPort("465");// 465或587(使用ssl) javaMailInfo.setFromAddress("发件人"); javaMailInfo.setUserName("您邮箱用户名"); javaMailInfo.setPassword("您邮箱授权码");// 密码需要使用对应邮箱的授权码授权码 javaMailInfo.setToAddress("收件人"); javaMailInfo.setSubject("邮件主题"); javaMailInfo.setContent("邮件内容"); List<String> photoUrlList = new ArrayList<>(); photoUrlList.add("图片1"); photoUrlList.add("图片2"); javaMailInfo.setPhotoUrlList(photoUrlList); List<String> attachList = new ArrayList<>(); attachList.add("附件1"); attachList.add("附件2"); javaMailInfo.setAttachList(attachList); sendJavaMail(javaMailInfo); } /** * 此工具类可根据邮件基本信息进行邮件的发送 */ /** * 发送邮件方法 * @param javaMailInfo * @return */ public static boolean sendJavaMail(JavaMailInfo javaMailInfo) { // 获取邮件session的相关配置参数 Properties properties = javaMailInfo.getProperties(); // 创建授权验证类 MyJavaMailAuthenticator myJavaMailAuthenticator = new MyJavaMailAuthenticator(); myJavaMailAuthenticator.setUserName(javaMailInfo.getUserName()); myJavaMailAuthenticator.setPassword(javaMailInfo.getPassword()); // 构建邮件Session会话对象 带不带default均可 查看源码可知 带default的是获取该类的属性 不带获取的是新创建的 Session mailSession = Session.getDefaultInstance(properties, myJavaMailAuthenticator); // 开启debug properties中设置了此处就无须设置 // mailSession.setDebug(true); // 邮差对象 也可使用静态方法进行发送 Transport transport = null; try { // 获取消息 也就是发送的内容 // Message message = createSimpleMail(mailSession, javaMailInfo); // Message message = createImageMail(mailSession, javaMailInfo); // Message message = createAttachMail(mailSession, javaMailInfo); Message message = createPhotoAndAttachMail(mailSession, javaMailInfo); // 设置规范 具体是什么规范呢? 固定写法 MailcapCommandMap defaultCommandMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); defaultCommandMap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); defaultCommandMap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); defaultCommandMap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); defaultCommandMap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); defaultCommandMap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); CommandMap.setDefaultCommandMap(defaultCommandMap); // 发送邮件 Transport.send(message); 或者获取Transport对象发送 transport = mailSession.getTransport(); transport.connect(javaMailInfo.getUserName(), javaMailInfo.getUserName()); transport.sendMessage(message, message.getAllRecipients()); System.out.println("邮件发送成功"); return true; } catch (MessagingException e) { e.printStackTrace(); System.out.println("邮件发送失败"); return false; } finally { if (null != transport) { try { transport.close(); } catch (MessagingException e) { e.printStackTrace(); } } } } /** * 根据邮件Session和邮件信息创建邮件内容(文本类 html) * @param mailSession * @param javaMailInfo * @return */ private static Message createSimpleMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException { /** * Message是一 个抽象类,我们使用MimeMessage这个子类, 该类是使用MIME类型、MIME信息头的 邮箱信息 * 信息头只能使用US-ASCII字符,而非ASCII字符将通过编码转换为ASCII的方式使用 */ // 根据邮件session创建消息对象 MimeMessage mimeMessage = new MimeMessage(mailSession); // 设置发件人 setFrom 和 setReplyTo 均可 有多个发件人使用 addFroms(Address[] addresses) mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress())); // 设置收件人 收件人类型 Message.RecipientType.TO(接受者) Message.RecipientType.CC(抄送着) Message.RecipientType.BCC(密送者) // setRecipients(Message.RecipientType var1, Address[] var2) 设置多个收件人 mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress())); // 设置标题 mimeMessage.setSubject(javaMailInfo.getSubject(), "text/plain;charset=utf-8"); // 设置内容 是文本可直接使用setText() mimeMessage.setContent(javaMailInfo.getContent(), "text/html;charset=utf-8"); // 设置发送时间 mimeMessage.setSentDate(new Date()); mimeMessage.saveChanges(); return mimeMessage; } /** * 根据邮件Session和邮件信息创建邮件内容(图片类 可多个图片) * @param mailSession * @param javaMailInfo * @return */ private static Message createImageMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException { /** * Message表示一个邮件,messgaes.getContent()返回一个Multipart对象。一个Multipart对象包含一个或多个BodyPart对象,来组成邮件的正文部分(包括附件) * Multipart的content-type * 总体来说,MIME消息由消息头和消息体两大部分组成。现在我们关注的是MIME邮件,因此在以下的讨论中姑且称“消息”为“邮件”。 * 邮件头包含了发件人、收件人、主题、时间、MIME版本、邮件内容的类型等重要信息。每条信息称为一个域,由域名后加“: ”和信息内容构成,可以是一行,较长的也可以占用多行。 * 域的首行必须“顶头”写,即左边不能有空白字符(空格和制表符);续行则必须以空白字符打头,且第一个空白字符不是信息本身固有的,解码时要过滤掉。 * 邮件体包含邮件的内容,它的类型由邮件头的“Content-Type”域指出。常见的简单类型有text/plain(纯文本)和text/html(超文本)。有时也会出现的multipart类型,是MIME邮件的精髓。 * 邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/related和multipart/alternative。 * multipart/mixed:附件。 * multipart/related:内嵌资源。 * multipart/alternative:纯文本与超文本共存。 */ MimeMessage mimeMessage = new MimeMessage(mailSession); mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress())); mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress())); mimeMessage.setSubject(javaMailInfo.getSubject(), "text/plain;charset=utf-8"); List<String> photoUrlList = javaMailInfo.getPhotoUrlList(); // 创建消息体 以下方式每个图片都有一个标题 MimeMultipart mimeMultipart = new MimeMultipart(); if (!CollectionUtils.isEmpty(photoUrlList)) { for (String photoUrl : photoUrlList) { MimeBodyPart text = new MimeBodyPart(); // 设置图片标题 注意img标签的引用位置 用cid:开头 String cid = UUID.randomUUID().toString(); text.setContent(javaMailInfo.getContent() +"<br/><img src=\'cid:"+ cid +".jpg\'>", "text/html;charset=utf-8"); // 使用数据处理器处理图片 MimeBodyPart image = new MimeBodyPart(); image.setDataHandler(new DataHandler(new FileDataSource(photoUrl))); image.setContentID(cid); // 描述正文和图片的关系 MimeMultipart photo = new MimeMultipart(); photo.addBodyPart(text); photo.addBodyPart(image); photo.setSubType("related"); MimeBodyPart mimeBodyPart = new MimeBodyPart(); mimeBodyPart.setContent(photo); // 将图片放入body中 mimeMultipart.addBodyPart(mimeBodyPart); } } /*// 以下方式所有图片公用一个标题 MimeMultipart photo = new MimeMultipart(); MimeBodyPart text = new MimeBodyPart(); photo.addBodyPart(text); StringBuilder textContent = new StringBuilder(javaMailInfo.getContent()); if (!CollectionUtils.isEmpty(photoUrlList)) { for (String photoUrl : photoUrlList) { // 设置图片标题 注意img标签的引用位置 用cid:开头 String cid = UUID.randomUUID().toString(); textContent.append("<br/><img src=\'cid:"+ cid +".jpg\'>"); // 使用数据处理器处理图片 MimeBodyPart image = new MimeBodyPart(); image.setDataHandler(new DataHandler(new FileDataSource(photoUrl))); image.setContentID(cid); // 描述正文和图片的关系 photo.addBodyPart(image); } photo.setSubType("related"); } text.setContent(textContent.toString(), "text/html;charset=utf-8");*/ // 设置消息体 mimeMessage.setContent(mimeMultipart); // mimeMessage.setContent(photo); mimeMessage.setSentDate(new Date()); mimeMessage.saveChanges(); return mimeMessage; } /** * 根据邮件Session和邮件信息创建邮件内容(附件类 可多个附件) * @param mailSession * @param javaMailInfo * @return */ private static Message createAttachMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException { MimeMessage mimeMessage = new MimeMessage(mailSession); mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress())); mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress())); mimeMessage.setSubject(javaMailInfo.getSubject(), "text/plain;charset=utf-8"); List<String> attachList = javaMailInfo.getAttachList(); // 创建消息体 MimeMultipart mimeMultipart = new MimeMultipart(); MimeBodyPart text = new MimeBodyPart(); text.setContent(javaMailInfo.getSubject(), "text/html;charset=utf-8"); mimeMultipart.addBodyPart(text); if (!CollectionUtils.isEmpty(attachList)) { for (String attach : attachList) { // 创建附件 MimeBodyPart mimeBodyPart = new MimeBodyPart(); DataHandler dataHandler = new DataHandler(new FileDataSource(attach)); mimeBodyPart.setDataHandler(dataHandler); mimeBodyPart.setFileName(dataHandler.getName()); // 加入最外面的容器 mimeMultipart.addBodyPart(mimeBodyPart); } // 描述关系 mimeMultipart.setSubType("mixed"); } mimeMessage.setContent(mimeMultipart); mimeMessage.setSentDate(new Date()); mimeMessage.saveChanges(); return mimeMessage; } /** * 根据邮件Session和邮件信息创建邮件内容(多图片 多附件) * @param mailSession * @param javaMailInfo * @return */ private static Message createPhotoAndAttachMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException { MimeMessage mimeMessage = new MimeMessage(mailSession); mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress())); mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress())); List<String> photoUrlList = javaMailInfo.getPhotoUrlList(); // 获取所有的图片 公用一个主题 MimeMultipart photo = new MimeMultipart(); MimeBodyPart text = new MimeBodyPart(); photo.addBodyPart(text); StringBuilder textContent = new StringBuilder(javaMailInfo.getContent()); if (!CollectionUtils.isEmpty(photoUrlList)) { for (String photoUrl : photoUrlList) { // 设置图片标题 注意img标签的引用位置 用cid:开头 String cid = UUID.randomUUID().toString(); textContent.append("<br/><img src=\'cid:"+ cid +".jpg\'>"); // 使用数据处理器处理图片 MimeBodyPart image = new MimeBodyPart(); image.setDataHandler(new DataHandler(new FileDataSource(photoUrl))); image.setContentID(cid); // 描述正文和图片的关系 photo.addBodyPart(image); } photo.setSubType("related"); } text.setContent(textContent.toString(), "text/html;charset=utf-8"); // 将图片包裹成一个body 作为 其内容 MimeBodyPart content = new MimeBodyPart(); content.setContent(photo); // 获取所有的附件 List<String> attachList = javaMailInfo.getAttachList(); MimeMultipart attach = new MimeMultipart(); if (!CollectionUtils.isEmpty(attachList)) { for (String attachUrl : attachList) { // 创建附件 MimeBodyPart mimeBodyPart = new MimeBodyPart(); DataHandler dataHandler = new DataHandler(new FileDataSource(attachUrl)); mimeBodyPart.setDataHandler(dataHandler); mimeBodyPart.setFileName(dataHandler.getName()); // 加入最外面的容器 attach.addBodyPart(mimeBodyPart); } } // 将图片body 和 附件组合 attach.addBodyPart(content); attach.setSubType("mixed"); mimeMessage.setContent(attach); mimeMessage.setSentDate(new Date()); mimeMessage.saveChanges(); return mimeMessage; } }
三、使用spring的JavaMailSender发送邮件(简单,带图片,带附件,带图片和附件,freemarker模板)
-
spring提供的JavaMailSender是对原始的javax.mail进行了简化
-
再其使用过程中可以注册到spring容器中,也可不用注册
-
导入依赖
-
javax.mail的依赖包 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>
-
邮件的基本信息类
@Data public class JavaMailSenderInfo { // 收件人地址 private String toAddress; // 邮件主题 private String subject; // 邮件内容 private String content; // 是否是html 注意字段boolean类型 不要用is开头 idea会生成get,set方法会进行优化 isHtml -> isHtml(),getHtml() -- html -> isHtml(),getHtml() private boolean html = false; // 图片地址集合 private List<String> photoList; // 附件地址集合 private List<String> attachList; }
-
准备mail.propertise配置文件(也就是设置会话的属性),文件放在resource目录下
#传输协议 mail.transport.protocol=smtp #服务器主机名 mail.smtp.host=smtp.qq.com #服务器端口号 465或587(使用ssl) mail.smtp.port=465 #是否进行用户名密码校验 配置了否 就不能配置 用户名和密码 否则会去获取用户名密码进行验证 mail.smtp.auth=true #设置是否使用ssl安全连接 ---一般都使用 mail.smtp.ssl.enable=true #设置是否显示debug信息 true 会在控制台显示相关信息 mail.debug=true #设置超时时间 mail.smtp.timeout=20000 #编码格式 mail.smtp.defaultEncoding=utf-8 #你的邮箱地址 mail.smtp.username=xxxxxx@qq.com #你的授权码(第三方使用时代替密码) mail.smtp.password=xxxxxx
-
加载配置文件,初始化JavaMailSender
public class InitJavaMailSender { /** * 此类的作用是加载配置文件来创建JavaMailSender对象 JavaMailSenderImpl是该接口的实现类 * 因此我们需要对JavaMailSenderImpl进行配置 在spring的环境下 我们可以使用加载配置文件的方式 或者 * 在spring配置文件中直接配置该bean(由spring托管)使用时@Autowired直接注入即可 * <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> * <property name="host" value="${mail.smtp.host}" /> * <property name="username" value="${mail.smtp.username}" /> * <property name="password" value="${mail.smtp.password}" /> * <property name="defaultEncoding" value="${mail.smtp.defaultEncoding}" /> * <property name="javaMailProperties"> * <props> * <prop key="mail.smtp.auth">${mail.smtp.auth}</prop> * <prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop> * ... * </props> * </property> * </bean> * 本次采用加载配置文件的方式 * 由spring提供 其底层使用的仍然是javax.mail进行邮件的发送 * JavaMailSenderImpl 依赖javax.mail 和 spring-context-support包 */ // 传输协议 private static String protocol; // 服务器主机名 private static String host; // 服务器端口号 private static String port; // 是否进行用户名密码校验 private static String auth; // 设置是否使用ssl安全连接 private static String enableSSL; // 设置是否显示debug信息 private static String debug; // 超时时间 private static String timeout; // 编码格式 private static String defaultEncoding; // 邮箱地址 public static String username; // 授权码 private static String password; private static volatile JavaMailSenderImpl javaMailSenderImpl; static { init(); } private static void init() { // 加载配置文件 Properties properties = new Properties(); InputStream resourceAsStream = JavaMailSender.class.getClassLoader().getResourceAsStream("mail.properties"); try { properties.load(resourceAsStream); protocol = properties.getProperty("mail.transport.protocol"); host = properties.getProperty("mail.smtp.host"); port = properties.getProperty("mail.smtp.port"); auth = properties.getProperty("mail.smtp.auth"); enableSSL = properties.getProperty("mail.smtp.ssl.enable"); debug = properties.getProperty("mail.debug"); timeout = properties.getProperty("mail.smtp.timeout"); defaultEncoding = properties.getProperty("mail.smtp.defaultEncoding"); username = properties.getProperty("mail.smtp.username"); password = properties.getProperty("mail.smtp.password"); System.out.println("mail.properties加载成功"); } catch (IOException e) { e.printStackTrace(); System.out.println("mail.properties加载失败"); } finally { if (null != resourceAsStream) { try { resourceAsStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 使用单例获取JavaMailSender 双重检查既保证的线程安全 又保证了效率 又能起到延迟加载的作用 * @return */ public static JavaMailSender getJavaMailSender() { if (null == javaMailSenderImpl) { synchronized (InitJavaMailSender.class) { if (null == javaMailSenderImpl) { javaMailSenderImpl = new JavaMailSenderImpl(); javaMailSenderImpl.setProtocol(protocol); javaMailSenderImpl.setHost(host); javaMailSenderImpl.setPort(Integer.parseInt(port)); javaMailSenderImpl.setDefaultEncoding(defaultEncoding); javaMailSenderImpl.setUsername(username); javaMailSenderImpl.setPassword(password); Properties properties = new Properties(); properties.setProperty("mail.smtp.auth", auth); properties.setProperty("mail.smtp.ssl.enable", enableSSL); properties.setProperty("mail.debug", debug); properties.setProperty("mail.smtp.timeout", timeout); javaMailSenderImpl.setJavaMailProperties(properties); } } } return javaMailSenderImpl; } }
-
邮件发送工具类
public class JavaMailSenderUtils { /** * 测试发送邮件 实际中可以在service中使用(若使用的spring配置的方式创建JavaMailSender,则需注入使用) * 此处为方便使用main方法 * @param args */ public static void main(String[] args) { JavaMailSenderInfo javaMailSenderInfo = new JavaMailSenderInfo(); javaMailSenderInfo.setToAddress("发件人"); javaMailSenderInfo.setSubject("邮件主题"); javaMailSenderInfo.setContent("邮件内容"); javaMailSenderInfo.setHtml(true); List<String> list = new ArrayList<>(); list.add("图片1"); // list.add("图片2"); // list.add("图片3"); // list.add("图片4"); javaMailSenderInfo.setPhotoList(list); javaMailSenderInfo.setAttachList(list); // JavaMailSenderUtils.sendSimpleMail(javaMailSenderInfo); JavaMailSenderUtils.sendPhotoMail(javaMailSenderInfo); // JavaMailSenderUtils.sendAttacheMail(javaMailSenderInfo); // JavaMailSenderUtils.sendPhotoAndAttacheMail(javaMailSenderInfo); } private static final JavaMailSender javaMailSender = InitJavaMailSender.getJavaMailSender(); private static final String htmlStartStr = "<html><body>"; private static final String htmlEndStr = "</body></html>"; /** * 发送简单邮件 文本 html * @param javaMailSenderInfo * @return */ public static boolean sendSimpleMail(JavaMailSenderInfo javaMailSenderInfo) { // 创建邮件消息 简单邮件可直接使用SimpleMailMessage MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = null; try { // 创建消息辅助器 参数二 为true时为多组件 html 等 mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8"); // 设置公共字段 setMailCommonField(mimeMessageHelper, javaMailSenderInfo); // 文本内容 可指定是否是html mimeMessageHelper.setText(javaMailSenderInfo.getContent(), javaMailSenderInfo.isHtml()); javaMailSender.send(mimeMessage); System.out.println("简单邮件发送成功"); return true; } catch (MessagingException e) { e.printStackTrace(); System.out.println("简单邮件发送失败"); return false; } } /** * 发送带图片的邮件 * @param javaMailSenderInfo * @return */ public static boolean sendPhotoMail(JavaMailSenderInfo javaMailSenderInfo) { // 创建邮件消息 简单邮件可直接使用SimpleMailMessage MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = null; try { mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8"); setMailCommonField(mimeMessageHelper, javaMailSenderInfo); List<String> photoList = javaMailSenderInfo.getPhotoList(); // html内容 StringBuilder text = new StringBuilder(htmlStartStr); text.append(javaMailSenderInfo.getContent()); if (!CollectionUtils.isEmpty(photoList)) { for (String photo : photoList) { // 每个图片创建一个标题吧 每个图片关联一个cid String cid = UUID.randomUUID().toString(); text.append("<br/><h1>"+ javaMailSenderInfo.getSubject() +"</h1><br/><img src=\'cid:"+ cid +"\'/>"); mimeMessageHelper.addInline(cid, new File(photo)); } } // 为什么会有最后一个图片图裂不显示的问题(求大佬指点) // String cid = UUID.randomUUID().toString(); // mimeMessageHelper.addInline(cid, new File("")); text.append(htmlEndStr); mimeMessageHelper.setText(text.toString(),true); javaMailSender.send(mimeMessage); System.out.println("带图片的邮件发送成功"); return true; } catch (MessagingException e) { e.printStackTrace(); System.out.println("带图片的邮件发送失败"); return false; } } /** * 发送带附件的邮件 * @param javaMailSenderInfo * @return */ public static boolean sendAttacheMail(JavaMailSenderInfo javaMailSenderInfo) { // 创建邮件消息 简单邮件可直接使用SimpleMailMessage MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = null; try { mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8"); setMailCommonField(mimeMessageHelper, javaMailSenderInfo); List<String> attachList = javaMailSenderInfo.getAttachList(); // 邮件文本 mimeMessageHelper.setText(javaMailSenderInfo.getContent(), javaMailSenderInfo.isHtml()); if (!CollectionUtils.isEmpty(attachList)) { for (String attach : attachList) { // 添加附件(最后一个附件是图片也存在图裂的问题,但可下载使用,求大佬指点) FileSystemResource fileSystemResource = new FileSystemResource(attach); // 参数一为附件名称 mimeMessageHelper.addAttachment(fileSystemResource.getFilename(), fileSystemResource); } } javaMailSender.send(mimeMessage); System.out.println("带附件的邮件发送成功"); return true; } catch (MessagingException e) { e.printStackTrace(); System.out.println("带附件的邮件发送失败"); return false; } } /** * 发送带图片和附件的邮件 * @param javaMailSenderInfo * @return */ public static boolean sendPhotoAndAttacheMail(JavaMailSenderInfo javaMailSenderInfo) { // 创建邮件消息 简单邮件可直接使用SimpleMailMessage MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = null; try { mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8"); setMailCommonField(mimeMessageHelper, javaMailSenderInfo); List<String> photoList = javaMailSenderInfo.getPhotoList(); // 放入图片和内容 StringBuilder text = new StringBuilder(htmlStartStr + javaMailSenderInfo.getContent()); if (!CollectionUtils.isEmpty(photoList)) { for (String photo : photoList) { String cid = UUID.randomUUID().toString(); text.append("<br/><img src=\'cid:"+ cid +"\'>"); mimeMessageHelper.addInline(cid, new File(photo)); } } text.append(htmlEndStr); mimeMessageHelper.setText(text.toString(),true); // 放入附件 List<String> attachList = javaMailSenderInfo.getAttachList(); if (!CollectionUtils.isEmpty(attachList)) { for (String attach : attachList) { // 添加附件 FileSystemResource fileSystemResource = new FileSystemResource(attach); // 参数一为附件名称 mimeMessageHelper.addAttachment(fileSystemResource.getFilename(), fileSystemResource); } } javaMailSender.send(mimeMessage); System.out.println("带图片和附件的邮件发送成功"); return true; } catch (MessagingException e) { e.printStackTrace(); System.out.println("带图片和附件邮件发送失败"); return false; } } /** * 发送由freemarker模板技术生成的邮件 * @param javaMailSenderInfo * @return */ public static boolean sendFreemarkerMail(JavaMailSenderInfo javaMailSenderInfo) { // 创建邮件消息 简单邮件可直接使用SimpleMailMessage MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = null; try { mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8"); setMailCommonField(mimeMessageHelper, javaMailSenderInfo); /** * 此处没有实现采用模板技术(可自行探索) * 封装模板所需要的数据 * 读取freemarker的模板文件 xxx.ftl 进行静态化,生成html形式的字符串 * 将生成好的html字符串设置到邮件的正文中 */ javaMailSender.send(mimeMessage); System.out.println("freemarker模板技术生成的邮件发送成功"); return true; } catch (MessagingException e) { e.printStackTrace(); System.out.println("freemarker模板技术生成的邮件发送失败"); return false; } } /** * 设置邮件的公共字段 * @param mimeMessageHelper * @param javaMailSenderInfo * @throws MessagingException */ private static void setMailCommonField(MimeMessageHelper mimeMessageHelper, JavaMailSenderInfo javaMailSenderInfo) throws MessagingException { // 发件人 mimeMessageHelper.setFrom(InitJavaMailSender.username); // 收件人 多人用数组 mimeMessageHelper.setTo(javaMailSenderInfo.getToAddress()); // 主题 mimeMessageHelper.setSubject(javaMailSenderInfo.getSubject()); // 日期 mimeMessageHelper.setSentDate(new Date()); } }
四、使用springboot发送邮件
-
使用springboot发送邮件和使用spring提供的JavaMailSender发送邮件的方式一样
-
在yml配置文件中配置相关的会话信息后
-
在service层中直接注入使用即可
-
导入依赖
-
<!--springboot整合mail--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
-
修改配置
# 邮件的设置 导入mail启动包 使用时注入直接JavaMailSender即可 spring: mail: protocol: smtp host: smtp.qq.com port: 465 default-encoding: utf-8 username: 邮箱用户名 password: 邮箱授权码 test-connection: true properties: mail: debug: true smtp: auth: true timeout: 20000 ssl: enable: true
-
直接在service层中使用即可
public MailServiceImpl { @Autowired private JavaMailSender javaMailSender; // 以下代码使用即可 ... }