Java mail sending: with attachment or without attachment is nothing

    Yesterday, I just wanted to use the function of sending emails. By the way, I looked at the specific implementation. There are many versions on the Internet. The following is a version that I think is highly available. It is very easy to use, and it is summarized and optimized. You can use it directly. Oh.

    When using Java, add the corresponding lib package: mail-1.4.7.jar, other versions are also fine. In general, three classes need to be implemented (however, for the rigor of the code structure, let's write more), you can put them under a package package for easy management and use.

    Well, without further ado, let's see the code.

    (1) Entity class of email content (most versions are similar, and some parameters are not used)

package com.yoki.util.mail;

import java.util.Properties;

public class MailSenderInfo
{
  // 发送邮件的服务器的IP和端口
  private String mailServerHost;
  private String mailServerPort = "25";
  // 邮件发送者的地址
  private String fromAddress;
  // 邮件接收者的地址
  private String toAddress;
  // 登陆邮件发送服务器的用户名和密码
  private String userName;
  private String password;
  // 是否需要身份验证
  private boolean validate = false;
  // 邮件主题
  private String subject;
  // 邮件的文本内容
  private String content;
  // 邮件附件的文件名
  private String[] attachFileNames;

  /**   
   * 获得邮件会话属性   
   */
  public Properties getProperties()
  {
    Properties p = new Properties();
    p.put("mail.smtp.host", this.mailServerHost);
    p.put("mail.smtp.port", this.mailServerPort);
    p.put("mail.smtp.auth", (this.validate) ? "true" : "false");
    return p; }

  public String getMailServerHost() {
    return this.mailServerHost; }

  public void setMailServerHost(String mailServerHost) {
    this.mailServerHost = mailServerHost; }

  public String getMailServerPort() {
    return this.mailServerPort; }

  public void setMailServerPort(String mailServerPort) {
    this.mailServerPort = mailServerPort; }

  public boolean isValidate() {
    return this.validate; }

  public void setValidate(boolean validate) {
    this.validate = validate; }

  public String[] getAttachFileNames() {
    return this.attachFileNames; }

  public void setAttachFileNames(String[] fileNames) {
    this.attachFileNames = fileNames; }

  public String getFromAddress() {
    return this.fromAddress; }

  public void setFromAddress(String fromAddress) {
    this.fromAddress = fromAddress; }

  public String getPassword() {
    return this.password; }

  public void setPassword(String password) {
    this.password = password; }

  public String getToAddress() {
    return this.toAddress; }

  public void setToAddress(String toAddress) {
    this.toAddress = toAddress; }

  public String getUserName() {
    return this.userName; }

  public void setUserName(String userName) {
    this.userName = userName; }

  public String getSubject() {
    return this.subject; }

  public void setSubject(String subject) {
    this.subject = subject; }

  public String getContent() {
    return this.content; }

  public void setContent(String textContent) {
    this.content = textContent;
  }
}

    (2) Authenticator when sending emails

package com.yoki.util.mail;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class MailAuthenticator extends Authenticator {
    /** 用户账号 */
    private String userName = null;
    /** 用户口令 */
    private String password = null;

    /**
     * @param userName
     * @param password
     */
    public MailAuthenticator(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    /**
     * 身份验证
     * @return
     */
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, password);
    }

}

    (3) Mail sender

package com.yoki.util.mail;

import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

public class MailSender
{
  /**
    * 以文本格式发送邮件
    * @param mailInfo 待发送邮件的信息
    */
  public boolean sendTextMail(MailSenderInfo mailInfo)
    throws Exception
  {
    // 判断是否需要身份认证
    MyAuthenticator authenticator = null;
    Properties props = mailInfo.getProperties();
    if (mailInfo.isValidate())
    {
      // 如果需要身份认证,则创建一个密码验证器
      authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
    }
    // 根据邮件会话属性和密码验证器构造一个发送邮件的session
    Session sendMailSession = Session.getInstance(props, authenticator);

    // 根据session创建一个邮件消息
    Message mailMessage = new MimeMessage(sendMailSession);
    // 创建邮件发送者地址
    Address from = new InternetAddress(mailInfo.getFromAddress());
    // 设置邮件消息的发送者
    mailMessage.setFrom(from);
    // 创建邮件的接收者地址,并设置到邮件消息中
    Address to = new InternetAddress(mailInfo.getToAddress());
    mailMessage.setRecipient(Message.RecipientType.TO, to);
    // 设置邮件消息的主题
    mailMessage.setSubject(mailInfo.getSubject());
    // 设置邮件消息发送的时间
    mailMessage.setSentDate(new Date());
    // MimeMultipart类是一个容器类,包含MimeBodyPart类型的对象
    Multipart mainPart = new MimeMultipart();
    MimeBodyPart mbpContent = new MimeBodyPart();
    // 设置邮件消息的主要内容
    String mailContent = mailInfo.getContent();
    mbpContent.setText(mailContent);
    mainPart.addBodyPart(mbpContent);
    // 添加附件
    if (mailInfo.getAttachFileNames().length != 0){
      String[] arrayOfString;
      int j = (arrayOfString = mailInfo.getAttachFileNames()).length; 
      for (int i = 0; i < j; ++i) { 
        String attachFile = arrayOfString[i];
        MimeBodyPart mbpart = new MimeBodyPart();
        FileDataSource fds = new FileDataSource(attachFile); // 得到数据源
        mbpart.setDataHandler(new DataHandler(fds));   // 得到附件本身并放入BodyPart
        mbpart.setFileName(MimeUtility.encodeText(fds.getName()));  // 得到文件名并编码(防止中文文件名乱码)同样放入BodyPart
        mainPart.addBodyPart(mbpart);
      }
    }
    mailMessage.setContent(mainPart);
    // 发送邮件
    Transport.send(mailMessage);
    logBefore(this.logger, "发送成功!");
    return true;
  }

  /**
    * 以HTML格式发送邮件
    * @param mailInfo 待发送邮件的信息
    */
  public boolean sendHtmlMail(MailSenderInfo mailInfo)
    throws Exception
  {
    // 判断是否需要身份认证
    MyAuthenticator authenticator = null;
    Properties pro = mailInfo.getProperties();
    // 如果需要身份认证,则创建一个密码验证器
    if (mailInfo.isValidate()) {
      authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
    }
    // 根据邮件会话属性和密码验证器构造一个发送邮件的session
    Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
    // 根据session创建一个邮件消息
    Message mailMessage = new MimeMessage(sendMailSession);
    // 创建邮件发送者地址
    Address from = new InternetAddress(mailInfo.getFromAddress());
    // 设置邮件消息的发送者
    mailMessage.setFrom(from);
    // 创建邮件的接收者地址,并设置到邮件消息中
    Address to = new InternetAddress(mailInfo.getToAddress());
    // Message.RecipientType.TO属性表示接收者的类型为TO
    mailMessage.setRecipient(Message.RecipientType.TO, to);
    // 设置邮件消息的主题
    mailMessage.setSubject(mailInfo.getSubject());
    // 设置邮件消息发送的时间
    mailMessage.setSentDate(new Date());
    // MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
    Multipart mainPart = new MimeMultipart();
    // 创建一个包含HTML内容的MimeBodyPart
    BodyPart html = new MimeBodyPart();
    // 设置HTML内容
    html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
    mainPart.addBodyPart(html);
    // 添加附件
    if (mailInfo.getAttachFileNames().length != 0) {
      String[] arrayOfString;
      int j = (arrayOfString = mailInfo.getAttachFileNames()).length; 
      for (int i = 0; i < j; ++i) { 
        String attachFile = arrayOfString[i];
        html = new MimeBodyPart();
        FileDataSource fds = new FileDataSource(attachFile); // 得到数据源
        html.setDataHandler(new DataHandler(fds));   // 得到附件本身并放入BodyPart
        html.setFileName(MimeUtility.encodeText(fds.getName()));  // 得到文件名并编码(防止中文文件名乱码)同样放入BodyPart
        mainPart.addBodyPart(html);
      }
    }
    // 将MimeMultipart对象设置为邮件内容
    mailMessage.setContent(mainPart);
    // 发送邮件
    Transport.send(mailMessage);
    logBefore(this.logger, "发送成功!");
    return true;
  }

  /**
   *@param SMTP 邮件服务器
   *@param PORT 端口
   *@param EMAIL 发送方邮箱账号
   *@param PAW 发送方邮箱密码
   *@param toEMAIL 接收方邮箱账号
   *@param TITLE  标题
   *@param CONTENT 内容
   *@param FJ 附件
   *@param TYPE  1:文本格式;2:HTML格式
   */
  public static void sendEmail(String SMTP, String PORT, String EMAIL, String PAW, String toEMAIL, String TITLE, String CONTENT, String[] FJ, String TYPE)
    throws Exception
  {
    // 设置邮件信息
    MailSenderInfo mailInfo = new MailSenderInfo();

    mailInfo.setMailServerHost(SMTP);
    mailInfo.setMailServerPort(PORT);
    mailInfo.setValidate(true);
    mailInfo.setUserName(EMAIL);
    mailInfo.setPassword(PAW);
    mailInfo.setFromAddress(EMAIL);
    mailInfo.setToAddress(toEMAIL);
    mailInfo.setSubject(TITLE);
    mailInfo.setContent(CONTENT);
    mailInfo.setAttachFileNames(FJ);

    // 发送邮件
    MailSender sms = new MailSender();

    if ("1".equals(TYPE))
      sms.sendTextMail(mailInfo);
    else
      sms.sendHtmlMail(mailInfo);
  }

  public static void main(String[] args)
  {
    MailSenderInfo mailInfo = new MailSenderInfo();
    mailInfo.setMailServerHost("smtp.qq.com");
    mailInfo.setMailServerPort("25");
    mailInfo.setValidate(true);
    mailInfo.setUserName("[email protected]");
    mailInfo.setPassword("123");
    mailInfo.setFromAddress("[email protected]");
    mailInfo.setToAddress("[email protected]");
    mailInfo.setSubject("设置邮箱标题");
    mailInfo.setContent("设置邮箱内容");

    MailSender sms = new MailSender();
    // sms.sendTextMail(mailInfo);//发送文体格式
    // sms.sendHtmlMail(mailInfo);//发送HTML格式
  }
}

    (4) It is possible to send emails directly in the form in the main above, but if you use emails in many places in your code, then is it too complicated and not concise at all. In order to facilitate management and reduce code modification, first, we need to create a new configuration file, such as: EMAIL.txt, the directory can be under WebRoot, the content:

发件服务器地址,yoki,端口,yoki,发送邮箱,yoki,密码

    Example:

smtp.qiye.163.com,yoki,25,yoki,[email protected],yoki,123

    Among them, yoki is just a split string, which is used when reading the file later, and you can define it yourself. As for how to check the address of the sending server, I use the Foxmail client, and the others are Baidu, as shown below:

    (5) After having the EMAIL configuration file, it is best to write a class to store the file path, which is convenient for direct use

package com.yoki.util;

public class MyConst{
    //邮箱服务器配置文件路径
    public static final String EMAIL = "config/EMAIL.txt";
}

    (6) After completing the above operations, you only need to create a new class that calls the sending mail. The methods here include: unified sending mail format; text file reading; mailbox verification, as shown below:

package com.yoki.util;

import java.util.Map;
import java.util.HashMap;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import com.yoki.util.MyConst;
import com.yoki.util.mail.MailSender;

public class Common{

   /**
    *EMAIL 对方邮箱,多个用;分隔开
    *TITLE 标题
    *CONTENT 内容
    *TYPE 1=纯文本 2=带标签
    *FJ 附件
    */
   public static Map<String, Object> sendEmail(String EMAIL, String TITLE, String CONTENT, 
    String[] FJ, String TYPE) throws Exception {
    Map map = new HashMap();
    String msg = "ok";  // 发送状态
   
    String strEMAIL = readTxtFile(MyConst.EMAIL);  // 读取邮件配置
    if ((strEMAIL != null) && (!("".equals(strEMAIL)))) {
      String[] strEM = strEMAIL.split(",yoki,");
      if (strEM.length == 4) {
        EMAIL = EMAIL.replaceAll(";", ";");
        EMAIL = EMAIL.replaceAll(" ", "");
        String[] arrTITLE = EMAIL.split(";");
        zcount = arrTITLE.length;
        try {
          for (int i = 0; i < arrTITLE.length; ++i) {
            if (checkEmail(arrTITLE[i])) { // 邮箱格式不对就跳过
              MailSender.sendEmail(strEM[0], strEM[1], 
                strEM[2], strEM[3], arrTITLE[i], TITLE, 
                CONTENT, FJ, TYPE); // 调用发送邮件函数
              ++count;
            }

          }

          msg = "ok";
        } catch (Exception e) {
          logger.error(e.toString(), e);
        }
      } else {
        msg = "error";
      }
    } else {
      msg = "error";
    }
    map.put("msg", msg);
   
    return map;
  }
  
  /**
   *读取txt的单行内容
   *fileP 文件路径
   */
  public static String readTxtFile(String fileP){
     try{
        String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource("")) + "../../";
        filePath = filePath.replaceAll("file:/", "");
        filePath = filePath.replaceAll("%20", " ");
        filePath = filePath.trim() + fileP.trim();
        if (filePath.indexOf(":") != 1)
          filePath = File.separator + filePath;
        String encoding = "utf-8";
        File file = new File(filePath);
        if ((file.isFile()) && (file.exists())) {  // 判断文件是否存在
          InputStreamReader read = new InputStreamReader(
            new FileInputStream(file), encoding);  // 考虑到编码格式
          BufferedReader bufferedReader = new BufferedReader(read);
          String lineTxt = null;
          while ((lineTxt = bufferedReader.readLine()) != null){
            return lineTxt;
          }
          read.close();
        }else
          System.out.println("找不到指定的文件,查看此路径是否正确:" + filePath);
     }catch (Exception e){
        System.out.println("读取文件内容出错");
     }
     return "";
  }

  /**
   *验证邮箱
   */
  public static boolean checkEmail(String email){
     boolean flag = false;
     try{
        String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        Pattern regex = Pattern.compile(check);
        Matcher matcher = regex.matcher(email);
        flag = matcher.matches();
     }catch(Exception e){
        flag = false;
     }
     return flag;
  }
}

    (7) Well, all the preparations are completed, the following is the call, let's see how to call it conveniently

System.out.println("--------  开始发送邮件任务  ---------");
String[] fj = {"D:\\doc\\模板1.xls"};
Common.sendEmail("[email protected]","附件发送测试","本次发送的是测试文件,请接收!",fj,"2");
System.out.println("--------  结束发送邮件任务  ---------");

    Here, there can be multiple attachments, which can be separated by commas.

    The above is a super convenient and concise email sending. Isn't it very simple? It only takes two lines of code to call, haha ​​O(∩_∩)O.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325459249&siteId=291194637