Java 版 (精华区)
发信人: asdf (变量), 信区: Java
标 题: J D C T E C H T I P S
发信站: 哈工大紫丁香 (Thu Jan 24 12:33:43 2002) , 转信
J D C T E C H T I P S
TIPS, TECHNIQUES, AND SAMPLE CODE
WELCOME to the Java Developer Connection(sm) (JDC) Tech Tips,
January 22, 2001. This issue covers:
* Retrieving Mail with the JavaMail(tm) API
* Working with the Java(tm) Communications API
These tips were developed using Java 2 SDK, Standard Edition,
v 1.3 and Java 2 Enterprise Edition, v 1.3.
This issue of the JDC Tech Tips is written by John Zukowski,
president of JZ Ventures, Inc. (http://www.jzventures.com).
You can view this issue of the Tech Tips on the Web at
http://java.sun.com/jdc/JDCTechTips/2002/tt0122.html
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RETRIEVING MAIL WITH THE JAVAMAIL API
The JavaMail API provides the framework for sending and
retrieving electronic messages (email). The JDC Tech Tip
"Sending Mail With the JavaMail API"
(http://java.sun.com/jdc/JDCTechTips/2001/tt1023.html#tip2)
showed you how to send mail via SMTP through the JavaMail API.
In this tip, you'll see how to retrieve messages from your
POP/IMAP server.
In many ways retrieving messages is similar to sending. For
example, sending mail involves using the Session, Message,
Address, and Transport classes. Retrieving messages involves the
same Session and Message classes, however you also use Folder and
Store classes. Once you make a connection to the mail server for
message retrieval, the messages are stored in a Folder of the
Store.
The first thing you do to retrieve mail is connect to the mail
server, just as you do for sending mail. But the mail servers
are different. When you send mail, you connect to a server that
supports the Simple Mail Transfer Protocol (SMTP). This is
a protocol explicitly for sending electronic mail. When you
retrieve mail, you connect to a server that supports the Post
Office Protocol, Version 3 (POP3) or Internet Message Access
Protocol, Version 4 (IMAP4) protocol. These protocols are
designed for retrieving electronic mail. POP is a simple
protocol. It allows users to retrieve mail, but it doesn't have
the sophistication to do things like identify "new" mail. IMAP,
by comparison, is more sophisticated.
You can get a mail session with either the getDefaultInstance()
or getInstance() methods of Session. Calling the
getDefaultInstance() method returns a shared session instance.
This means that the same session is returned (and thus shared) by
every call to the method. The getInstance() method returns a new
session instance each time you call it. New sessions are useful
when you don't want other threads to be working simultaneously
with the shared session.
When you get the session, you must pass a Properties
instance. This contains property settings such as the mail server
you're using for the connection. You need to set the
"mail.pop3.host" (or "mail.imap.host") to the mail server for the
connection (for example, pop.example.com):
// Setup properties
Properties props = System.getProperties();
props.put("mail.pop3.host", host);
When you send mail, you should authenticate the connection, for
instance, prompt for a username and password. You
can do this by extending JavaMail's Authenticator class. For
example, the following class, PopupAuthenticator, uses a Swing
JOptionPane to prompt for a username and password. In this
example, the user would enter the username and password as
a comma-separated list. Notice that the
getPasswordAuthentication() method returns the username and
password. (Feel free to improve on this to use a JPasswordField
instead for the password.)
import javax.mail.*;
import javax.swing.*;
import java.util.*;
public class PopupAuthenticator
extends Authenticator {
public PasswordAuthentication
getPasswordAuthentication() {
String username, password;
String result = JOptionPane.showInputDialog(
"Enter 'username,password'");
StringTokenizer st =
new StringTokenizer(result, ",");
username = st.nextToken();
password = st.nextToken();
return new PasswordAuthentication(
username, password);
}
}
After you have the Properties, and an Authenticator, you can get
a Session:
// Setup authentication, get session
Authenticator auth = new PopupAuthenticator();
Session session =
Session.getDefaultInstance(props, auth);
Then make a connection to the Store with the getStore() method,
passing the method the appropriate mail protocol for your server
-- either "pop3" or "imap". Here's how you would make the
appropriate connection to a POP3 server:
// Get the store
Store store = session.getStore("pop3");
store.connect();
The call to the connect() method of Store triggers a call to
PopupAuthenticator. As mentioned earlier, PopupAuthenticator
prompts for a valid username and password combination. If you
respond with a valid userid and password for the mail account,
a connection is established with the mail server and you can
then read your mail.
All mail is stored in folders, that is, instances of the Folder
class. So to read mail, the first thing you do is connect to the
appropriate Folder. In the case of POP mail, there is only one
folder, INBOX. In the case of IMAP, the Folder can be INBOX or
any other folders that you created. Assuming you want to read
mail from your INBOX, simply connect to the folder with the
getFolder() method of Session:
// Get folder
Folder folder = store.getFolder("INBOX");
Next, you need to open the Folder with the open() method. You can
open it in either Folder.READ_WRITE mode or Folder.READ_ONLY
mode. To read messages, you can use read-only, although if you
want to delete messages, you need to use READ_WRITE.
folder.open(Folder.READ_ONLY);
Connecting to the Folder gives you access to the individual
Message objects. You can use the getMessage() method to get an
individual message, or as in the following example, use the
getMessages() method to get all the messages:
// Get directory
Message message[] = folder.getMessages();
The Folder class also defines a getNewMessageCount() method to
count the number of new messages in the Folder. However you
shouldn't use it if you use a POP server -- remember POP doesn't
support the concept of "new" messages.
You have several options in deciding what to retrieve from each
message. For instance, you can call getFrom() or getSubject() to
retrieve the identity of the sender (as an Address array), or
the message subject, respectively.
// Display from (only first) and subject of messages
for (int i=0, n=message.length; i<n; i++) {
System.out.println(i + ": "
+ message[i].getFrom()[0]
+ "\t" + message[i].getSubject());
}
More than likely though, you're interested in the message
content. Typically, you use the getContent() method to see the
message content:
System.out.println(message[i].getContent());
You can also use the writeTo() method to get the message content.
This permits you to save the entire contents of the message
(including headers) to an output stream.
After reading your mail, be sure to close the Folder and the
Store. In the case of the Folder, the close() method requires
you to specify whether you want to expunge any deleted messages.
The Store doesn't require any arguments to its close() method:
// Close connection
folder.close(false);
store.close();
What follows is a complete program, Fetch, that demonstrates the
concepts described above. In order to run the program, you'll
need to have the JavaMail API installed, as well as the
JavaBeans(tm) Activation Framework. Information about where to
get the downloads follows the program below.
The Fetch program displays the first 200 characters of any
messages currently stored in your INBOX. If your mail server
supports IMAP and not POP, change the "pop3" references in the
code to "imap". Before you compile the program, remember to first
compile the PopupAuthenticator class shown earlier.
Run the Fetch program from the command line like this:
java Fetch mailserver
Replace "mailserver" with the name of your mail server.
In response, the program will prompt you for your userid and
password.
import java.io.*;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
public class Fetch {
public static void main (String args[])
throws Exception {
String host = args[0];
// Get system properties
Properties props = System.getProperties();
props.put("mail.pop3.host", host);
// Setup authentication, get session
Authenticator auth = new PopupAuthenticator();
Session session =
Session.getDefaultInstance(props, auth);
// Get the store
Store store = session.getStore("pop3");
store.connect();
// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
// Get directory
Message message[] = folder.getMessages();
for (int i=0, n=message.length; i<n; i++) {
System.out.println(i + ": "
+ message[i].getFrom()[0]
+ "\t" + message[i].getSubject());
String content =
message[i].getContent().toString();
if (content.length() > 200) {
content = content.substring(0, 200);
}
System.out.print(content);
}
// Close connection
folder.close(false);
store.close();
System.exit(0);
}
}
The latest version of the JavaMail API is available for download
from the JavaMail API page
(http://java.sun.com/products/javamail/). To use the JavaMail API,
you must also have the JavaBeans Activation Framework installed.
The JavaBeans Activation Framework is available for download
from the JavaBeans Activation Framework page
(http://java.sun.com/products/javabeans/glasgow/jaf.html). You
can also get the JavaMail API and the JavaBeans Activation
Framework as part of the Java 2 Platform, Enterprise Edition 1.3
download at http://java.sun.com/j2ee/download.html. Source code
for the JavaMail classes is available through the J2EE 1.3 Sun
Community Source Licensing (SCSL) program at
http://www.sun.com/software/communitysource/j2ee/.
Here's a variation on the previous approach. If you don't want to
use an Authenticator, get a Session without setting any
properties. Then, provide the host name, username, and password
to the connect() method. The following
snippet shows this behavior:
// Setup empty properties
Properties props = new Properties();
// Get session
Session session = Session.getDefaultInstance(props, null);
// Get the store
Store store = session.getStore("pop3");
store.connect(host, username, password);
Notice that the Fetch example does not deal with any message
content as an attachment. For information on fetching
attachments, see the tutorial "Fundamentals of the JavaMail API
at http://java.sun.com/jdc/onlineTraining/JavaMail/.
Also, if you use Yahoo for mail, you must enable POP Access &
Forwarding from their Options screen to get mail through the
JavaMail API. You can't use Hotmail though -- it doesn't support
remote access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WORKING WITH THE JAVA COMMUNICATIONS API
The Java Communications (COMM) API is an optional package for the
Java 2 platform. It provides support for communicating with
peripheral devices through the serial and parallel ports of
a computer. It is a special API in the sense that while the API
is well defined across platforms, you must download
a platform-specific version of the COMM libraries to actually use
them.
This tip will demonstrate the COMM API by showing you how to get
a list of the available ports on a machine and printing to a
printer. The COMM API does not include support for communicating
over Universal Serial Bus (USB) ports. Support for USB ports will
be provided by a separate API that is currently undergoing
a public review through the Java Community Process (JCP). See
JSR 80 (http://www.jcp.org/jsr/detail/80.jsp) for details.
To begin, download and unpack the Java Communications API. To
get the Java Communications API for Windows and Solaris
platforms visit the Java Communications API page at
http://java.sun.com/products/javacomm/.
When you do that, you need to do a little setup work. You don't
just put the comm.jar file into your class path, though that is
the first step. You also must copy the shared library to the bin
directory, and the javax.comm.properties file to the lib directory
of the runtime environment. For Java 2 SDK, version 1.3 for
Windows, that means:
copy comm.jar \jdk1.3\jre\lib\ext
copy win32com.dll \jdk1.3\bin
copy javax.comm.properties \jdk1.3\jre\lib
After doing the setup work, the Java Communications API classes
are available from the javax.comm package. The key classes in the
package are CommPortIdentifier and CommPort. You use
CommPortIdentifier to find out the set of installed CommPort
objects. You can then communicate with any individual CommPort
object.
To find out what ports are installed, you ask the
CommPortIdentifier for the installed set with
getPortIdentifiers(). This returns an Enumeration of
CommPortIdentifier objects. Each object is of the type
PORT_PARALLEL or PORT_SERIAL, two constants in the
CommPortIdentifier class.
To demonstrate, the following fetches the set of ports available
and reports the name and type of each:
import javax.comm.*;
import java.util.Enumeration;
public class ListPorts {
public static void main(String args[]) {
Enumeration ports =
CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements()) {
CommPortIdentifier port =
(CommPortIdentifier)ports.nextElement();
String type;
switch (port.getPortType()) {
case CommPortIdentifier.PORT_PARALLEL:
type = "Parallel";
break;
case CommPortIdentifier.PORT_SERIAL:
type = "Serial";
break;
default: /// Shouldn't happen
type = "Unknown";
break;
}
System.out.println(port.getName() + ": " + type);
}
}
}
ListPorts should produce results similar to the following:
COM1: Serial
COM2: Serial
LPT1: Parallel
LPT2: Parallel
In addition to walking through an Enumeration of ports from the
CommPortIdentifier, you can ask for a specific port. You do this
by passing the name of the port (LPT1, for instance) to the
getPortIdentifier() identifier method. This returns the port
identifier, or throws a javax.comm.NoSuchPortException if the
port doesn't exist.
// Get port
CommPortIdentifier portId =
CommPortIdentifier.getPortIdentifier(portname);
To read from or write to a port, use the open() method. The
open() method requires an owner name for the port, and a timeout
value in milliseconds.
// Open port
// Open requires a owner name and timeout
CommPort port = portId.open("Application Name", 30000);
After you've opened a port, you can read and write to it just
like a socket connection. The InputStream is available from the
getInputStream() method of CommPort and the OutputStream is
available with getOutputStream().
// Setup output
OutputStream os = port.getOutputStream();
BufferedOutputStream bos =
new BufferedOutputStream(os);
Let's use the COMM API to print a file. To do that, you simply
find the printer port, open it, get its OutputStream, and send
the file contents through it. The following example demonstrates
that sequence. It prints a sample PostScript file named
sample.ps. You'll need to create the sample file first. Be sure
to close the port and streams when you are finished with them.
import javax.comm.*;
import java.io.*;
public class PrintFile {
public static void main(String args[])
throws Exception {
if (args.length != 2) {
System.err.println(
"usage : java PrintFile port file");
System.err.println(
"sample: java PrintFile LPT1 sample.ps");
System.exit(-1);
}
String portname = args[0];
String filename = args[1];
// Get port
CommPortIdentifier portId =
CommPortIdentifier.getPortIdentifier(portname);
// Open port
// Open requires a owner name and timeout
CommPort port = portId.open("Application Name", 30000);
// Setup reading from file
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
// Setup output
OutputStream os = port.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
int c;
while ((c = br.read()) != -1) {
bos.write(c);
}
// Close
bos.close();
br.close();
port.close();
}
}
For more information about the Java Communications API, see the
Java Communications API Users Guide at
http://java.sun.com/products/javacomm/javadocs/API_users_guide.html
. . . . . . . . . . . . . . . . . . . . . . .
IMPORTANT: Please read our Terms of Use and Privacy policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
* FEEDBACK
Comments? Send your feedback on the JDC Tech Tips to:
jdc-webmaster@sun.com
* SUBSCRIBE/UNSUBSCRIBE
- To subscribe, go to the subscriptions page,
(http://developer.java.sun.com/subscription/), choose
the newsletters you want to subscribe to and click "Update".
- To unsubscribe, go to the subscriptions page,
(http://developer.java.sun.com/subscription/), uncheck the
appropriate checkbox, and click "Update".
- To use our one-click unsubscribe facility, see the link at
the end of this email:
- ARCHIVES
You'll find the JDC Tech Tips archives at:
http://java.sun.com/jdc/TechTips/index.html
- COPYRIGHT
Copyright 2002 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.
This document is protected by copyright. For more information, see:
http://java.sun.com/jdc/copyright.html
JDC Tech Tips
January 22, 2002
Sun, Sun Microsystems, Java, Java Developer Connection, JavaMail,
and JavaBeans are trademarks or registered trademarks of
Sun Microsystems, Inc. in the United States and other countries.
--
※ 来源:.哈工大紫丁香 http://bbs.hit.edu.cn [FROM: 211.167.226.69]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:209.123毫秒