Implementing multi-tier applications using the Servlet API
Download
Report
Transcript Implementing multi-tier applications using the Servlet API
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