All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.net.smtp.SMTPClient Maven / Gradle / Ivy

Go to download

Apache Commons Net library contains a collection of network utilities and protocol implementations. Supported protocols include: Echo, Finger, FTP, NNTP, NTP, POP3(S), SMTP(S), Telnet, Whois

There is a newer version: 20030805.205232
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.net.smtp;

import java.io.IOException;
import java.io.Writer;
import java.net.InetAddress;

import org.apache.commons.net.io.DotTerminatedMessageWriter;

/**
 * SMTPClient encapsulates all the functionality necessary to send files
 * through an SMTP server.  This class takes care of all
 * low level details of interacting with an SMTP server and provides
 * a convenient higher level interface.  As with all classes derived
 * from {@link org.apache.commons.net.SocketClient},
 * you must first connect to the server with
 * {@link org.apache.commons.net.SocketClient#connect  connect }
 * before doing anything, and finally
 * {@link org.apache.commons.net.SocketClient#disconnect  disconnect }
 * after you're completely finished interacting with the server.
 * Then you need to check the SMTP reply code to see if the connection
 * was successful.  For example:
 * 
 *    try {
 *      int reply;
 *      client.connect("mail.foobar.com");
 *      System.out.print(client.getReplyString());
 *
 *      // After connection attempt, you should check the reply code to verify
 *      // success.
 *      reply = client.getReplyCode();
 *
 *      if(!SMTPReply.isPositiveCompletion(reply)) {
 *        client.disconnect();
 *        System.err.println("SMTP server refused connection.");
 *        System.exit(1);
 *      }
 *
 *      // Do useful stuff here.
 *      ...
 *    } catch(IOException e) {
 *      if(client.isConnected()) {
 *        try {
 *          client.disconnect();
 *        } catch(IOException f) {
 *          // do nothing
 *        }
 *      }
 *      System.err.println("Could not connect to server.");
 *      e.printStackTrace();
 *      System.exit(1);
 *    }
 * 
*

* Immediately after connecting is the only real time you need to check the * reply code (because connect is of type void). The convention for all the * SMTP command methods in SMTPClient is such that they either return a * boolean value or some other value. * The boolean methods return true on a successful completion reply from * the SMTP server and false on a reply resulting in an error condition or * failure. The methods returning a value other than boolean return a value * containing the higher level data produced by the SMTP command, or null if a * reply resulted in an error condition or failure. If you want to access * the exact SMTP reply code causing a success or failure, you must call * {@link org.apache.commons.net.smtp.SMTP#getReplyCode getReplyCode } after * a success or failure. *

* You should keep in mind that the SMTP server may choose to prematurely * close a connection for various reasons. The SMTPClient class will detect a * premature SMTP server connection closing when it receives a * {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE } * response to a command. * When that occurs, the method encountering that reply will throw * an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException} * . * SMTPConectionClosedException * is a subclass of IOException and therefore need not be * caught separately, but if you are going to catch it separately, its * catch block must appear before the more general IOException * catch block. When you encounter an * {@link org.apache.commons.net.smtp.SMTPConnectionClosedException} * , you must disconnect the connection with * {@link #disconnect disconnect() } to properly clean up the * system resources used by SMTPClient. Before disconnecting, you may check * the last reply code and text with * {@link org.apache.commons.net.smtp.SMTP#getReplyCode getReplyCode }, * {@link org.apache.commons.net.smtp.SMTP#getReplyString getReplyString }, * and * {@link org.apache.commons.net.smtp.SMTP#getReplyStrings getReplyStrings}. *

* Rather than list it separately for each method, we mention here that * every method communicating with the server and throwing an IOException * can also throw a * {@link org.apache.commons.net.MalformedServerReplyException} * , which is a subclass * of IOException. A MalformedServerReplyException will be thrown when * the reply received from the server deviates enough from the protocol * specification that it cannot be interpreted in a useful manner despite * attempts to be as lenient as possible. * * @see SMTP * @see SimpleSMTPHeader * @see RelayPath * @see SMTPConnectionClosedException * @see org.apache.commons.net.MalformedServerReplyException */ public class SMTPClient extends SMTP { /** * Default SMTPClient constructor. Creates a new SMTPClient instance. */ public SMTPClient() { } /** * Overloaded constructor that takes an encoding specification * @param encoding The encoding to use * @since 2.0 */ public SMTPClient(final String encoding) { super(encoding); } /** * At least one SMTPClient method ({@link #sendMessageData sendMessageData }) * does not complete the entire sequence of SMTP commands to complete a * transaction. These types of commands require some action by the * programmer after the reception of a positive intermediate command. * After the programmer's code completes its actions, it must call this * method to receive the completion reply from the server and verify the * success of the entire transaction. *

* For example, *

     * writer = client.sendMessageData();
     * if(writer == null) // failure
     *   return false;
     * header =
     *  new SimpleSMTPHeader("[email protected]", "[email protected]", "Re: Foo");
     * writer.write(header.toString());
     * writer.write("This is just a test");
     * writer.close();
     * if(!client.completePendingCommand()) // failure
     *   return false;
     * 
*

* @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean completePendingCommand() throws IOException { return SMTPReply.isPositiveCompletion(getReply()); } /** * Login to the SMTP server by sending the HELO command with the * given hostname as an argument. Before performing any mail commands, * you must first login. *

* @param hostname The hostname with which to greet the SMTP server. * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean login(final String hostname) throws IOException { return SMTPReply.isPositiveCompletion(helo(hostname)); } /** * Login to the SMTP server by sending the HELO command with the * client hostname as an argument. Before performing any mail commands, * you must first login. *

* @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean login() throws IOException { final String name; final InetAddress host; host = getLocalAddress(); name = host.getHostName(); if (name == null) { return false; } return SMTPReply.isPositiveCompletion(helo(name)); } /** * Set the sender of a message using the SMTP MAIL command, specifying * a reverse relay path. The sender must be set first before any * recipients may be specified, otherwise the mail server will reject * your commands. *

* @param path The reverse relay path pointing back to the sender. * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean setSender(final RelayPath path) throws IOException { return SMTPReply.isPositiveCompletion(mail(path.toString())); } /** * Set the sender of a message using the SMTP MAIL command, specifying * the sender's email address. The sender must be set first before any * recipients may be specified, otherwise the mail server will reject * your commands. *

* @param address The sender's email address. * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean setSender(final String address) throws IOException { return SMTPReply.isPositiveCompletion(mail("<" + address + ">")); } /** * Add a recipient for a message using the SMTP RCPT command, specifying * a forward relay path. The sender must be set first before any * recipients may be specified, otherwise the mail server will reject * your commands. *

* @param path The forward relay path pointing to the recipient. * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean addRecipient(final RelayPath path) throws IOException { return SMTPReply.isPositiveCompletion(rcpt(path.toString())); } /** * Add a recipient for a message using the SMTP RCPT command, the * recipient's email address. The sender must be set first before any * recipients may be specified, otherwise the mail server will reject * your commands. *

* @param address The recipient's email address. * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean addRecipient(final String address) throws IOException { return SMTPReply.isPositiveCompletion(rcpt("<" + address + ">")); } /** * Send the SMTP DATA command in preparation to send an email message. * This method returns a DotTerminatedMessageWriter instance to which * the message can be written. Null is returned if the DATA command * fails. *

* You must not issue any commands to the SMTP server (i.e., call any * (other methods) until you finish writing to the returned Writer * instance and close it. The SMTP protocol uses the same stream for * issuing commands as it does for returning results. Therefore the * returned Writer actually writes directly to the SMTP connection. * After you close the writer, you can execute new commands. If you * do not follow these requirements your program will not work properly. *

* You can use the provided * {@link org.apache.commons.net.smtp.SimpleSMTPHeader} * class to construct a bare minimum header. * To construct more complicated headers you should * refer to RFC 5322. When the Java Mail API is finalized, you will be * able to use it to compose fully compliant Internet text messages. * The DotTerminatedMessageWriter takes care of doubling line-leading * dots and ending the message with a single dot upon closing, so all * you have to worry about is writing the header and the message. *

* Upon closing the returned Writer, you need to call * {@link #completePendingCommand completePendingCommand() } * to finalize the transaction and verify its success or failure from * the server reply. *

* @return A DotTerminatedMessageWriter to which the message (including * header) can be written. Returns null if the command fails. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. * @see #sendShortMessageData(String) */ public Writer sendMessageData() throws IOException { if (!SMTPReply.isPositiveIntermediate(data())) { return null; } return new DotTerminatedMessageWriter(writer); } /** * A convenience method for sending short messages. This method fetches * the Writer returned by {@link #sendMessageData sendMessageData() } * and writes the specified String to it. After writing the message, * this method calls {@link #completePendingCommand completePendingCommand() } * to finalize the transaction and returns * its success or failure. *

* @param message The short email message to send. * This must include the headers and the body, but not the trailing "." * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean sendShortMessageData(final String message) throws IOException { try (final Writer writer = sendMessageData()) { if (writer == null) { return false; } writer.write(message); } return completePendingCommand(); } /** * A convenience method for a sending short email without having to * explicitly set the sender and recipient(s). This method * sets the sender and recipient using * {@link #setSender setSender } and * {@link #addRecipient addRecipient }, and then sends the * message using {@link #sendShortMessageData sendShortMessageData }. *

* @param sender The email address of the sender. * @param recipient The email address of the recipient. * @param message The short email message to send. * This must include the headers and the body, but not the trailing "." * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean sendSimpleMessage(final String sender, final String recipient, final String message) throws IOException { if (!setSender(sender)) { return false; } if (!addRecipient(recipient)) { return false; } return sendShortMessageData(message); } /** * A convenience method for a sending short email without having to * explicitly set the sender and recipient(s). This method * sets the sender and recipients using * {@link #setSender(String) setSender} and * {@link #addRecipient(String) addRecipient}, and then sends the * message using {@link #sendShortMessageData(String) sendShortMessageData}. *

* Note that the method ignores failures when calling * {@link #addRecipient(String) addRecipient} so long as * at least one call succeeds. If no recipients can be successfully * added then the method will fail (and does not attempt to * send the message) *

* @param sender The email address of the sender. * @param recipients An array of recipient email addresses. * @param message The short email message to send. * This must include the headers and the body, but not the trailing "." * @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean sendSimpleMessage(final String sender, final String[] recipients, final String message) throws IOException { boolean oneSuccess = false; int count; if (!setSender(sender)) { return false; } for (count = 0; count < recipients.length; count++) { if (addRecipient(recipients[count])) { oneSuccess = true; } } if (!oneSuccess) { return false; } return sendShortMessageData(message); } /** * Logout of the SMTP server by sending the QUIT command. *

* @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean logout() throws IOException { return SMTPReply.isPositiveCompletion(quit()); } /** * Aborts the current mail transaction, resetting all server stored * sender, recipient, and mail data, cleaing all buffers and tables. *

* @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean reset() throws IOException { return SMTPReply.isPositiveCompletion(rset()); } /** * Verify that a username or email address is valid, i.e., that mail * can be delivered to that mailbox on the server. *

* @param username The username or email address to validate. * @return True if the username is valid, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean verify(final String username) throws IOException { final int result; result = vrfy(username); return result == SMTPReply.ACTION_OK || result == SMTPReply.USER_NOT_LOCAL_WILL_FORWARD; } /** * Fetches the system help information from the server and returns the * full string. *

* @return The system help string obtained from the server. null if the * information could not be obtained. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public String listHelp() throws IOException { if (SMTPReply.isPositiveCompletion(help())) { return getReplyString(); } return null; } /** * Fetches the help information for a given command from the server and * returns the full string. *

* @param command The command on which to ask for help. * @return The command help string obtained from the server. null if the * information could not be obtained. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public String listHelp(final String command) throws IOException { if (SMTPReply.isPositiveCompletion(help(command))) { return getReplyString(); } return null; } /** * Sends a NOOP command to the SMTP server. This is useful for preventing * server timeouts. *

* @return True if successfully completed, false if not. * @throws SMTPConnectionClosedException * If the SMTP server prematurely closes the connection as a result * of the client being idle or some other reason causing the server * to send SMTP reply code 421. This exception may be caught either * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. */ public boolean sendNoOp() throws IOException { return SMTPReply.isPositiveCompletion(noop()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy