一、java发邮件

  1. 电子邮件服务器:这些邮件服务器就类似于邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中,按功能划分有两种类型

    • SMTP邮件服务器:用户替用户发送邮件和接收外面发送给本地用户的邮件
    • POP3/IMAP邮件服务器:用户帮助用户读取SMTP邮件服务器接收进来的邮件
  2. 邮件传输协议:电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行邮件传递,就需遵守一定的规则
    • SMTP协议:全称为 Simple Mail Transfer Protocol,简单邮件传输协议。它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则
    • POP3协议:全称为 Post Office Protocol,邮局协议。它定义了邮件客户端软件和POP3邮件服务器的通信规则
    • IMAP协议:全称为 Internet Message Access Protocol,Internet消息访问协议,它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则
  3. 邮件格式:邮件内容的基本格式和具体细节分别是由 RFC822 文档和 MIME 协议定义的
    • RFC822文档中定义的文件格式包括两个部分:邮件头和邮件体
    • ME协议(Multipurpose Internet Mail Extensions )用于定义复杂邮件体的格式,使邮件的内容更加多样化
  4. 邮件发送与接收流程
      • 邮件客户端软件写好一封邮件,交到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>
  1. 邮件的基本信息类

    @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;
    } }
  2. 权限认证类

    @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);
    }
    }
  3. 发送邮件工具类

    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>
  1. 邮件的基本信息类

    @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; }
  2. 准备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
  3. 加载配置文件,初始化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 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;
    } }
  4. 邮件发送工具类

    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>
  1. 修改配置

    # 邮件的设置 导入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
  2. 直接在service层中使用即可

    public MailServiceImpl {
    
       @Autowired
    private JavaMailSender javaMailSender; // 以下代码使用即可
    ...
    }

1.使用javax.mail, spring的JavaMailSender,springboot发送邮件的更多相关文章

  1. spring -java.lang.NoClassDefFoundError: javax/mail/MessagingException

    今天遇到这个问题,网上找了半天,终于解决了,最后记录一下. spring集成了mail,于是就测试了下,结果报了java.lang.NoClassDefFoundError: javax/mail/M ...

  2. javax.mail 发送邮件 , greenMail 测试 , spring

    发送邮件接口: package com.manxu.archetype.account.email; import javax.security.auth.login.AccountException ...

  3. 利用springframework+javax.mail发邮件(普通邮件、带附件邮件、HTML格式邮件)

    Spring提供了发送电子邮件的支持,可以发送普通邮件.带附件邮件.HTML格式邮件,甚至还可以使用Velocity模板定制化邮件内容. 一.引入相关的库 1 2 3 4 5 6 7 8 9 10 1 ...

  4. 使用spring的JavaMailSender发送邮件

    一:pom.xml <!-- java邮件 -->      <dependency>          <groupId>javax.mail</group ...

  5. java使用javax.mail进行免费的邮件发送

    1. 建议发送方使用阿里云邮箱https://mail.aliyun.com/,阿里云默认是开启个人邮箱pop3.smtp协议的,所以无需在阿里云邮箱里设置,pop3.smtp的密码默认邮箱登录密码, ...

  6. javax.mail 发送邮件异常

    一.运行过程抛出异常 1.Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/ ...

  7. javamail中的 javax.mail.AuthenticationFailedException: failed to connect

    java.lang.RuntimeException: javax.mail.AuthenticationFailedException: failed to connect javax.mail.A ...

  8. javax.mail.MessagingException: 501 Syntax: HELO hostname Linux端异常解决

    在项目里面使用javamail在window环境正常,放在服务器上面的时候抛出异常javax.mail.MessagingException: 501 Syntax: HELO hostname ,原 ...

  9. javax.mail用smtp服务器发送带附件的邮件

    jar包: javax.mail-1.5.5.jar maven配置: <dependency> <groupId>com.sun.mail</groupId> & ...

随机推荐

  1. 009 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 03 什么是变量?

    009 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 03 什么是变量? 什么是变量? 形象化的生活中的例子理解什么是变量以及变量的三个元素 我们可以根据客人要求 ...

  2. Java知识系统回顾整理01基础03变量04类型转换

    一.不同类型之间的数据可以互相转换,但是要满足一定的规则 二.数据类型转换规则 转换规则如图所示  精度高的数据类型就像容量大的杯子,可以放更大的数据 精度低的数据类型就像容量小的杯子,只能放更小的数 ...

  3. python排序算法总结和实现

    ------------------希尔排序------------- 一直没搞懂希尔排序怎么搞得 def Shell_sort(L): step = len(L)/2 while step > ...

  4. Nuxt/Vue自定义导航栏Topbar+标签栏Tabbar组件

    基于Vue.js实现自定义Topbar+Tabbar组件|仿咸鱼底部凸起导航 最近一直在倒腾Nuxt项目,由于Nuxt.js是基于Vue.js的服务端渲染框架,只要是会vue,基本能很快上手了. 一般 ...

  5. # BlackLivesMatter !

    下载 # BlackLivesMatter ! https://blacklivesmatter.com/ 黑人的生命是重要的运动资源 VueCroppie VueCroppie是一个Vue 2包装C ...

  6. 用< 100行代码向EPUB或Web服务器添加视频回放

    下载source - 32.3 KB 下载latest version from GituHub 介绍 在我 在关于CodeProject的前一篇文章中,我展示了一个简单的EPUB查看器 Androi ...

  7. 设置 eclipse C++ 版本

    gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 默认是使用 C++ 98 版本进行编译 设置 eclipse 中 C++ 的版本: Project  -& ...

  8. ARM-Linux S5PV210 UART驱动(转)

    ARM-Linux S5PV210 UART驱动(3)----串口核心层.关键结构体.接口关系 尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现t ...

  9. 【二分图】HEOI2012 朋友圈

    题目内容 洛谷链接 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着. 一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大 ...

  10. 自定义常用input表单元素一:纯css 实现自定义checkbox复选框

    最下面那个是之前写的  今天在做项目的时候发现,之前写的貌似还是有点多,起码增加的span标签可以去掉,这样保持和原生相同的结构最好的,仅仅是样式上的变化.今天把项目中的这个给更新上来.下面就直接还是 ...