JavaMail

Scroll Down

JavaMail 案例

环境配置

  1. tomcat 9
  2. mail.jar
  3. activation.jar

需求说明

建立一个简单的网站,输入账户和密码以及邮件内容和标题,能够实现简单的邮件发送功能

前端页面

采用jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>模拟email</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #content{
            margin: auto;
            width: 400px;
        }
        form{
            margin-left: auto;
            margin-top: 300px;
        }
        td{
            padding: 4px;
            text-align: center;
        }
        textarea{
            width: 200px;
            height: 200px;
        }
    </style>
</head>
<body>
    <div id="content">
        <form method="post" action="${pageContext.request.contextPath}/emailServlet">
            <table>
                <tr>
                    <th colspan="2">
                        模拟电子邮件
                    </th>
                </tr>
                <tr>
                    <td>账户</td>
                    <td><input type="text" name="username"></td>
                </tr>
                <tr>
                    <td>密码</td>
                    <td><input type="password" name="password"></td>
                </tr>
                <tr>
                    <td>标题</td>
                    <td><input type="text" name="subject"></td>
                </tr>
                <tr>
                    <td>发件人地址</td>
                    <td><input type="text" name="from"></td>
                </tr>
                <tr>
                    <td>收件人地址</td>
                    <td><input type="text" name="to"></td>
                </tr>
                <tr>
                    <td>
                        内容
                    </td>
                    <td>
                        <textarea name="content"></textarea>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="file" name="file">
                    </td>
                </tr>
                <tr>
                    <td>
                        <input type="submit">
                    </td>
                    <td>
                        <input type="reset">
                    </td>
                </tr>
            </table>
        </form>
    </div>
</body>
</html>

效果很简单

样式.png

后端部分

流程分析

  1. 创建和邮件服务器会话Session
    通过一个Properties类来存放配置,主要是邮件服务器的地址

    1、QQ邮箱(mail.qq.com)
    SMTP服务器地址:smtp.qq.com(端口:25)
    2、搜狐邮箱(sohu.com):
    SMTP服务器地址:smtp.sohu.com(端口:25)
    3、HotMail邮箱(hotmail.com):
    SMTP服务器地址:smtp.live.com(端口:587)
    4、移动139邮箱:
    SMTP服务器地址:SMTP.139.com(端口:25)
    5、景安网络邮箱:
    SMTP服务器地址:SMTP.zzidc.com(端口:25)

     properties.put("mail.smtp.host", "smtp.qq.com");
     properties.put("mail.smtp.auth", "true");
    

    在这里我使用qq邮箱

     Session session = Session.getDefaultInstance(properties); 
    

    然后获取会话对象

  2. 设置信件内容
    设置信件内容,通过MimeMessage类来进行实现,在里面通过InternetAddress类来设置地址,设置内容等都比较固定

    try {
         //设置主题
         message.setSubject(subject);
         InternetAddress fromAddress=new InternetAddress(from);
         //设置发件人地址
         message.setFrom(fromAddress);
         InternetAddress toAddress=new InternetAddress(to);
         //设置收件人地址
         message.setRecipient(Message.RecipientType.TO, toAddress);
         //设置内容 
         message.setContent(content,"text/html;charset=gb2312");
         //设置发送日期
         message.setSentDate(new Date());
     } catch (Exception e) {
         e.printStackTrace();
     }
    
  3. 发送信件
    用一个Transport对象,来进行发送操作

    try {
         Transport transport=session.getTransport("smtp");
         //连上邮件服务器
         transport.connect("smtp.qq.com",username,password);
         //发送信息
         transport.sendMessage(message, message.getAllRecipients());
         //关闭连接
         transport.close();
         System.out.println("发送成功");
     } catch (Exception e) {
         e.printStackTrace();
     }
    

问题整理

  1. java.lang.NoClassDefFoundError
    

    导致这种问题的原因是jar包没有加入classpath或者jar包出问题

  2.  javax.mail.AuthenticationFailedException: 535 Login Fail. Please enter your authorization code to login
    

    这种问题的原因是有些邮箱需要授权码,我这里以qq邮箱举例

    邮箱授权.png

    在qq邮箱里有一个授权的POP3/SMPT服务,用这个授权码当密码填写就可以了

文件上传

需要的jar包

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
   <version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.3.3</version>
</dependency>

注意这种情况的表单提交属性设置

<form method="post" action="${pageContext.request.contextPath}/upload" ENCTYPE="multipart/form-data">
  1. 创建DiskFileItemFactory
  2. 获取ServletFileUpload
  3. 获取upload.parseRequest(req)
  4. 分析每一个FileItem,对其进行处理
  5. 关掉输入流和FileItem
try {
   DiskFileItemFactory fac = new DiskFileItemFactory();
   //fac.setRepository();//设置临时目录
   Map<String,String> map = new HashMap<String, String>();
   ServletFileUpload upload = new ServletFileUpload(fac);  //文件上传核心对象,获取所有 FileItem 对象
   upload.setFileSizeMax(30 * 1024 *1024);     //文件最大大小  30M
   //判断是否为上传表单
   if (upload.isMultipartContent(req)) {
       List<FileItem> list = upload.parseRequest(req);
       for (FileItem item : list) {
           if (item.isFormField())
           {
               //如果是普通表单
               String name = item.getFieldName();  //文本框名称
               String content = item.getString("UTF-8");  //文本框内容
               map.put(name,content);
           }else {
               String fileName = item.getName();   //文件名
               String contentType = item.getContentType();     //文件类型
               String name = item.getFieldName();      //表单名称
               //InputStream inputStream = item.getInputStream();    //文件输入流
               item.write(new File(req.getServletContext().getRealPath("/upload"),fileName));//写文件到某个目录下
               item.delete();      //删除临时文件
           }
       }
   }
} catch (FileUploadException e) {
   e.printStackTrace();
} catch (Exception e) {
   e.printStackTrace();
}

错误解决

如果提示临时文件删除失败,记得一定要删除item,和关掉文件输入流