Java/Swing Components/Email Client

Материал из Java эксперт
Перейти к: навигация, поиск

A Client to Send SMTP Mail

   <source lang="java">

import java.awt.*; import javax.swing.*; /**

* Example program from Chapter 1 Programming Spiders, Bots and Aggregators in
* Java Copyright 2001 by Jeff Heaton
* 
* SendMail is an example of client sockets. This program presents a simple
* dialog box that prompts the user for information about how to send a mail.
* 
* @author Jeff Heaton
* @version 1.0
*/

/*

* Using the SMTP Program
* 
* To use the program in Listing 1.2, you must know the address of an SMTP
* server usually provided by your ISP. If you are unsure of your SMTP server,
* you should contact your ISP"s customer service. In order for outbound e-mail
* messages to be sent, your e-mail program must have this address. Once it
* does, you can enter who is sending the e-mail (if you are sending it, you
* would type your e-mail address in) and who will be on the receiving end. This
* is usually entered under the Reply To field of your e-mail program. Both of
* these addresses must be valid. If they are invalid, the e-mail may not be
* sent. After you have entered these addresses, you should continue by entering
* the subject, writing the actual message, and then clicking send. Note
* 
* For more information on how to compile examples in this book, see Appendix E
* "How to Compile Examples Under Windows."
* 
* As stated earlier, to send an e-mail with this program, you must enter who is
* sending the message. You may be thinking that you could enter any e-mail
* address you want here, right? Yes, this is true; as long as the SMTP server
* allows it, this program will allow you to impersonate anyone you enter into
* the To address field. However, as previously stated, a savvy Internet user
* can tell whether the e-mail address is fake.
* 
* After the mention of possible misrepresentation of identity on the sender"s
* end, you may now be asking yourself, Is this program dangerous? This
* program is no more dangerous than any e-mail client (such as Microsoft
* Outlook Express or Eudora) that also requires you to tell it who you are. In
* general, all e-mail programs must request both your identity and that of the
* SMTP server. Examining the SMTP Server
* 
* You will now be shown how this program works. We will begin by looking at how
* a client socket is created. When the client socket is first instantiated, you
* must specify two parameters. First, you must specify the host to connect to;
* second, you must specify the port number (e.g., 80) you would like to connect
* on. These two items are generally passed into the constructor. The following
* line of code (from Listing 1.2) accomplishes this:
* 
* java.net.Socket s =new java.net.Socket( _smtp.getText(),25 );
* 
* This line of code creates a new socket, named s. The first parameter to the
* constructor, _smtp .getText(), specifies the address to connect to. Here it
* is being read directly from a text field. The second parameter specifies the
* port to connect to. (The port for SMTP is 25.) Table 1.1 shows a listing of
* the ports associated with most Internet services. The hostname is retrieved
* from the _smtp class level variable, which is the JTextField control that the
* SMTP hostname is entered into.
* 
* If any errors occur while you are making the connection to the specified
* host, the Socket constructor will throw an IOException. Once this connection
* is made, input and output streams are obtained from the Socket.getInputStream
* and Socket.getOutputStream methods. This is done with the following lines of
* code from Listing 1.2:
* 
* _out = new java.io.PrintWriter(s.getOutputStream());
* _in = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream()));
* 
* These low-level stream types are only capable of reading binary data. Because
* this data is needed in text format, filters are used to wrap the lower-level
* input and output streams obtained from the socket.
* 
* In the code above, the output stream has been wrapped in a PrintWriter
* object. This is because PrintWriter allows the program to output text to the
* socket in a similar manner to the way an application would write data to the
* System.out object by using the print and println methods. The application
* presented here uses the println method to send commands to the SMTP server.
* As you can see in the code, the InputStream object has also been wrapped; in
* this case, it has been wrapped in a BufferedReader. Before this could happen,
* however, this object must first have been wrapped in an InputStreamReader
* object as shown here:
* 
* _in = new java.io.BufferedReader(new
* java.io.InputStreamReader(s.getInputStream()));
* 
* This is done because the BufferedReader object provides reads that are made
* up of lines of text instead of individual bytes. This way, the program can
* read text up to a carriage return without having to parse the individual
* characters. This is done with the readLine method.
* 
* You will now be shown how each command is sent to the SMTP server. Each of
* these commands that is sent results in a response being issued from the SMTP
* server. For the protocol to work correctly, each response must be read by the
* SMTP client program. These responses start with a number and then they give a
* textual description of what the result was. A full-featured SMTP client
* should examine these codes and ensure that no error has occurred.
* 
* For the purposes of the SendMail example, we will simple ignore these
* responses because most are informational and not needed. Instead, for our
* purposes, the response will be read in and displayed to the _output list box.
* Commands that have been sent to the server are displayed in this list with a
* C: prefix to indicate that they are from the client. Responses returned from
* the SMTP server will be displayed with the S: prefix.
* 
* To accomplish this, the example program will use the send method. The send
* method accepts a single String parameter to indicate the SMTP command to be
* issued. Once this command is sent, the send method awaits a response from the
* SMTP host. The portion of Listing 1.2 that contains the send method is
* displayed here:
* 
* protected void send(String s) throws java.io.IOException { 
       // Send the SMTP command 
        if(s!=null) { 
        _model.addElement("C:"+s); 
        _out.println(s);
       _out.flush(); } 
      // Wait for the response 
        String line = _in.readLine();
       if(line!=null) { 
      _model.addElement("S:"+line); 
      } 
}
* 
* As you can see, the send method does not handle the exceptions that might
* occur from its commands. Instead, they are thrown to the calling method as
* indicated by the throws clause of the function declaration. The variable s is
* checked to see if it is null. If s is null, then no command is to be sent and
* only a response is sought. If s is not null, then the value of s is logged
* and then sent to the socket. After this happens, the flush command is given
* to the socket to ensure that the command was actually sent and not just
* buffered. Once the command is sent, the readLine method is called to await
* the response from the server. If a response is sent, then it is logged.
* 
* Once the socket is created and the input and output objects are created, the
* SMTP session can begin. The following commands manage the entire SMTP
* session:
* 
* send(null); 
* send("HELO " + java.net.InetAddress.getLocalHost().getHostName() );
* send("MAIL FROM: " + _from.getText() ); send("RCPT TO: " + _to.getText() );
* send("DATA"); 
* _out.println("Subject:" + _subject.getText()); _out.println(
* _body.getText() ); send("."); s.close();
* 
* Tip
* 
* Refer to Table 1.4 in the preceding section to review the details of what
* each of the SMTP commands actually means.
* 
* The rest of the SendMail program (as seen in Listing 1.2) is a typical Swing
* application. The graphical user interface (GUI) layout for this application
* was created using VisualCaf?. The VisualCaf? comments have been left in to
* allow the form"s GUI layout to be edited by VisualCaf? if you are using it.
* If you are using an environment other than VisualCaf?, you may safely delete
* the VisualCaf? comments (lines starting in //). The VisualCaf? code only
* consists of comments and does not need to be deleted to run on other
* platforms.
*  
*/

public class SendMail extends javax.swing.JFrame {

 /**
  * The constructor. Do all basic setup for this application.
  */
 public SendMail() {
   //{{INIT_CONTROLS
   setTitle("SendMail Example");
   getContentPane().setLayout(null);
   setSize(736, 312);
   setVisible(false);
   JLabel1.setText("From:");
   getContentPane().add(JLabel1);
   JLabel1.setBounds(12, 12, 36, 12);
   JLabel2.setText("To:");
   getContentPane().add(JLabel2);
   JLabel2.setBounds(12, 48, 36, 12);
   JLabel3.setText("Subject:");
   getContentPane().add(JLabel3);
   JLabel3.setBounds(12, 84, 48, 12);
   JLabel4.setText("SMTP Server:");
   getContentPane().add(JLabel4);
   JLabel4.setBounds(12, 120, 84, 12);
   getContentPane().add(_from);
   _from.setBounds(96, 12, 300, 24);
   getContentPane().add(_to);
   _to.setBounds(96, 48, 300, 24);
   getContentPane().add(_subject);
   _subject.setBounds(96, 84, 300, 24);
   getContentPane().add(_smtp);
   _smtp.setBounds(96, 120, 300, 24);
   getContentPane().add(_scrollPane2);
   _scrollPane2.setBounds(12, 156, 384, 108);
   _body.setText("Enter your message here.");
   _scrollPane2.getViewport().add(_body);
   _body.setBounds(0, 0, 381, 105);
   Send.setText("Send");
   Send.setActionCommand("Send");
   getContentPane().add(Send);
   Send.setBounds(60, 276, 132, 24);
   Cancel.setText("Cancel");
   Cancel.setActionCommand("Cancel");
   getContentPane().add(Cancel);
   Cancel.setBounds(216, 276, 120, 24);
   getContentPane().add(_scrollPane);
   _scrollPane.setBounds(408, 12, 312, 288);
   getContentPane().add(_output);
   _output.setBounds(408, 12, 309, 285);
   //}}
   //{{INIT_MENUS
   //}}
   //{{REGISTER_LISTENERS
   SymAction lSymAction = new SymAction();
   Send.addActionListener(lSymAction);
   Cancel.addActionListener(lSymAction);
   //}}
   _output.setModel(_model);
   _model.addElement("Server output displayed here:");
   _scrollPane.getViewport().setView(_output);
   _scrollPane2.getViewport().setView(_body);
 }
 /**
  * Moves the app to the correct position when it is made visible.
  * 
  * @param b
  *            True to make visible, false to make invisible.
  */
 public void setVisible(boolean b) {
   if (b)
     setLocation(50, 50);
   super.setVisible(b);
 }
 /**
  * The main function basically just creates a new object, then shows it.
  * 
  * @param args
  *            Command line arguments. Not used in this application.
  */
 static public void main(String args[]) {
   (new SendMail()).show();
 }
 /**
  * Created by VisualCafe. Sets the window size.
  */
 public void addNotify() {
   // Record the size of the window prior to
   // calling parents addNotify.
   Dimension size = getSize();
   super.addNotify();
   if (frameSizeAdjusted)
     return;
   frameSizeAdjusted = true;
   // Adjust size of frame according to the
   // insets and menu bar
   Insets insets = getInsets();
   javax.swing.JMenuBar menuBar = getRootPane().getJMenuBar();
   int menuBarHeight = 0;
   if (menuBar != null)
     menuBarHeight = menuBar.getPreferredSize().height;
   setSize(insets.left + insets.right + size.width, insets.top
       + insets.bottom + size.height + menuBarHeight);
 }
 // Used by addNotify
 boolean frameSizeAdjusted = false;
 //{{DECLARE_CONTROLS
 /**
  * A label.
  */
 javax.swing.JLabel JLabel1 = new javax.swing.JLabel();
 /**
  * A label.
  */
 javax.swing.JLabel JLabel2 = new javax.swing.JLabel();
 /**
  * A label.
  */
 javax.swing.JLabel JLabel3 = new javax.swing.JLabel();
 /**
  * A label.
  */
 javax.swing.JLabel JLabel4 = new javax.swing.JLabel();
 /**
  * Who this message is from.
  */
 javax.swing.JTextField _from = new javax.swing.JTextField();
 /**
  * Who this message is to.
  */
 javax.swing.JTextField _to = new javax.swing.JTextField();
 /**
  * The subject of this message.
  */
 javax.swing.JTextField _subject = new javax.swing.JTextField();
 /**
  * The SMTP server to use to send this message.
  */
 javax.swing.JTextField _smtp = new javax.swing.JTextField();
 /**
  * A scroll pane.
  */
 javax.swing.JScrollPane _scrollPane2 = new javax.swing.JScrollPane();
 /**
  * The body of this email message.
  */
 javax.swing.JTextArea _body = new javax.swing.JTextArea();
 /**
  * The send button.
  */
 javax.swing.JButton Send = new javax.swing.JButton();
 /**
  * The cancel button.
  */
 javax.swing.JButton Cancel = new javax.swing.JButton();
 /**
  * A scroll pain.
  */
 javax.swing.JScrollPane _scrollPane = new javax.swing.JScrollPane();
 /**
  * The output area. Server messages are displayed here.
  */
 javax.swing.JList _output = new javax.swing.JList();
 //}}
 /**
  * The list of items added to the output list box.
  */
 javax.swing.DefaultListModel _model = new javax.swing.DefaultListModel();
 /**
  * Input from the socket.
  */
 java.io.BufferedReader _in;
 /**
  * Output to the socket.
  */
 java.io.PrintWriter _out;
 //{{DECLARE_MENUS
 //}}
 /**
  * Internal class created by VisualCafe to route the events to the correct
  * functions.
  * 
  * @author VisualCafe
  * @version 1.0
  */
 class SymAction implements java.awt.event.ActionListener {
   /**
    * Route the event to the correction method.
    * 
    * @param event
    *            The event.
    */
   public void actionPerformed(java.awt.event.ActionEvent event) {
     Object object = event.getSource();
     if (object == Send)
       Send_actionPerformed(event);
     else if (object == Cancel)
       Cancel_actionPerformed(event);
   }
 }
 /**
  * Called to actually send a string of text to the socket. This method makes
  * note of the text sent and the response in the JList output box. Pass a
  * null value to simply wait for a response.
  * 
  * @param s
  *            A string to be sent to the socket. null to just wait for a
  *            response.
  * @exception java.io.IOException
  */
 protected void send(String s) throws java.io.IOException {
   // Send the SMTP command
   if (s != null) {
     _model.addElement("C:" + s);
     _out.println(s);
     _out.flush();
   }
   // Wait for the response
   String line = _in.readLine();
   if (line != null) {
     _model.addElement("S:" + line);
   }
 }
 /**
  * Called when the send button is clicked. Actually sends the mail message.
  * 
  * @param event
  *            The event.
  */
 void Send_actionPerformed(java.awt.event.ActionEvent event) {
   try {
     java.net.Socket s = new java.net.Socket(_smtp.getText(), 25);
     _out = new java.io.PrintWriter(s.getOutputStream());
     _in = new java.io.BufferedReader(new java.io.InputStreamReader(s
         .getInputStream()));
     send(null);
     send("HELO " + java.net.InetAddress.getLocalHost().getHostName());
     send("MAIL FROM: " + _from.getText());
     send("RCPT TO: " + _to.getText());
     send("DATA");
     _out.println("Subject:" + _subject.getText());
     _out.println(_body.getText());
     send(".");
     s.close();
   } catch (Exception e) {
     _model.addElement("Error: " + e);
   }
 }
 /**
  * Called when cancel is clicked. End the application.
  * 
  * @param event
  *            The event.
  */
 void Cancel_actionPerformed(java.awt.event.ActionEvent event) {
   System.exit(0);
 }

}

      </source>