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