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毫秒