Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
JavaMail API Fundamentals John Zukowski - [email protected] JZ Ventures, Inc. © 2001 JZ Ventures, Inc. 1 Agenda Getting Started Core Classes Getting Mail Sending Mail Attachments Searching Q&A © 2001 JZ Ventures, Inc. 2 Getting Started Without (Pre?) JavaMail With JavaMail http://java.sun.com/products/javamail/ © 2001 JZ Ventures, Inc. 3 Without JavaMail Read RFC 821 for SMTP http://www.cis.ohio-state.edu/htbin/rfc/rfc821.html Other RFC describe things like attachments RFC 822: Text Messages, RFC 2045-7: MIME, RFC 1939: POP3, RFC 2060: IMAP, ... Open socket connection to port 25 HELO sending host MAIL FROM: sender email RCPT TO: recipient email DATA ... the email message... ... any number of lines ... . QUIT © 2001 JZ Ventures, Inc. 4 SmtpClient import sun.net.smtp.SmtpClient; import java.io.PrintStream; public class SmtpClientExample { public static void main (String args[]) throws Exception { String host = args[0]; String from = args[1]; String to = args[2]; SmtpClient smtp = new SmtpClient(host); smtp.from(from); smtp.to(to); PrintStream msg = smtp.startMessage(); msg.println("To: " + to); msg.println("Subject: Hello SmtpClient"); msg.println(); // blank line between headers and message msg.println("This is a test message."); smtp.closeServer(); } } © 2001 JZ Ventures, Inc. 5 Without JavaMail Take 3 Just use a URL Open a mailto: URL Write to opened URLConnection Need to set mail.host System property Be sure to end lines with \r\n Don’t use println() © 2001 JZ Ventures, Inc. 6 Mail Through URL import java.io.*; import java.net.*; public class MailTo { public static void main(String args[]) throws Exception { System.getProperties().put("mail.host", args[0]); URL url = new URL("mailto:[email protected]"); URLConnection conn = url.openConnection(); PrintStream out = new PrintStream(conn.getOutputStream(), true); out.print("From: [email protected]"+"\r\n"); out.print("Subject: Works Great!"+"\r\n"); out.print("Thanks!"+"\r\n"); out.close(); System.out.println("Message Sent"); } } © 2001 JZ Ventures, Inc. 7 With JavaMail API Latest Version 1.2 Need to get JavaBeans Activation Framework December 5, 2000 release Sun includes IMAP, POP, and SMTP service providers Version 1.1.3 (2/22/2000) most popular one used http://java.sun.com/beans/glasgow/jaf.html See demo directory for many examples © 2001 JZ Ventures, Inc. 8 JavaMail Setup Add JAR files to CLASSPATH, to jre/lib/ext Applets can use: javax.* JavaMail Won’t work in Netscape though without Plug-in Will work in Internet Explorer / HotJava mail.jar (280K) Separate JAR files available if only using parts Activation Framework activation.jar (45K) © 2001 JZ Ventures, Inc. 9 JDK Requirements Works with JDK 1.1.6+ Works with Java 2 platform, Standard Edition, versions 1.2 / 1.3 Included with Java 2 platform, Enterprise Edition © 2001 JZ Ventures, Inc. 10 Core Classes Session Message / MimeMessage InternetAddress Authenticator Transport © 2001 JZ Ventures, Inc. 11 Session Represents a mail session Uses Properties to get things like mail host mail.host mail.smtp.host Get session - no constructor Session session = Session.getInstance(props, null); // null for Authenticator Session session = Session.getDefaultInstance(props, null); © 2001 JZ Ventures, Inc. 12 Message / MimeMessage Represents a mail message Get message from session Message abstract class implements Part MimeMessage is MIME style email message implements MimePart MimeMessage message = new MimeMessage(session); Set parts message.setContent() / mimeMessage.setText() © 2001 JZ Ventures, Inc. 13 InternetAddress RFC822 Address Create: new InternetAddress("[email protected]"); new InternetAddress("[email protected] ", "John Zukowski"); For To, From, CC, BCC message.setFrom(address) message.addRecipient(type, address) Types Message.RecipientType.TO Message.RecipientType.CC Message.RecipientType.BCC © 2001 JZ Ventures, Inc. 14 Authenticator Permit mechanism to prompt for username and password javax.mail.Authenticator != java.net.Authenticator Extend Authenticator Override: public PasswordAuthentication getPasswordAuthentication() { String username, password; // Then get them ... return new PasswordAuthentication(username, password); } © 2001 JZ Ventures, Inc. 15 Transport Message transport mechanism Get transport for session Connect transport.connect(host, username, password); Act - repeat if necessary Transport transport = session.getTransport("smtp"); transport.sendMessage(message, message.getAllRecipients()); Done transport.close(); © 2001 JZ Ventures, Inc. 16 Sending Mail Need a working SMTP server Can be written in Java using JavaMail API, but irrelevant Need from/to addresses, but don’t need to be valid, unless SMTP server includes some form of verification To run example: java MailExample smtp.mailserver [email protected] [email protected] © 2001 JZ Ventures, Inc. 17 Hello World import java.util.Properties; import javax.mail.*; import javax.mail.internet.*; public class MailExample { public static void main (String args[]) throws Exception { String host = args[0]; String from = args[1]; String to = args[2]; // Get system properties Properties props = System.getProperties(); // Setup mail server props.put("mail.smtp.host", host); © 2001 JZ Ventures, Inc. 18 Hello World/2 // Get session Session session = Session.getInstance(props, null); // Define message MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject("Hello JavaMail"); message.setText("Welcome to JavaMail"); // Send message Transport.send(message); } } © 2001 JZ Ventures, Inc. 19 Getting Mail POP3 provider doesn’t provide local data storage There are mailbox store providers available Need to get/install POP3 provider Part of JavaMail 1.2 release NOT part of basic JavaMail 1.1 API implementation © 2001 JZ Ventures, Inc. 20 Reading Hello World import java.io.*; import java.util.Properties; import javax.mail.*; import javax.mail.internet.*; public class GetMessageExample { public static void main (String args[]) throws Exception { String host = args[0]; String username = args[1]; String password = args[2]; // Create empty properties Properties props = new Properties(); // Get session Session session = Session.getInstance(props, null); © 2001 JZ Ventures, Inc. 21 Reading Hello World/2 // Get the store Store store = session.getStore("pop3"); store.connect(host, username, password); // Get folder Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); BufferedReader reader = new BufferedReader ( new InputStreamReader(System.in)); // Get directory Message message[] = folder.getMessages(); for (int i=0, n=message.length; i<n; i++) { © 2001 JZ Ventures, Inc. 22 Reading Hello World/3 System.out.println(i + ": " + message[i].getFrom()[0] + "\t" + message[i].getSubject()); System.out.println("Do you want to read message? [YES to read/QUIT to end]"); String line = reader.readLine(); if ("YES".equals(line)) { message[i].writeTo(System.out); } else if ("QUIT".equals(line)) { break; } } // Close connection folder.close(false); store.close(); } } © 2001 JZ Ventures, Inc. 23 Authenticator Usage Put host in properties Properties props = new Properties(); props.put("mail.host", host); Setup authentication, get session Authenticator auth = new PopupAuthenticator(); Session session = Session.getInstance(props, auth); Get the store Store store = session.getStore("pop3"); store.connect(); © 2001 JZ Ventures, Inc. 24 Saving Messages To save copy locally: Get/create appropriate provider Knife - http://www.dog.net.uk/knife/ mimeMessage.writeTo(outputStream) © 2001 JZ Ventures, Inc. 25 Replying Use Message.reply(boolean) Sets up message with proper headers boolean of true indicates reply to all vs. reply to sender only Does NOT setup message contents © 2001 JZ Ventures, Inc. 26 Deleting Messages Set message flag to deleted: Be sure folder opened read-write: folder.open(Folder.READ_WRITE); Deleted when folder closed: message.setFlag(Flags.Flag.DELETED, true); folder.close(true); // true = expunge Expunge / Permanently Deletes folder.expunge() NOT always implemented © 2001 JZ Ventures, Inc. 27 Including Attachments Each attachment goes into a MimeBodyPart DataHandler deals with reading in contents Provide it with a DataSource Either URLDataSource or FileDataSource © 2001 JZ Ventures, Inc. 28 Sending Attachments // create mime message object and set the required parameters MimeMessage message = createMessage(to, cc, subject); // create the message part MimeBodyPart messageBodyPart = new MimeBodyPart(); //fill message messageBodyPart.setText(msg); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // fill the array of files to be attached File [] attachments = { .... } © 2001 JZ Ventures, Inc. 29 Sending Attachments/2 for( int i = 0; i < attachments.length; i++ ) { messageBodyPart = new MimeBodyPart(); FileDataSource fileDataSource =new FileDataSource(attachments[i]); messageBodyPart.setDataHandler(new DataHandler(fileDataSource)); messageBodyPart.setFileName(attachments[i].getName()); multipart.addBodyPart(messageBodyPart); } // add the Multipart to the message message.setContent(multipart); // SEND THE MESSAGE Transport.send(message); © 2001 JZ Ventures, Inc. 30 Sending HTML Attachment Don’t use setText() Use setDataHandler() String htmlText = "<H1>Hello</H1><H2>World</H2>"; message.setContent(htmlText, "text/html")); © 2001 JZ Ventures, Inc. 31 Including HTML Images Inline Specify Image source with cid: URL Set Content-ID in header of image attachment <IMG SRC=cid:23abc@pc27> part.setHeader("ContentID","23abc@pc27"); Complete example: http://www.jguru.com/jguru/faq/view.jsp?EID=97371 © 2001 JZ Ventures, Inc. 32 Getting Attachments from Client You want to create a web-based email system Your user wants to include file from their system as attachment Use an HTML Form Use Servlet to read stream Use MultipartRequest class from O’Reilly servlets book – www.servlets.com © 2001 JZ Ventures, Inc. 33 HTML Form <FORM ENCTYPE="multipart/form-data" method=post action="/myservlet"> <INPUT TYPE="file" NAME="mptest"> <INPUT TYPE="submit" VALUE="upload"> </FORM> © 2001 JZ Ventures, Inc. 34 Getting Attachments For each part of Multipart, process part Attachments can be inline or not String disposition = part.getDisposition(); if (disposition.equals(Part.INLINE)) if (disposition.equals(Part.ATTACHMENT)) © 2001 JZ Ventures, Inc. 35 Save Attachments public static void handleMultipart(Multipart multipart) throws MessagingException, IOException { for (int i=0, n=multipart.getCount(); i<n; i++) { handlePart(multipart.getBodyPart(i)); } } Following code doesn’t deal with Multipart in Multipart left as exercise for reader © 2001 JZ Ventures, Inc. 36 Save Attachments/2 public static void handlePart(Part part) throws MessagingException, IOException { String disposition = part.getDisposition(); String contentType = part.getContentType(); if (disposition == null) { // When just body System.out.println("Null: " + contentType); // Check if plain if ((contentType.length() >= 10) && (contentType.toLowerCase().substring(0, 10).equals("text/plain"))) { part.writeTo(System.out); } else { // Don't think this will happen System.out.println("Other body: " + contentType); part.writeTo(System.out); } © 2001 JZ Ventures, Inc. 37 Save Attachments/3 } else if (disposition.equals(Part.ATTACHMENT)) { System.out.println("Attachment: " + part.getFileName() + " : " + contentType); saveFile(part.getFileName(), part.getInputStream()); } else if (disposition.equals(Part.INLINE)) { System.out.println("Inline: " + part.getFileName() + " : " + contentType); saveFile(part.getFileName(), part.getInputStream()); } else { // Should never happen System.out.println("Other: " + disposition); } } © 2001 JZ Ventures, Inc. 38 Debugging Trace commands sent session.setDebug(true) © 2001 JZ Ventures, Inc. 39 New Mail Notification Events Add MessageCountListener to folder Find out when new messages are received Sleep then folder.getMessageCount() to get notification from IMAP server Not POP3 - Does not work when folder open © 2001 JZ Ventures, Inc. 40 More Notification Events Transport/Store/Folder.addConnectionListener () open, closed, disconnected created, deleted, renamed changed notification Folder.addFolderListener() Folder.addMessageChangeListener Store.addStoreListener Transport.addTransportListener message delivered, not delivered, partially delivered © 2001 JZ Ventures, Inc. 41 JavaMail Searching API includes support for searching for matching messages javax.mail.search package Build a SearchTerm Search: Message[] msgs = folder.search(st); © 2001 JZ Ventures, Inc. 42 Building Up SearchTerm AND terms (class AndTerm) OR terms (class OrTerm) NOT terms (class NotTerm) SENT DATE terms (class SentDateTerm) CONTENT terms (class BodyTerm) HEADER terms (FromTerm / FromStringTerm, RecipientTerm / RecipientStringTerm, SubjectTerm, etc..) © 2001 JZ Ventures, Inc. 43 Using SearchTerm Folder folder = store.getFolder("INBOX"); SearchTerm st = new AndTerm(new SubjectTerm("ADV:"), new BodyTerm("hello"); Message[] msgs = folder.search(st); © 2001 JZ Ventures, Inc. 44 S/MIME Includes email signing and encryption support Get a different provider Phaos S/MIME toolkit http://www.phaos.com/e_security/prod_smime. html JCSI http://security.dstc.edu.au/projects/java/releas e2.html © 2001 JZ Ventures, Inc. 45 JavaMail with JSP Definitely doable with Java source scriptlets However, should limit amount of Java source in JSP pages Use JavaBeans that hide/simplify capabilities for Web designer Create / Get ImMailBean http://www.imessaging.com/html/immailbean.html Source Fourge http://sourceforge.net/project/?group_id=1282 © 2001 JZ Ventures, Inc. 46 JavaMail with NNTP You can use JavaMail with NNTP Need to get an NNTP provider http://www.dog.net.uk/knife/ To read newsgroups Store store = session.getStore("nntp"); store.connect(host, username, password); Folder folder = store.getFolder(newsgroup); folder.open(Folder.READ_ONLY); Message message[] = folder.getMessages(); © 2001 JZ Ventures, Inc. 47 JavaMail is Free Sun’s reference implementation is completely free Sun’s License: http://java.sun.com/products/javamail/LIC ENSE.txt Includes SMTP, IMAP, and POP3 providers © 2001 JZ Ventures, Inc. 48 James Java Apache Mail Enterprise Server Pure Java-based mail server Supports Mailets Like servlets, but for extending mail server Add capabilities like mailing list support, filtering, translation, etc. http://java.apache.org/james/index.html © 2001 JZ Ventures, Inc. 49 Miscellaneous Sun’s JavaMail FAQ Mailing List http://java.sun.com/products/javamail/FAQ.html http://archives.java.sun.com/archives/javamail-interest.html Get the JavaMail Source 1.1.2 source part of J2EE Sun Community Source Licensing http://www.sun.com/software/communitysource/j2ee/ © 2001 JZ Ventures, Inc. 50 Other Providers knife Project "POPpers" http://www.dog.net.uk/knife/ NNTP, POP3, mailbox file provider http://www2s.biglobe.ne.jp/~dat/java/project/pop pers/index_en.html ICEMail Java-based Email Client http://www.icemail.org/ © 2001 JZ Ventures, Inc. 51 Questions & Answers Questions? Use the FAQs John Zukowski http://www.jguru.com http://java.about.com http://www.jguru.com/faq/JavaMail © 2001 JZ Ventures, Inc. 52