java实现邮件发送

要实现邮箱的发送,需要一个已知账号和密码的邮箱,并且开通了STMP,POP3服务,常见主流邮箱邮件收取和发送pop3、stmp服务配置汇总介绍一文中详细介绍了各个邮箱开通服务的步骤.

邮件发送是利用与邮件发送服务器建立的Socket连接,通过这个连接获得输入,输出流,再利用流在程序中输入特定的命令行来实现邮件的发送。

——————————————————————————————————————————————

下面是程序步骤:

  1. 与邮件发送服务器建立器Socket连接(需要端口号和服务器名称)
  2. 用"HELO"命令注册到服务器上
  3. 用"AUTH LOGIN"命令,根据已有的邮箱账号和密码登陆到服务器
  4. 用"MAIL FROM<..>"命令设置邮件源地址信息
  5. 用"MAIL TO<..>"命令设置邮件目的地址信息
  6. 用"DATA","FROM","TO","SUBJECT"命令分别设置发件人昵称,收件人昵称,主题信息和内容,"."+回车结束内容输入
  7. 最后用"QUIT"命令退出邮件发送服务

——————————————————————————————————————————————————————

下面是程序代码:

定义一个接口,主要是上面步骤方法的声明:

SendMail.java:

package com.sunflower.yuan.sendmail;

import java.io.IOException;

/**
 * @author Caihanyuan
 * @time 2012-8-31 上午10:27:22
 */
public interface SendMail {

    /**
     * 向服务器发送命令
     * 
     * @param order
     *            向服务器发送的命令行
     * @return 返回服务器状态
     * */
    public int sendToServer(String order);

    /**
     * 解析服务器返回的应答信息
     * 
     * @return 返回服务器状态
     * */
    public int getResult();

    /** 与服务器发起会话 */
    public void regist() throws IOException;

    /** 登录到服务器 */
    public void login() throws IOException;

    /** 设置邮件源地址 */
    public void setMailFrom() throws IOException;

    /** 设置邮件目的地址 */
    public void setMailTo() throws IOException;

    /** 设置邮件内容 */
    public void setData() throws IOException;

    /** 退出邮箱服务 */
    public void quit() throws IOException;

    /** 发送邮件的主程序 */
    public boolean sendMail() throws IOException;

} 

接口的实现类。

SendMailImp.java:

package com.sunflower.yuan.sendmail;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.StringTokenizer;

import sun.misc.BASE64Encoder;

/**
 * @author Caihanyuan
 * @time 2012-8-31 上午11:05:20
 */
public class SendMailImp implements SendMail {
    public static final int SINA = 0;
    public static final int QQ = 1;
    public static final int FOXMAIL = 2;
    public static final int WANGYI163 = 3;
    public static final int WANGYI126 = 8;
    public static final int YEAH = 4;
    public static final int HOTMAIL = 5;
    public static final int YAHOO = 6;
    public static final int GMAIL = 7;

    /** 用于向服务器发起连接 */
    private Socket socket = null;
    /** 与服务器连接后的输入流 */
    private BufferedReader input = null;
    /** 与服务器连接后的输出流 */
    private BufferedWriter output = null;
    /** 发送邮件服务器名称 */
    private String server = null;
    /** 发送端口号 */
    private int port;
    /** 邮件信息 */
    private MailMessage message;

    public MailMessage getMessage() {
        return message;
    }
    
    //设置邮件的信息内容,以方法链的方式实现
    public SendMailImp setMessage(MailMessage message) {
        this.message = message;
        return this;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public BufferedReader getInput() {
        return input;
    }

    public void setInput(BufferedReader input) {
        this.input = input;
    }

    public BufferedWriter getOutput() {
        return output;
    }

    public void setOutput(BufferedWriter output) {
        this.output = output;
    }

    public String getServer() {
        return server;
    }

    public void setServer(String server) {
        this.server = server;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    /**
     * 根据邮箱类型,设置发送邮件服务器和端口号
     */
    public static SendMailImp getInstance(int sendMailType) {
        SendMailImp sendMailImp = new SendMailImp();
        switch (sendMailType) {
        case SINA:
            sendMailImp.setServer("smtp.sina.com");
            sendMailImp.setPort(25);
            break;
        case QQ:
        case FOXMAIL:
            sendMailImp.setServer("smtp.qq.com");
            sendMailImp.setPort(25);
            break;
        case WANGYI126:
            sendMailImp.setServer("smtp.126.com");
            sendMailImp.setPort(25);
            break;
        case WANGYI163:
            sendMailImp.setServer("smtp.163.com");
            sendMailImp.setPort(25);
            break;
        case YEAH:
            sendMailImp.setServer("smtp.yeah.net");
            sendMailImp.setPort(25);
            break;
        case YAHOO:
            sendMailImp.setServer("smtp.mail.yahoo.com");
            sendMailImp.setPort(465);
            break;
        case GMAIL:
            sendMailImp.setServer("smtp.gmail.com");
            sendMailImp.setPort(465);
            break;
        case HOTMAIL:
            sendMailImp.setServer("smtp.live.com");
            sendMailImp.setPort(25);
            break;
        default:
            break;
        }

        try {
            // 与发送邮件服务器建立Socket连接,并得到输入输出流
            Socket socket = new Socket(sendMailImp.getServer(), sendMailImp
                    .getPort());
            BufferedReader input = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            BufferedWriter output = new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream()));

            sendMailImp.setSocket(socket);
            sendMailImp.setInput(input);
            sendMailImp.setOutput(output);
        }
        catch (UnknownHostException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return sendMailImp;
    }

    public int sendToServer(String order) {
        try {
            this.getOutput().write(order);
            this.getOutput().newLine();
            this.getOutput().flush();

            System.out.println("已发送命令:" + order);
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return getResult();
    }

    public int getResult() {
        String line = "";
        try {
            line = this.getInput().readLine();
            System.out.println("服务器返回状态:" + line);
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        // 从服务器返回消息中取得状态码,并转换成整数返回
        StringTokenizer get = new StringTokenizer(line, " ");
        return Integer.parseInt(get.nextToken());
    }

    public void regist() throws IOException {
        int result = getResult();
        // 连接上服务器后,服务器给出220应答
        if (result != 220)
            throw new IOException("连接服务器失败");

        result = sendToServer("HELO " + this.getServer());
        // HELO命令成功后,服务器返回250应答
        if (result != 250)
            throw new IOException("注册邮件服务器失败");
    }

    public void login() throws IOException {
        BASE64Encoder encode = new BASE64Encoder();

        int result = sendToServer("AUTH LOGIN");
        // 登陆服务成功,服务器返回334应答
        if (result != 334)
            throw new IOException("登陆服务失败");

        // 对邮箱用户名进行验证
        result = sendToServer(encode.encode(this.message.getUser().getBytes()));
        if (result != 334)
            throw new IOException("用户名错误");

        // 对邮箱密码进行验证
        result = sendToServer(encode.encode(message.getPassword().getBytes()));
        if (result != 235)
            throw new IOException("用户验证错误");
    }

    public void setMailFrom() throws IOException {
        int result = sendToServer("MAIL FROM:<" + this.getMessage().getFrom()
                + ">");
        if (result != 250)
            throw new IOException("邮件源地址错误");
    }

    public void setMailTo() throws IOException {
        int result = sendToServer("RCPT TO:<" + this.getMessage().getTo() + ">");
        if (result != 250)
            throw new IOException("邮件目的地址错误");
    }

    public void setData() throws IOException {
        int result = sendToServer("DATA");
        // 输入date回车后,若收到354应答后,继续输入邮件内容
        if (result != 354)
            throw new IOException("不能发送数据");

        this.getOutput().write("FROM:" + this.getMessage().getDatafrom());
        this.getOutput().newLine();
        this.getOutput().write("TO:" + this.getMessage().getDatato());
        this.getOutput().newLine();
        this.getOutput().write("SUBJECT:" + this.getMessage().getSubject());
        this.getOutput().newLine();
        this.getOutput().newLine();
        this.getOutput().write(this.getMessage().getContent());
        this.getOutput().newLine();

        // 句点加回车结束邮件内容输入
        result = sendToServer(".");
        if (result != 250)
            throw new IOException("发送数据错误");
    }

    public void quit() throws IOException {
        int result = sendToServer("QUIT");
        if (result != 221)
            throw new IOException("未能正确退出");

        this.getInput().close();
        this.getOutput().close();
    }

    public boolean sendMail() {
        boolean success = true;
        try {
            // 注册到发送邮件服务器
            regist();
            // 登陆到服务器
            login();
            // 设置邮件源地址
            setMailFrom();
            // 设置邮件目的地址
            setMailTo();
            // 设置邮件体
            setData();
            // 退出邮件
            quit();
        }
        catch (Exception e) {
            e.printStackTrace();
            success = false;
        }
        return success;
    }
}

邮件信息的实体类:

 MailMessage.java:

package com.sunflower.yuan.sendmail;

/**
 * @author Caihanyuan
 * @time 2012-8-30 下午11:10:27
 */
public class MailMessage {
    // 发件人
    private String from;
    // 收件人
    private String to;
    // 发件人,在邮件中显示
    private String datafrom;
    // 收件人,在邮件中显示
    private String datato;
    // 主题
    private String subject;
    // 内容
    private String content;
    // 日期
    private String date;
    // 发送邮箱用户名,邮箱名的前缀
    private String user;
    // 发送邮箱密码
    private String password;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getDatafrom() {
        return datafrom;
    }

    public void setDatafrom(String datafrom) {
        this.datafrom = datafrom;
    }

    public String getDatato() {
        return datato;
    }

    public void setDatato(String datato) {
        this.datato = datato;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

测试类

 Test.java:

package com.sunflower.yuan.test;

import java.io.IOException;

import com.sunflower.yuan.sendmail.MailMessage;
import com.sunflower.yuan.sendmail.SendMail;
import com.sunflower.yuan.sendmail.SendMailImp;

/**
 * @author Caihanyuan
 * @time 2012-8-31 下午02:45:23
 */
public class Test {
    public static void main(String[] args) {
        MailMessage message = new MailMessage();
        message.setFrom("caih****@163.com");
        message.setTo("57*****@qq.com");
        message.setSubject("这个是一个邮件发送测试");
        message.setUser("caih****");
        message.setContent("Hello,this is a mail send test\n你好这是一个邮件发送测试");
        message.setDatafrom("caih****@163.com");
        message.setDatato("57****@qq.com");
        message.setPassword("*****");
        
        SendMail send = SendMailImp.getInstance(SendMailImp.WANGYI163).setMessage(message);
        try {
            send.sendMail();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 要注意的是setUser()里面的字符信息是邮件源地址的前缀.

 程序运行效果:

 

java实现邮件发送

 

你可能感兴趣的:(java实现)