Java邮件发送(实名发送和匿名发送)

共包含三个类:
MailAuthenticator、MailMessage、MailUtil

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

public class MailAuthenticator extends Authenticator {


    /**
     * Represents the username of sending SMTP server.
     * <p>For example: If you use smtp.163.com as your smtp server, then the related
     * username should be: <br>'<b>[email protected]</b>', or just '<b>testname</b>' is OK.
     */
    private String username = null;
    /**
     * Represents the password of sending SMTP sever.
     * More explicitly, the password is the password of username.
     */
    private String password = null;
    public MailAuthenticator(String user, String pass) {
        username = user;
    password = pass;
    } 

    protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(username, password);
    }
}

package com.plugin.pojo;

public class MailMessage {
	private String subject;

	private String from;

	private String[] tos;

	private String[] ccs;

	private String[] bccs;

	private String content;

	private String[] fileNames;

	/**
	 * 
	 * 
	 * No parameter constructor.
	 * 
	 * 
	 */

	public MailMessage() {
	}

	/**
	 * 
	 * 
	 * Construct a MailMessage object.
	 * 
	 * 
	 */

	public MailMessage(String subject, String from, String[] tos,

			String[] ccs, String[] bccs, String content, String[] fileNames) {

		this.subject = subject;

		this.from = from;

		this.tos = tos;

		this.ccs = ccs;

		this.bccs = bccs;

		this.content = content;

		this.fileNames = fileNames;

	}

	/**
	 * 
	 * 
	 * Construct a simple MailMessage object.
	 * 
	 * 
	 */

	public MailMessage(String subject, String from, String to, String content) {

		this.subject = subject;

		this.from = from;

		this.tos = new String[] { to };

		this.content = content;

	}

	public String getSubject() {

		return subject;

	}

	public void setSubject(String subject) {

		this.subject = subject;

	}

	public String getFrom() {

		return from;

	}

	public void setFrom(String from) {

		this.from = from;

	}

	public String[] getTos() {

		return tos;

	}

	public void setTos(String[] tos) {

		this.tos = tos;

	}

	public String[] getCcs() {

		return ccs;

	}

	public void setCcs(String[] ccs) {

		this.ccs = ccs;

	}

	public String[] getBccs() {

		return bccs;

	}

	public void setBccs(String[] bccs) {

		this.bccs = bccs;

	}

	public String getContent() {

		return content;

	}

	public void setContent(String content) {

		this.content = content;

	}

	public String[] getFileNames() {

		return fileNames;

	}

	public void setFileNames(String[] fileNames) {

		this.fileNames = fileNames;

	}

}

package com.plugin.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
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;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.apache.log4j.Logger;
import com.common.MailAuthenticator;
import com.plugin.pojo.MailMessage;

 

public class MailUtil {

    private static final Logger LOGGER = Logger.getLogger(MailUtil.class);
    private static String SMTPServer;
    private static String SMTPUsername;
    private static String SMTPPassword;
    private static String POP3Server;
    private static String POP3Username;
    private static String POP3Password;
//    static {
//        loadConfigProperties();
//    }

//    public static void main(String[] args) {
//
//        //发送邮件
//        MailMessage mail = new MailMessage(
//                "test-subject", 
//                "[email protected]", 
//                "[email protected]", 
//                "This is mail content");
//        //set attachments
//        String[] attachments = new String[]{
//                "C:\\AndroidManifest.xml", 
//                "C:\\ic_launcher-web.png", 
//                "C:\\光良 - 童话.mp3", 
//                "C:\\文档测试.doc", 
//                "C:\\中文文件名测试.txt"};
//        mail.setFileNames(attachments);
//        sendEmail(mail);
//        //接收邮件
//        receiveEmail(POP3Server, POP3Username, POP3Password);
//        //发送匿名邮件
//        MailMessage anonymousMail = new MailMessage("subject", 
//            "[email protected]", "[email protected]", "content");
//        anonymousMail.setFileNames(attachments);
//        //sendAnonymousEmail(anonymousMail);
//    }


           

    /**
     * Load configuration properties to initialize attributes.
     */
    private static void loadConfigProperties() {
        File f = new File("");
        //this path would point to AbcCommon
        String absolutePath = f.getAbsolutePath();
        String propertiesPath = "";
        String OSName = System.getProperty("os.name");
        if(OSName.contains("Windows")) {
            propertiesPath = absolutePath + "\\..\\src\\main\\resources\\project.properties";
        } else if(OSName.contains("unix")) {
            propertiesPath = absolutePath + "/../src/main/resources/project.properties";
        }

        f = new File(propertiesPath);
        if(!f.exists()) {
            throw new RuntimeException("Porperties file not found at: " + f.getAbsolutePath());
        }

        Properties props = new Properties();
        try {
            props.load(new FileInputStream(f));
            SMTPServer = props.getProperty("AbcCommon.mail.SMTPServer");
            SMTPUsername = props.getProperty("AbcCommon.mail.SMTPUsername");
            SMTPPassword = props.getProperty("AbcCommon.mail.SMTPPassword");
            POP3Server = props.getProperty("AbcCommon.mail.POP3Server");
            POP3Username = props.getProperty("AbcCommon.mail.POP3Username");
            POP3Password = props.getProperty("AbcCommon.mail.POP3Password");
        } catch (FileNotFoundException e) {
            LOGGER.error("File not found at " + f.getAbsolutePath(), e);
        } catch (IOException e) {
            LOGGER.error("Error reading config file " + f.getName(), e);
        }
    }


     

    /**
     * Send email. Note that the fileNames of MailMessage are the absolute path of file.
     * @param mail The MailMessage object which contains at least all the required 
     *        attributes to be sent.
     */
    public static void sendEmail(MailMessage mail) {
        sendEmail(null, mail, false);
    }


     

    /**
     * Send anonymous email. Note that although we could give any address as from address,
     * (for example: <b>'[email protected]' is valid</b>), the from of MailMessage should always be the 
     * correct format of email address(for example the <b>'aaaa' is invalid</b>). Otherwise 
     * an exception would be thrown say that username is invalid.
     * @param mail The MailMessage object which contains at least all the required 
     *        attributes to be sent.
     */
    public  void sendAnonymousEmail(MailMessage mail) {
        String dns = "dns://";
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
        env.put(Context.PROVIDER_URL, dns);
        String[] tos = mail.getTos();

        try {
            DirContext ctx = new InitialDirContext(env);
            for(String to:tos) {
                String domain = to.substring(to.indexOf('@') + 1);
                //Get MX(Mail eXchange) records from DNS
                Attributes attrs = ctx.getAttributes(domain, new String[] { "MX" });
                if (attrs == null || attrs.size() <= 0) {
                    throw new java.lang.IllegalStateException(
                        "Error: Your DNS server has no Mail eXchange records!");
                }


                @SuppressWarnings("rawtypes")
                NamingEnumeration servers = attrs.getAll();
                String smtpHost = null;
                boolean isSend = false;
                StringBuffer buf = new StringBuffer();
                //try all the mail exchange server to send the email.
                while (servers.hasMore()) {
                    Attribute hosts = (Attribute) servers.next();
                    for (int i = 0; i < hosts.size(); ++i) {
                        //sample: 20 mx2.qq.com
                        smtpHost = (String) hosts.get(i);
                        //parse the string to get smtpHost. sample: mx2.qq.com
                        smtpHost = smtpHost.substring(smtpHost.lastIndexOf(' ') + 1);
                        try {
                            sendEmail(smtpHost, mail, true);
                            isSend = true;
                            return;
                        } catch (Exception e) {
                            LOGGER.error("", e);
                            buf.append(e.toString()).append("\r\n");
                            continue;
                        }
                    }
                }

                if (!isSend) {
                    throw new java.lang.IllegalStateException("Error: Send email error."
                            + buf.toString());
                }
            }
        } catch (NamingException e) {
            LOGGER.error("", e);
        }
    } 


     

    /**
     * Send Email. Use string array to represents attachments file names.
     * @see #sendEmail(String, String, String[], String[], String[], String, File[])
     */
    private static void sendEmail(String smtpHost, 
        MailMessage mail, boolean isAnonymousEmail) {
        if(mail == null) {
            throw new IllegalArgumentException("Param mail can not be null.");
        }

        String[] fileNames = mail.getFileNames();
        //only needs to check the param: fileNames, other params would be checked through
        //the override method.
        File[] files = null;
        if(fileNames != null && fileNames.length > 0) {

            files = new File[fileNames.length];
            for(int i = 0; i < files.length; i++) {
                File file = new File(fileNames[i]);
                files[i] = file;
            }
        }

        sendEmail(smtpHost, mail.getSubject(), mail.getFrom(), mail.getTos(), 
                mail.getCcs(), mail.getBccs(), mail.getContent(), files, isAnonymousEmail);


    }


     

    /**


     * Send Email. Note that content and attachments cannot be empty at the same time.


     * @param smtpHost The SMTPHost. This param is needed when sending an anonymous email.


     *        When sending normal email, the param is ignored and the default SMTPServer


     *        configured is used.


     * @param subject The email subject.


     * @param from The sender address. This address must be available in SMTPServer.


     * @param tos The receiver addresses. At least 1 address is valid.


     * @param ccs The 'copy' receiver. Can be empty.


     * @param bccs The 'encrypt copy' receiver. Can be empty.


     * @param content The email content.


     * @param attachments The file array represent attachments to be send.


     * @param isAnonymousEmail If this mail is send in anonymous mode. When set to true, the 


     *        param smtpHost is needed and sender's email address from should be in correct


     *        pattern.


     */


    private static void sendEmail(String smtpHost, String subject, 
            String from, String[] tos, String[] ccs, String[] bccs, 
            String content, File[] attachments, boolean isAnonymousEmail) {
        //parameter check
        if(isAnonymousEmail && smtpHost == null) {
            throw new IllegalStateException(
                "When sending anonymous email, param smtpHost cannot be null");
        }
        if(subject == null || subject.length() == 0) {
            subject = "Auto-generated subject";
        }


        if(from == null) {
            throw new IllegalArgumentException("Sender's address is required.");
        }

        if(tos == null || tos.length == 0) {
            throw new IllegalArgumentException(
                "At lease 1 receive address is required.");
        }


        if(content == null && (attachments == null || attachments.length == 0)) {
            throw new IllegalArgumentException(
                "Content and attachments cannot be empty at the same time");
        }


        if(attachments != null && attachments.length > 0) {
            List<File> invalidAttachments = new ArrayList<>();
            for(File attachment:attachments) {
                if(!attachment.exists() || attachment.isDirectory() 
                    || !attachment.canRead()) {
                    invalidAttachments.add(attachment);
                }
            }
            if(invalidAttachments.size() > 0) {
                String msg = "";
                for(File attachment:invalidAttachments) {
                    msg += "\n\t" + attachment.getAbsolutePath();
                }
                throw new IllegalArgumentException(
                    "The following attachments are invalid:" + msg);
            }
        }


        Session session;
        Properties props = new Properties();
        props.put("mail.transport.protocol", "smtp");
        if(isAnonymousEmail) {
            //only anonymous email needs param smtpHost
            props.put("mail.smtp.host", smtpHost);
            props.put("mail.smtp.auth", "false");
            session = Session.getInstance(props, null);
        } else {
            //normal email does not need param smtpHost and uses the default host SMTPServer
            props.put("mail.smtp.host", SMTPServer); 
            props.put("mail.smtp.auth", "true");
            session = Session.getInstance(props, 
                new MailAuthenticator(SMTPUsername, SMTPPassword));
        }


        //create message
        MimeMessage msg = new MimeMessage(session);
        try {
            //Multipart is used to store many BodyPart objects.
            Multipart multipart=new MimeMultipart();          
            BodyPart part = new MimeBodyPart();
            part.setContent(content,"text/html;charset=gb2312");
            //add email content part.
            multipart.addBodyPart(part);           
            //add attachment parts.

            if(attachments != null && attachments.length > 0) {
                for(File attachment: attachments) {
                    String fileName = attachment.getName();
                    DataSource dataSource = new FileDataSource(attachment);
                    DataHandler dataHandler = new DataHandler(dataSource);
                    part = new MimeBodyPart();
                    part.setDataHandler(dataHandler);
                    //solve encoding problem of attachments file name.
                    try {
                        fileName = MimeUtility.encodeText(fileName);
                    } catch (UnsupportedEncodingException e) {
                        LOGGER.error(
                            "Cannot convert the encoding of attachments file name.", e);
                    }
                    //set attachments the original file name. if not set, 
                    //an auto-generated name would be used.
                    part.setFileName(fileName);
                    multipart.addBodyPart(part);
                }
            }
            msg.setSubject(subject);
            msg.setSentDate(new Date());
            //set sender
            msg.setFrom(new InternetAddress(from));
            //set receiver, 
            for(String to: tos) {
                msg.addRecipient(RecipientType.TO, new InternetAddress(to));
            }

            if(ccs != null && ccs.length > 0) {
                for(String cc: ccs) {
                    msg.addRecipient(RecipientType.CC, new InternetAddress(cc));
                }
            }
            if(bccs != null && bccs.length > 0) {
                for(String bcc: bccs) {
                    msg.addRecipient(RecipientType.BCC, new InternetAddress(bcc));
                }
            }
            msg.setContent(multipart);
            //save the changes of email first.
            msg.saveChanges();
            //to see what commands are used when sending a email, use session.setDebug(true)
            //session.setDebug(true);
            //send email
            Transport.send(msg); 
            LOGGER.info("Send email success.");
            System.out.println("Send html email success.");
        } catch (NoSuchProviderException e) {
            LOGGER.error("Email provider config error.", e);
        } catch (MessagingException e) {
            LOGGER.error("Send email error.", e);
        }
    }


     
 

    /**
     * Receive Email from POPServer. Use POP3 protocal by default. Thus,
     * call this method, you need to provide a pop3 mail server address.
     * @param emailAddress The email account in the POPServer.
     * @param password The password of email address.
     */
    public static void receiveEmail(String host, String username, String password) {
        //param check. If param is null, use the default configured value.

        if(host == null) {
            host = POP3Server;
        }

        if(username == null) {
            username = POP3Username;
        }

        if(password == null) {
            password = POP3Password;
        }
        Properties props = System.getProperties();
        //MailAuthenticator authenticator = new MailAuthenticator(username, password);


        try {
            Session session = Session.getDefaultInstance(props, null);
            // Store store = session.getStore("imap");
            Store store = session.getStore("pop3");
            // Connect POPServer
            store.connect(host, username, password);
            Folder inbox = store.getFolder("INBOX");
            if (inbox == null) {
                throw new RuntimeException("No inbox existed.");
            }

            // Open the INBOX with READ_ONLY mode and start to read all emails.
            inbox.open(Folder.READ_ONLY);

            System.out.println("TOTAL EMAIL:" + inbox.getMessageCount());

            Message[] messages = inbox.getMessages();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (int i = 0; i < messages.length; i++) {
                Message msg = messages[i];
                String from = InternetAddress.toString(msg.getFrom());
                String replyTo = InternetAddress.toString(msg.getReplyTo());
                String to = InternetAddress.toString(
                    msg.getRecipients(Message.RecipientType.TO));

                String subject = msg.getSubject();
                Date sent = msg.getSentDate();
                Date ress = msg.getReceivedDate();
                String type = msg.getContentType();
                System.out.println((i + 1) + ".---------------------------------------------");
                System.out.println("From:" + mimeDecodeString(from));
                System.out.println("Reply To:" + mimeDecodeString(replyTo));
                System.out.println("To:" + mimeDecodeString(to));
                System.out.println("Subject:" + mimeDecodeString(subject));
                System.out.println("Content-type:" + type);

                if (sent != null) {
                    System.out.println("Sent Date:" + sdf.format(sent));
                }

                if (ress != null) {
                    System.out.println("Receive Date:" + sdf.format(ress));
                }

//                //Get message headers.
//                @SuppressWarnings("rawtypes")
//                Enumeration headers = msg.getAllHeaders();
//                while (headers.hasMoreElements()) {
//                    Header h = (Header) headers.nextElement();
//                    String name = h.getName();
//                    String val = h.getValue();
//                    System.out.println(name + ": " + val);
//                }

                 
//                //get the email content.
//                Object content = msg.getContent();
//                System.out.println(content);
//                //print content
//                Reader reader = new InputStreamReader(
//                        messages[i].getInputStream());
//                int a = 0;
//                while ((a = reader.read()) != -1) {
//                    System.out.print((char) a);
//                }
            }

            // close connection. param false represents do not delete messaegs on server.
            inbox.close(false);
            store.close();

//        } catch(IOException e) {
//            LOGGER.error("IOException caught while printing the email content", e);
        } catch (MessagingException e) {
            LOGGER.error("MessagingException caught when use message object", e);
        }
    }

    /**
     * For receiving an email, the sender, receiver, reply-to and subject may 
     * be messy code. The default encoding of HTTP is ISO8859-1, In this situation, 
     * use MimeUtility.decodeTex() to convert these information to GBK encoding.
     * @param res The String to be decoded.
     * @return A decoded String.
     */
    private static String mimeDecodeString(String res) {
        if(res != null) {
            String from = res.trim();
            try {
                if (from.startsWith("=?GB") || from.startsWith("=?gb")
                        || from.startsWith("=?UTF") || from.startsWith("=?utf")) {
                    from = MimeUtility.decodeText(from);
                }
            } catch (Exception e) {
                LOGGER.error("Decode string error. Origin string is: " + res, e);
            }
            return from;
        }
        return null;
    }
}



猜你喜欢

转载自blog.csdn.net/mubing870825/article/details/80015512