Java - JavaMail - 利用 JavaMail 发邮件的 小demo

1. 概述

  1. 面试的时候, 被问到一些乱七八糟的运维知识
  2. 虽然我不是干运维的, 但是最后却告诉我专业知识深度不够, 感觉很难受
  3. 又回到了一个烦人的问题
    1. 工作没有深度的情况下, 你该如何的提升自己, 并且做出些有意义的成果
    2. 反正我现在是一脸懵逼的
    3. 后悔之前选择不慎的同时, 也得想想如何丰富自己了
  4. 扯远了

2. 准备

  1. 环境
    1. 硬件

      1. 略, 这个没啥特定要求, 我就是在一个 windows 的 pc 上写的
    2. 软件

      1. 操作系统
        1. Windows 10
      2. jdk
        1. JDK8
      3. maven
        1. 3.3.9
      4. 组件
        1. JavaMail

          <!-- 主要是 JavaMail 相关的组件 -->
          <!-- 还用到 TestNG 来做单元测试 -->
          <dependency>
          <groupId>javax.mail</groupId>
          <artifactId>javax.mail-api</artifactId>
          <version>1.6.2</version>
          </dependency>
          <dependency>
          <groupId>com.sun.mail</groupId>
          <artifactId>javax.mail</artifactId>
          <version>1.6.2</version>
          </dependency>
          <dependency>
          <groupId>javax.activation</groupId>
          <artifactId>activation</artifactId>
          <version>1.1.1</version>
          </dependency>
    3. 邮件相关的一些协议

      1. SMTP
        1. 名称
          1. Simple Mail Transfer Protocol
        2. 功能
          1. 收发邮件
      2. POP
        1. 名称
          1. Post Office protocol
        2. 功能
          1. 接受邮件
          2. 原始版本, 只能单用户, 单邮箱
      3. IMAP
        1. 名称
          1. Internet Message Access Protocol
        2. 功能
          1. 接收邮件
          2. 可以多用户, 多邮箱
      4. 本次demo
        1. 功能
          1. 只有简单的发送邮件
        2. 采用
          1. SMTP
    4. SMTP 的一些准别

      1. 参数

        1. 邮件服务器
        2. 邮件端口
        3. 邮箱账号
        4. 邮箱密码
      2. 获取方法

        1. 略, 这个每个邮件服务商, 都有自己的获取方式
    5. JavaMail 的一些准备

      1. Session

        1. 概述
          1. 存储基本的邮箱信息
          2. 作为与邮箱连接的 会话对象
        2. 依赖属性
          1. Properties
            1. 一个属性对象
            2. 属性
              1. 后面会专门列出 properties 文件
          2. Authenticator
            1. 认证器
            2. 属性
              1. 邮箱用户
              2. 邮箱密码
      2. Authenticator

        1. 概述
          1. 认证器
      3. Message

        1. 概述
          1. 消息
          2. 依赖 Session
        2. 属性
          1. 发件人
            1. 依赖 Address
          2. 收件人
            1. 依赖 Address
          3. 标题
          4. 内容
      4. Address

        1. 概述
          1. 地址信息
        2. 属性
          1. URL
      5. Transport

        1. 概述
          1. 收发器
    6. 思路

      1. 获取配置
      2. 创建 Authenticator
      3. 创建 Session
      4. 创建 Message
      5. 发送邮件

3. 项目结构

  1. 概述

    1. Maven 项目
    2. 简单描述下结构
  2. 结构

    • project
      • src
        • main
          • java
          • resources
        • test
          • java
          • resources
  3. 说明

    1. src

      1. 子目录
        1. main
          1. 程序目录
        2. test
          1. 测试目录
    2. main

      1. 子目录
        1. java
          1. 程序目录
        2. resources
          1. 资源目录
          2. classpath 的位置
    3. test

      1. 子目录
        1. java
          1. 测试目录
        2. resouces
          1. 资源目录
          2. classpath 的位置
    4. 资源目录

      1. java 和 test 下的资源目录, 不是互通的
      2. 测试代码在测试 java 下的代码时
        1. 如果涉及到取 classpath, 会自动转换到 test 的 resource 下

4. 代码

  1. 配置文件

    1. 概述

      1. 配置的字段名, 最好不要改
      2. 如何把这些东西读到 properties 里, 这个就八仙过海了
    2. 代码

      # Server
      mail.smtp.host=smtp.qq.com
      mail.smtp.port=587 # Account
      mail.smtp.account=<yourEmailAccount>
      mail.smtp.password=<yourEmailPassword> # Options
      # 这俩是那种必须要, 但是我又懒得去搞懂的参数
      mail.smtp.auth=true
      mail.smtp.startssl.enable=true # Message
      mail.message.from=<yourSender>
      mail.message.to=<yourReciever>
      mail.message.subject=<yourTitle>
      mail.message.text=<yourContent>
    3. 友情提示

      1. = 号两边的空格, 最好贴演示
      2. 配置的值, 千万不要加 引号
        1. 千万不要加 引号
          1. 千万不要加 引号
  2. 代码

    1. 概述

      1. 按照之前描述的思路
      2. 肯定不能运行
        1. 原因是我没有上传我 properties 的处理组件
        2. 其实自己改改, 也不麻烦, 毕竟只是一个简单的发邮件功能
    2. 代码

      import javax.mail.*;
      import javax.mail.internet.InternetAddress;
      import javax.mail.internet.MimeMessage;
      import java.util.Properties; public class MyMailBox { public static void main(String[] args) {
      // 1. 获取 session;
      // # 1. 准备属性
      String filename = "demo.properties";
      final Properties properties = PropertiesUtil.getProperties(filename); // # 2. 准备用户信息
      Authenticator auth = new Authenticator() {
      @Override
      protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication(properties.getProperty(MailConstants.MAIL_ACCOUNT),
      properties.getProperty(MailConstants.MAIL_PASSWORD));
      }
      }; // # 3. 创建 Session
      Session session = Session.getDefaultInstance(properties, auth); // 2. 构造 消息;
      try {
      // # 1. 创建 message
      Message message = new MimeMessage(session); // # 2. 设置发信人
      message.setFrom(new InternetAddress(properties.getProperty(MailConstants.MAIL_FROM))); // # 3. 设置设置收信人
      message.setRecipient(Message.RecipientType.TO,
      new InternetAddress(properties.getProperty(MailConstants.MAIL_TO))); // # 4. 设置标题
      message.setSubject(properties.getProperty(MailConstants.MAIL_SUBJECT)); // # 5. 设置内容
      message.setText(properties.getProperty(MailConstants.MAIL_TEXT)); // 3. 发送消息
      Transport.send(message); System.out.println("Mission complete!");
      } catch (MessagingException e) {
      throw new RuntimeException(e);
      } }
      }

5. 结果

  1. 邮件能发出来

6. 其他的一些想法

  1. 工程上

    1. 更加地面向对象

      1. 可以把一些东西抽象出来, 做复用
        1. 邮件服务器
        2. 用户信息
        3. 邮件信息
      2. 这次没做, 是因为东西比较少, 一个 properties 搞定
    2. properties 读取配置

      1. 这块已经做了, 不过没发上来
        1. 确实有点不地道
        2. 我会在另一篇博客里, 补充一些相关的东西
      2. properties 读取数组
        1. 不知道可不可以, 但是面的多个收信人, 起码不会太尴尬, 是吧
    3. 邮件内容

      1. 尝试发送复杂的东西
        1. html 页面
        2. freemarker 模板做的 html 页面
        3. 附件
    4. 测试

      1. 尝试了 测试驱动开发 的思路
      2. 问题
        1. 测试方法如何管理, 命名

          1. 测试一个方法
            1. 正向
              1. 正向场景1
              2. 正向场景2
            2. 逆向
              1. 逆向场景1
              2. 逆向场景2
          2. 问题
            1. 方法命名
              1. 我之前的思路, 是 test 打头, 接原方法名, 再接场景, 再接参数
              2. 他的太长没法看, 而且很乱
            2. 真心求一个组织用例的方式
              1. 因为代码不多, 我所有方法, 都是写到一个测试类里
              2. 难道是要分包, 分类, 在细分?
        2. 数据管理

          1. 写在专门的数据类里
          2. 问题
            1. 该数据需要重新编译
            2. 如果写在 mysql 里, 表结构不知道怎么定义会比较合适
            3. 如果改成 关键字驱动, 那么表结构什么的, 估计也会比较麻烦
    5. 自动化测试, 与发送邮件告警

      1. 写这个的目的, 是希望在出问题的时候, 可以邮件告警

      2. 结果

        1. 单纯的 java 项目
          1. 需要 maven 插件的配置
        2. 持续集成系统
          1. jinkens
            1. 自带模块, 配置好了就能发
            2. 还有模板什么的
        3. 监控系统
          1. zabbix
            1. 自带功能
            2. 配置好了就能使
            3. 还有模板
            4. 还有问题级别
            5. 还支持自定义 py 脚本
              1. 什么短信, 微信也是信手拈来
  2. 回到那个最原始的问题

    1. 如何在工作很浅的情况下, 提升自己, 干有意义的事
上一篇:Python3.5 执行发邮件Exchangelib(=)


下一篇:PHP使用cURL ping Minecraft服务器