本文根据Ian F. Darwin的《Java Cookbook》整理而成,原书用整章的文字介绍如何发邮件,可能头绪会比较乱,本文则将其浓缩成一篇文章,力求使完全不懂JavaMail的人,都可以根据文中指示稍作修改,拿来就可以用。如果对其中原理还有不清楚,你可以参考原书。
一、首先要用到三个java文件:
1.MailConstants.java,properties文件的助记符:///package untitled2;
/** Simply a list of names for the Mail System to use. * If you "implement" this interface, you don't have to prefix * all the names with MailProps in your code. */public interface MailConstants { public static final String PROPS_FILE_NAME = "MailClient.properties";
public static final String SEND_PROTO = "Mail.send.protocol"; public static final String SEND_USER = "Mail.send.user"; public static final String SEND_PASS = "Mail.send.password"; public static final String SEND_ROOT = "Mail.send.root"; public static final String SEND_HOST = "Mail.send.host"; public static final String SEND_DEBUG = "Mail.send.debug";
public static final String RECV_PROTO = "Mail.receive.protocol"; public static final String RECV_PORT = "Mail.receive.port"; public static final String RECV_USER = "Mail.receive.user"; public static final String RECV_PASS = "Mail.receive.password"; public static final String RECV_ROOT = "Mail.receive.root"; public static final String RECV_HOST = "Mail.receive.host"; public static final String RECV_DEBUG = "Mail.receive.debug";}///
2.FileProperties.java,从文件中读取properties:///package untitled2;
import java.io.*;import java.util.*;
/** * The <CODE>FileProperties</CODE> class extends <CODE>Properties</CODE>, * "a persistent set of properties [that] can be saved to a stream * or loaded from a stream". This subclass attends to all the mundane * details of opening the Stream(s) for actually saving and loading * the Properties. * * <P>This subclass preserves the useful feature that * a property list can contain another property list as its * "defaults"; this second property list is searched if * the property key is not found in the original property list. * * @author Ian F. Darwin, ian@darwinsys.com * @version $Id: FileProperties.java,v 1.5 2001/04/28 13:22:37 ian Exp $ */public class FileProperties extends Properties { protected String fileName = null;
/** * Construct a FileProperties given a fileName. * @param loadsaveFileName the progerties file name * @throws IOException */ public FileProperties(String loadsaveFileName) throws IOException { super(); fileName = loadsaveFileName; load(); }
/** Construct a FileProperties given a fileName and * a list of default properties. * @param loadsaveFileName the properties file name * @param defProp the default properties * @throws IOException */ public FileProperties(String loadsaveFileName, Properties defProp) throws IOException { super(defProp); fileName = loadsaveFileName; load(); }
/** The InputStream for loading */ protected InputStream inStr = null;
/** The OutputStream for loading */ protected OutputStream outStr = null;
/** Load the properties from the saved filename. * If that fails, try again, tacking on the .properties extension * @throws IOException */ public void load() throws IOException { try { if (inStr == null) { inStr = new FileInputStream(fileName); } } catch (FileNotFoundException fnf) { if (!fileName.endsWith(".properties")) { inStr = new FileInputStream(fileName + ".properties"); // If we succeeded, remember it: fileName += ".properties"; } else {
// It did end with .properties and failed, re-throw exception. throw fnf; } } // now message the superclass code to load the file. load(inStr); }
/** Save the properties for later loading. * * @throws IOException */
public void save() throws IOException { if (outStr == null) { outStr = new FileOutputStream(fileName); } // Get the superclass to do most of the work for us. store(outStr, "# Written by FileProperties.save() at " + new Date()); }
public void close() { try { if (inStr != null) { inStr.close(); } if (outStr != null) { outStr.close(); } } catch (IOException e) { // don't care } }}///
3.Mailer.java,将javamail发邮件的部分进行封装:///package untitled2;
import java.util.*;import java.io.*;import javax.mail.*;import javax.mail.internet.*;import javax.activation.*;
public class Mailer { /** The javamail session object. */ protected Session session; /** The sender's email address */ protected String from; /** The subject of the message. */ protected String subject; /** The recipient ("To:"), as Strings. */ protected ArrayList toList = new ArrayList(); /** The CC list, as Strings. */ protected ArrayList ccList = new ArrayList(); /** The BCC list, as Strings. */ protected ArrayList bccList = new ArrayList(); /** The text of the message. */ protected String body; /** The SMTP relay host */ protected String mailHost; /** The accessories list, as Strings.*/ protected ArrayList accessories = new ArrayList(); /** The verbosity setting */ protected boolean verbose;
/** Get from * @return where the mail from */ public String getFrom() { return from; }
/** Set from * @param fm where the mail from */ public void setFrom(String fm) { from = fm; }
/** Get subject * @return the mail subject */ public String getSubject() { return subject; }
/** Set subject * @param subj the mail subject */ public void setSubject(String subj) { subject = subj; }
// SETTERS/GETTERS FOR TO: LIST
/** Get tolist, as an array of Strings * @return the list of toAddress */ public ArrayList getToList() { return toList; }
/** Set to list to an ArrayList of Strings * @param to the list of toAddress */ public void setToList(ArrayList to) { toList = to; }
/** Set to as a string like "tom, mary, robin@host". Loses any * previously-set values. * @param s the list of toAddress*/ public void setToList(String s) { toList = tokenize(s); }
/** Add one "to" recipient * @param to the toAddress */ public void addTo(String to) { toList.add(to); }
// SETTERS/GETTERS FOR CC: LIST
/** Get cclist, as an array of Strings * @return the list of ccAddress */ public ArrayList getCcList() { return ccList; }
/** Set cc list to an ArrayList of Strings * @param cc the list of ccAddress */ public void setCcList(ArrayList cc) { ccList = cc; }
/** Set cc as a string like "tom, mary, robin@host". Loses any * previously-set values. * @param s the list of ccAddress */ public void setCcList(String s) { ccList = tokenize(s); }
/** Add one "cc" recipient * @param cc the address of cc */ public void addCc(String cc) { ccList.add(cc); }
// SETTERS/GETTERS FOR BCC: LIST
/** Get bcclist, as an array of Strings * @return the list of bcc */ public ArrayList getBccList() { return bccList; }
/** Set bcc list to an ArrayList of Strings * @param bcc the address of bcc */ public void setBccList(ArrayList bcc) { bccList = bcc; }
/** Set bcc as a string like "tom, mary, robin@host". Loses any * previously-set values. * @param s the address of bcc */ public void setBccList(String s) { bccList = tokenize(s); }
/** Add one "bcc" recipient * @param bcc the address of bcc */ public void addBcc(String bcc) { bccList.add(bcc); }
// SETTER/GETTER FOR MESSAGE BODY
/** Get message * @return the mail body */ public String getBody() { return body; }
/** Set message * @param text the mail body */ public void setBody(String text) { body = text; }
// SETTER/GETTER FOR ACCESSORIES
/** Get accessories * @return the arrayList of the accessories */ public ArrayList getAccessories() { return accessories; }
/** Set accessories * @param accessories the arrayList of the accessories */ public void setAccessories(ArrayList accessories) { this.accessories = accessories; }
// SETTER/GETTER FOR VERBOSITY
/** Get verbose * @return verbose */ public boolean isVerbose() { return verbose; }
/** Set verbose * @param v the verbose */ public void setVerbose(boolean v) { verbose = v; }
/** Check if all required fields have been set before sending. * Normally called e.g., by a JSP before calling doSend. * Is also called by doSend for verification. * @return if complete return true else return false */ public boolean isComplete() { if (from == null || from.length() == 0) { System.err.println("doSend: no FROM"); return false; } if (subject == null || subject.length() == 0) { System.err.println("doSend: no SUBJECT"); return false; } if (toList.size() == 0) { System.err.println("doSend: no recipients"); return false; } if (body == null || body.length() == 0) { System.err.println("doSend: no body"); return false; } if (mailHost == null || mailHost.length() == 0) { System.err.println("doSend: no server host"); return false; } return true; }
public void setServer(String s) { mailHost = s; }
/** Send the message. * @throws MessagingException */ public synchronized void doSend() throws MessagingException {
if (!isComplete()) { throw new IllegalArgumentException( "doSend called before message was complete"); }
/** Properties object used to pass props into the MAIL API */ Properties props = new Properties(); props.put("mail.smtp.host", mailHost);
// Create the Session object if (session == null) { session = Session.getDefaultInstance(props, null); if (verbose) { session.setDebug(true); // Verbose! } }
// create a message final Message mesg = new MimeMessage(session);
InternetAddress[] addresses;
// TO Address list addresses = new InternetAddress[toList.size()]; for (int i = 0; i < addresses.length; i++) { addresses[i] = new InternetAddress( (String) toList.get(i)); } mesg.setRecipients(Message.RecipientType.TO, addresses);
// From Address mesg.setFrom(new InternetAddress(from));
// CC Address list addresses = new InternetAddress[ccList.size()]; for (int i = 0; i < addresses.length; i++) { addresses[i] = new InternetAddress( (String) ccList.get(i)); } mesg.setRecipients(Message.RecipientType.CC, addresses);
// BCC Address list addresses = new InternetAddress[bccList.size()]; for (int i = 0; i < addresses.length; i++) { addresses[i] = new InternetAddress( (String) bccList.get(i)); } mesg.setRecipients(Message.RecipientType.BCC, addresses);
// The Subject mesg.setSubject(subject);
// Now the message body. Multipart mp = new MimeMultipart(); MimeBodyPart mbp = null; mbp = new MimeBodyPart(); mbp.setText(body); mp.addBodyPart(mbp);
// Now the accessories. int accessoriesCount = accessories.size(); File f; DataSource ds; String uf; int j; for (int i = 0; i < accessoriesCount; i++) { mbp = new MimeBodyPart(); f = new File( (String) accessories.get(i)); ds = new FileDataSource(f); mbp.setDataHandler(new DataHandler(ds)); j = f.getName().lastIndexOf(File.separator); uf = f.getName().substring(j + 1); mbp.setFileName(uf); mp.addBodyPart(mbp); }
mesg.setContent(mp);
// Finally, send the message! (use static Transport method) // Do this in a Thread as it sometimes is too slow for JServ // new Thread() { // public void run() { // try {
Transport.send(mesg);
// } catch (MessagingException e) { // throw new IllegalArgumentException( // "Transport.send() threw: " + e.toString()); // } // } // }.start(); }
/** Convenience method that does it all with one call. * @param mailhost - SMTP server host * @param recipient - domain address of email (user@host.domain) * @param sender - your email address * @param subject - the subject line * @param message - the entire message body as a String with embedded \n's * @param accessories - the accessories list * @throws MessagingException */ public static void send(String mailhost, String recipient, String sender, String subject, String message, ArrayList accessories) throws MessagingException { Mailer m = new Mailer(); m.setServer(mailhost); m.addTo(recipient); m.setFrom(sender); m.setSubject(subject); m.setBody(message); m.setAccessories(accessories); m.doSend(); }
/** Convert a list of addresses to an ArrayList. This will work * for simple names like "tom, mary@foo.com, 123.45@c$.com" * but will fail on certain complex (but RFC-valid) names like * "(Darwin, Ian) <ian@darwinsys.com>". * Or even "Ian Darwin <ian@darwinsys.com>". * @param s the string of some list * @return the list after split */ protected ArrayList tokenize(String s) { ArrayList al = new ArrayList(); StringTokenizer tf = new StringTokenizer(s, ","); // For each word found in the line while (tf.hasMoreTokens()) { // trim blanks, and add to list. al.add(tf.nextToken().trim()); } return al; }}///
二、创建一个properties文件:
MailClient.properties:///# This file contains my default Mail properties.# # Values for sendingMail.address=xx@zsu.edu.cnMail.send.proto=smtpMail.send.host=student.zsu.edu.cnMail.send.debug=true## Values for receivingMail.receive.host=student.zsu.edu.cnMail.receive.protocol=pop3Mail.receive.user=xxMail.receive.pass=ASKMail.receive.root=d:\test///
三、创建主程序,生成Mailer.java里面的Mailer类的对象,设置参数,发出邮件。
首先import:///import java.io.*;import java.util.*;import javax.mail.internet.*;import javax.mail.*;import javax.activation.*;///
然后用下面的代码完成发送:/// try { Mailer m = new Mailer();
FileProperties props = new FileProperties(MailConstants.PROPS_FILE_NAME); String serverHost = props.getProperty(MailConstants.SEND_HOST); if (serverHost == null) { System.out.println("\"" + MailConstants.SEND_HOST + "\" must be set in properties"); System.exit(0); } m.setServer(serverHost);
String tmp = props.getProperty(MailConstants.SEND_DEBUG); m.setVerbose(tmp != null && tmp.equals("true"));
String myAddress = props.getProperty("Mail.address"); if (myAddress == null) { System.out.println("\"Mail.address\" must be set in properties"); System.exit(0); } m.setFrom(myAddress);
//以下根据具体情况设置:=============================================== m.setToList("xx@zsu.edu.cn");//收件人 m.setCcList("xx@163.com,yy@163.com");//抄送,每个地址用逗号隔开;或者用一个ArrayList的对象作为参数 // m.setBccList(bccTF.getText());
m.setSubject("demo");//主题
// Now copy the text from the Compose TextArea. m.setBody("this is a demo");//正文 // XXX I18N: use setBody(msgText.getText(), charset) ArrayList v=new ArrayList(); v.add("d:\\test.htm"); m.setAccessories(v);//附件//以上根据具体情况设置================================================= // Finally, send the sucker! m.doSend();
} catch (MessagingException me) { me.printStackTrace(); while ( (me = (MessagingException) me.getNextException()) != null) { me.printStackTrace(); } System.out.println("Mail Sending Error:\n" + me.toString()); } catch (Exception ex) { System.out.println("Mail Sending Error:\n" + ex.toString()); }///
相关资源:java中javamail发送带附件的邮件实现方法