zoukankan      html  css  js  c++  java
  • 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()里面的字符信息是邮件源地址的前缀.

     程序运行效果:

     

    一颗平常心,踏踏实实,平静对待一切
  • 相关阅读:
    Zjnu Stadium(hdu3047带权并查集)
    cocos2d-x结合cocosbuilder,不同屏幕适配小结
    分布式爬虫系统设计、实现与实战:爬取京东、苏宁易购全网手机商品数据+MySQL、HBase存储
    Generating RSA keys in PKCS#1 format in Java--转
    nodejs安装node-rsa遇到的问题及解决
    spring-redis-data的一个坑
    node-rsa加密,java解密调试
    MySQL 四种事务隔离级别详解及对比--转
    从实际案例聊聊Java应用的GC优化--转
    动态可缓存的内容管理系统(CMS)
  • 原文地址:https://www.cnblogs.com/hanyuan/p/2665467.html
Copyright © 2011-2022 走看看