import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
public class MailAuthenticator extends Authenticator {
/**
* Represents the username of sending SMTP server.
* For example: If you use smtp.163.com as your smtp server, then the related
* username should be:
'[email protected]', or just 'testname' 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: '[email protected]' is valid), the from of MailMessage should always be the
* correct format of email address(for example the 'aaaa' is invalid). 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 env = new Hashtable();
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 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;
}
}