⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mailmessage.java

📁 Use the links below to download a source distribution of Ant from one of our mirrors. It is good pra
💻 JAVA
字号:
/* *  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. * *//* * The original version of this class was donated by Jason Hunter, * who wrote the class as part of the com.oreilly.servlet * package for his book "Java Servlet Programming" (O'Reilly). * See http://www.servlets.com. * */package org.apache.tools.mail;import java.io.IOException;import java.io.PrintStream;import java.io.BufferedOutputStream;import java.io.OutputStream;import java.net.Socket;import java.net.InetAddress;import java.util.Vector;import java.util.Enumeration;/** * A class to help send SMTP email. * This class is an improvement on the sun.net.smtp.SmtpClient class * found in the JDK.  This version has extra functionality, and can be used * with JVMs that did not extend from the JDK.  It's not as robust as * the JavaMail Standard Extension classes, but it's easier to use and * easier to install, and has an Open Source license. * <p> * It can be used like this: * <blockquote><pre> * String mailhost = "localhost";  // or another mail host * String from = "Mail Message Servlet &lt;MailMessage@server.com&gt;"; * String to = "to@you.com"; * String cc1 = "cc1@you.com"; * String cc2 = "cc2@you.com"; * String bcc = "bcc@you.com"; * &nbsp; * MailMessage msg = new MailMessage(mailhost); * msg.setPort(25); * msg.from(from); * msg.to(to); * msg.cc(cc1); * msg.cc(cc2); * msg.bcc(bcc); * msg.setSubject("Test subject"); * PrintStream out = msg.getPrintStream(); * &nbsp; * Enumeration enum = req.getParameterNames(); * while (enum.hasMoreElements()) { *   String name = (String)enum.nextElement(); *   String value = req.getParameter(name); *   out.println(name + " = " + value); * } * &nbsp; * msg.sendAndClose(); * </pre></blockquote> * <p> * Be sure to set the from address, then set the recepient * addresses, then set the subject and other headers, then get the * PrintStream, then write the message, and finally send and close. * The class does minimal error checking internally; it counts on the mail * host to complain if there's any malformatted input or out of order * execution. * <p> * An attachment mechanism based on RFC 1521 could be implemented on top of * this class.  In the meanwhile, JavaMail is the best solution for sending * email with attachments. * <p> * Still to do: * <ul> * <li>Figure out how to close the connection in case of error * </ul> * * @version 1.1, 2000/03/19, added angle brackets to address, helps some servers * version 1.0, 1999/12/29 */public class MailMessage {    /** default mailhost */    public static final String DEFAULT_HOST = "localhost";    /** default port for SMTP: 25 */    public static final int DEFAULT_PORT = 25;    /** host name for the mail server */    private String host;    /** host port for the mail server */    private int port = DEFAULT_PORT;    /** sender email address */    private String from;    /** list of email addresses to reply to */    private Vector replyto;    /** list of email addresses to send to */    private Vector to;    /** list of email addresses to cc to */    private Vector cc;    /** headers to send in the mail */    private Vector headersKeys;    private Vector headersValues;    private MailPrintStream out;    private SmtpResponseReader in;    private Socket socket;    private static final int OK_READY = 220;    private static final int OK_HELO = 250;    private static final int OK_FROM = 250;    private static final int OK_RCPT_1 = 250;    private static final int OK_RCPT_2 = 251;    private static final int OK_DATA = 354;    private static final int OK_DOT = 250;    private static final int OK_QUIT = 221;  /**   * Constructs a new MailMessage to send an email.   * Use localhost as the mail server with port 25.   *   * @exception IOException if there's any problem contacting the mail server   */  public MailMessage() throws IOException {    this(DEFAULT_HOST, DEFAULT_PORT);  }  /**   * Constructs a new MailMessage to send an email.   * Use the given host as the mail server with port 25.   *   * @param host the mail server to use   * @exception IOException if there's any problem contacting the mail server   */  public MailMessage(String host) throws IOException {    this(host, DEFAULT_PORT);  }  /**   * Constructs a new MailMessage to send an email.   * Use the given host and port as the mail server.   *   * @param host the mail server to use   * @param port the port to connect to   * @exception IOException if there's any problem contacting the mail server   */  public MailMessage(String host, int port) throws IOException {    this.port = port;    this.host = host;    replyto = new Vector();    to = new Vector();    cc = new Vector();    headersKeys = new Vector();    headersValues = new Vector();    connect();    sendHelo();  }    /**     * Set the port to connect to the SMTP host.     * @param port the port to use for connection.     * @see #DEFAULT_PORT     */    public void setPort(int port) {        this.port = port;    }    /**     * Sets the from address.  Also sets the "From" header.  This method should     * be called only once.     * @param from the from address     * @exception IOException if there's any problem reported by the mail server     */    public void from(String from) throws IOException {        sendFrom(from);        this.from = from;    }    /**     * Sets the replyto address     * This method may be     * called multiple times.     * @param rto the replyto address     *     */    public void replyto(String rto) {      this.replyto.addElement(rto);    }  /**   * Sets the to address.  Also sets the "To" header.  This method may be   * called multiple times.   *   * @param to the to address   * @exception IOException if there's any problem reported by the mail server   */  public void to(String to) throws IOException {    sendRcpt(to);    this.to.addElement(to);  }  /**   * Sets the cc address.  Also sets the "Cc" header.  This method may be   * called multiple times.   *   * @param cc the cc address   * @exception IOException if there's any problem reported by the mail server   */  public void cc(String cc) throws IOException {    sendRcpt(cc);    this.cc.addElement(cc);  }  /**   * Sets the bcc address.  Does NOT set any header since it's a *blind* copy.   * This method may be called multiple times.   *   * @param bcc the bcc address   * @exception IOException if there's any problem reported by the mail server   */  public void bcc(String bcc) throws IOException {    sendRcpt(bcc);    // No need to keep track of Bcc'd addresses  }  /**   * Sets the subject of the mail message.  Actually sets the "Subject"   * header.   * @param subj the subject of the mail message   */  public void setSubject(String subj) {    setHeader("Subject", subj);  }  /**   * Sets the named header to the given value.  RFC 822 provides the rules for   * what text may constitute a header name and value.   * @param name name of the header   * @param value contents of the header   */  public void setHeader(String name, String value) {    // Blindly trust the user doesn't set any invalid headers    headersKeys.add(name);    headersValues.add(value);  }  /**   * Returns a PrintStream that can be used to write the body of the message.   * A stream is used since email bodies are byte-oriented.  A writer can   * be wrapped on top if necessary for internationalization.   * This is actually done in Message.java   *   * @return a printstream containing the data and the headers of the email   * @exception IOException if there's any problem reported by the mail server   * @see org.apache.tools.ant.taskdefs.email.Message   */  public PrintStream getPrintStream() throws IOException {    setFromHeader();    setReplyToHeader();    setToHeader();    setCcHeader();    setHeader("X-Mailer", "org.apache.tools.mail.MailMessage (ant.apache.org)");    sendData();    flushHeaders();    return out;  }  // RFC 822 s4.1: "From:" header must be sent  // We rely on error checking by the MTA  void setFromHeader() {    setHeader("From", from);  }  // RFC 822 s4.1: "Reply-To:" header is optional  void setReplyToHeader() {    if (!replyto.isEmpty()) {      setHeader("Reply-To", vectorToList(replyto));    }  }  void setToHeader() {    if (!to.isEmpty()) {      setHeader("To", vectorToList(to));    }  }  void setCcHeader() {    if (!cc.isEmpty()) {      setHeader("Cc", vectorToList(cc));    }  }  String vectorToList(Vector v) {    StringBuffer buf = new StringBuffer();    Enumeration e = v.elements();    while (e.hasMoreElements()) {      buf.append(e.nextElement());      if (e.hasMoreElements()) {        buf.append(", ");      }    }    return buf.toString();  }  void flushHeaders() throws IOException {    // RFC 822 s4.1:    //   "Header fields are NOT required to occur in any particular order,    //    except that the message body MUST occur AFTER the headers"    // (the same section specifies a reccommended order, which we ignore)   for (int i = 0; i < headersKeys.size(); i++) {      String name = (String) headersKeys.elementAt(i);      String value = (String) headersValues.elementAt(i);      out.println(name + ": " + value);    }    out.println();    out.flush();  }  /**   * Sends the message and closes the connection to the server.   * The MailMessage object cannot be reused.   *   * @exception IOException if there's any problem reported by the mail server   */  public void sendAndClose() throws IOException {      try {          sendDot();          sendQuit();      } finally {          disconnect();      }  }  // Make a limited attempt to extract a sanitized email address  // Prefer text in <brackets>, ignore anything in (parentheses)  static String sanitizeAddress(String s) {    int paramDepth = 0;    int start = 0;    int end = 0;    int len = s.length();    for (int i = 0; i < len; i++) {      char c = s.charAt(i);      if (c == '(') {        paramDepth++;        if (start == 0) {          end = i;  // support "address (name)"        }      } else if (c == ')') {        paramDepth--;        if (end == 0) {          start = i + 1;  // support "(name) address"        }      } else if (paramDepth == 0 && c == '<') {        start = i + 1;      } else if (paramDepth == 0 && c == '>') {        end = i;      }    }    if (end == 0) {      end = len;    }    return s.substring(start, end);  }  // * * * * * Raw protocol methods below here * * * * *  void connect() throws IOException {    socket = new Socket(host, port);    out = new MailPrintStream(          new BufferedOutputStream(          socket.getOutputStream()));    in = new SmtpResponseReader(socket.getInputStream());    getReady();  }  void getReady() throws IOException {    String response = in.getResponse();    int[] ok = {OK_READY};    if (!isResponseOK(response, ok)) {      throw new IOException(        "Didn't get introduction from server: " + response);    }  }  void sendHelo() throws IOException {    String local = InetAddress.getLocalHost().getHostName();    int[] ok = {OK_HELO};    send("HELO " + local, ok);  }  void sendFrom(String from) throws IOException {    int[] ok = {OK_FROM};    send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok);  }  void sendRcpt(String rcpt) throws IOException {    int[] ok = {OK_RCPT_1, OK_RCPT_2};    send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok);  }  void sendData() throws IOException {    int[] ok = {OK_DATA};    send("DATA", ok);  }  void sendDot() throws IOException {    int[] ok = {OK_DOT};    send("\r\n.", ok);  // make sure dot is on new line  }    void sendQuit() throws IOException {        int[] ok = {OK_QUIT};        try {            send("QUIT", ok);        } catch (IOException e) {            throw new ErrorInQuitException(e);        }    }    void send(String msg, int[] ok) throws IOException {        out.rawPrint(msg + "\r\n");  // raw supports <CRLF>.<CRLF>        String response = in.getResponse();        if (!isResponseOK(response, ok)) {            throw new IOException("Unexpected reply to command: "                                  + msg + ": " + response);        }    }  boolean isResponseOK(String response, int[] ok) {    // Check that the response is one of the valid codes    for (int i = 0; i < ok.length; i++) {      if (response.startsWith("" + ok[i])) {        return true;      }    }    return false;  }    void disconnect() throws IOException {        if (out != null) {            out.close();        }        if (in != null) {            try {                in.close();            } catch (IOException e) {                // ignore            }        }        if (socket != null) {            try {                socket.close();            } catch (IOException e) {                // ignore            }        }    }}/** * This PrintStream subclass makes sure that <CRLF>. becomes <CRLF>.. *  per RFC 821.  It also ensures that new lines are always \r\n.*/class MailPrintStream extends PrintStream {  private int lastChar;  public MailPrintStream(OutputStream out) {    super(out, true);  // deprecated, but email is byte-oriented  }  // Mac does \n\r, but that's tough to distinguish from Windows \r\n\r\n.  // Don't tackle that problem right now.  public void write(int b) {    if (b == '\n' && lastChar != '\r') {      rawWrite('\r');  // ensure always \r\n      rawWrite(b);    } else if (b == '.' && lastChar == '\n') {      rawWrite('.');  // add extra dot      rawWrite(b);    } else {      rawWrite(b);    }    lastChar = b;  }  public void write(byte[] buf, int off, int len) {    for (int i = 0; i < len; i++) {      write(buf[off + i]);    }  }  void rawWrite(int b) {    super.write(b);  }  void rawPrint(String s) {    int len = s.length();    for (int i = 0; i < len; i++) {      rawWrite(s.charAt(i));    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -