zoukankan      html  css  js  c++  java
  • 廖雪峰Java13网络编程-2Email编程-1发送email

    1.邮件发送

    1.1传统邮件发送:

    • 传统的邮件是通过邮局投递,从一个邮局到另一个邮局,最终到达用户的邮箱。

    1.2电子邮件发送:

    • 与传统邮件类似,它是从用户电脑的邮件软件(如outlook)发送到邮件服务器上,然后经过若干个邮件服务器的中转,到达对方邮件服务器上,收件方就可以用软件或浏览器来接收邮件。
    • MUA(邮件软件,Mail User Agent)——>MTA(邮件服务器,Mail Transfer Agent)——>MTA——>MDA(邮件投递代理,Mail Delivery Agent)<——MUA
    • 邮件一半到达MDA就不再动了,等收件人通过MUA或浏览器查看邮件即可
    • 从MUA发送到MTA使用的协议就是SMTP协议

    1.3 SMTP协议:发送电子邮件的协议

    • Simple Mail Transport protocol:SMTP是一个建立在TCP之上的协议。
    • 标准端口:25
    • 加密端口:465/587。如果某个会话需要被加密的话,使用加密端口465/587

    2 如何发送EMail:

    • 使用Java Mail API
    • 无需关心SMTP协议原理。

    2.1 使用Java Mail API有三个部分

    #    创建session
    Session session = Session.getInstance(props,new Authenticator(){...});
    #    创建message对象
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress("from@email.com")); //发件人
    message.setRecipient(Message.RecipientType.TO, new IntenetAddress("to@email.com")); //收件人
    message.setSubject("RE:how to use JavaEmail","UTF-8"); //邮件主题
    message.setText("blablabla...","UTF-8"); //邮件正文
    #    发送邮件
    Transport.send(message);
    

    示例代码

    package com.csj2018;
    
    import java.util.Properties;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.AddressException;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    
    public class SendQQMailUtil {
    
        public static void main(String[] args) throws AddressException,MessagingException {
            Properties properties = new Properties();
            properties.put("mail.transport.protocol", "smtp");// 连接协议
            properties.put("mail.smtp.host", "smtp.qq.com");// 主机名  网易替换为"smtp.126.com"
            properties.put("mail.smtp.port", 465);// 端口号
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
    //        properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息,同session.setDebug(true);
            // 得到回话对象
            Session session = Session.getInstance(properties);
            session.setDebug(true);
            // 获取邮件对象
            Message message = new MimeMessage(session);
            // 设置发件人邮箱地址
            message.setFrom(new InternetAddress("123456789@qq.com"));
            // 设置收件人邮箱地址,多个收件人
            message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("123456789@qq.com"),new InternetAddress("1234567890@qq.com")}); 
            //message.setRecipient(Message.RecipientType.TO, new InternetAddress("xxx@qq.com"));//一个收件人
            // 设置邮件标题
            message.setSubject("xmqtest");
            // 设置邮件内容
            message.setText("邮件内容邮件内容邮件内容xmqtest");
            // 得到邮差对象
            Transport transport = session.getTransport();
            // 连接自己的邮箱账户
            transport.connect("123456789@qq.com", "abcdefg");// 密码为QQ邮箱开通的stmp服务后得到的客户端授权码
            // 发送邮件
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        }
    }
    

    2.2 新建maven工程

    pom.xml导入依赖

    <!-- https://mvnrepository.com/artifact/javax.mail/mail -->
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>
    

    注意:不要导错依赖。详细请参考

            <!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
            <!--导入javax.mail-api,运行时会提示Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger
    -->
            <dependency>
                <groupId>javax.mail</groupId>
                <artifactId>javax.mail-api</artifactId>
                <version>1.6.2</version>
            </dependency>
    
    

    2.3 发送一封文本邮件

    package com.email;
    
    import javax.mail.*;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import java.security.MessageDigest;
    import java.util.Properties;
    
    public class SendMail {
        final String smtpHost;
        final String username;
        final String password;
        final boolean debug;
        public SendMail(String smtpHost,String username,String password){
            this.smtpHost = smtpHost;
            this.username = username;
            this.password = password;
            this.debug = true;
        }
        public static void main(String[] args) throws Exception{
            SendMail sender = new SendMail("smtp.qq.com","123456789@qq.com","abcdefg");
            Session session = sender.createSSLSession();
            Message message = createTextMessage(session,"123456789@qq.com","123456789@126.com","标题吗","Hello,这是一封Javamail测试邮件");
            Transport.send(message);
        }
        //创建一个加密的session对象
        private Session createSSLSession(){
            Properties props = new Properties();
            props.put("mail.transport.protocol","smtp");
            props.put("mail.smtp.host",this.smtpHost);//SMTP主机名
            props.put("mail.smtp.port",465);//主机端口号
            props.put("mail.smtp.auth","true");//是否需要用户认证
            //启动SSL
            props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.port","465");
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(SendMail.this.username,SendMail.this.password);
                }
            });
            session.setDebug(this.debug);//显示调试信息
            return session;
        }
        private static Message createTextMessage(Session session,String from,String to,String subject,String body) throws MessagingException {
            MimeMessage message= new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipient(Message.RecipientType.TO,new InternetAddress(to));
            message.setSubject(subject,"UTF-8");
            message.setText(body,"UTF-8");
            return message;
        }
    }
    

    2.4发送一个HTML格式的邮件

    package com.email;
    
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    
    public class SendMailWithHtml {
        public static void main(String[] args) throws Exception{
            SendMail sendMail = new SendMail("smtp.qq.com","123456789@qq.com","abcdefg");
            Session session = sendMail.createSSLSession();
            Message message = createHtmlMessage(session,"123456789@qq.com","123456789@126.com","这是一封html的邮件","
    " +
                    "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    " +
                    "<html xmlns="http://www.w3.org/1999/xhtml">
    " +
                    "
    " +
                    "<head>
    " +
                    "
    " +
                    "<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    " +
                    "<meta http-equiv="Cache-Control" content="no-transform" />
    " +
                    "<title>剧烈咳嗽就是肺癌?肺癌的这些症状也不可忽视 - 家庭医生在线肿瘤频道</title>
    " +
                    "<meta name="keywords" content="剧烈咳嗽,肺癌,肺癌的症状" />
    " +
                    "<meta name="description" content="肺癌,一个发病率极其高的癌症,由于目前环境污染日渐严重,导致越来越多的人肺部受到感染而出现病变,导致肺癌的出现,生活中有很多因为肺癌而丧失性命的人。也正是因为如此让很多人对于肺癌都比较重视,对于肺癌也有做相关的了解,而大多数人因为过于谨慎,在身体出现一些成风吹草动的时候就认为是肺癌,特别是在出现剧烈咳嗽的时候,其实出现剧烈咳嗽也并不完全是肺癌发生。" />
    " +
                    "<script type="text/javascript">
    " +
                    "CUSTOMER.setCus(["channel:cancer","level:page"]);
    " +
                    "</script>
    " +
                    "</head>
    " +
                    "<body>
    " +
                    "	<div class="article-titile">
    " +
                    "		<h1>剧烈咳嗽就是肺癌?肺癌的这些症状也不可忽视</h1></div>
    " +
                    "<!--头部模块开始--> 
    " +
                    "<div id="viewContent" class="viewContent"> <p style="text-indent:2em;text-align:left;">肺癌,一个发病率极其高的,由于目前环境污染日渐严重,导致越来越多的人肺部受到而出现病变,导致肺癌的出现,生活中有很多因为肺癌而丧失性命的人。也正是因为如此让很多人对于肺癌都比较重视,对于肺癌也有做相关的了解,而大多数人因为过于谨慎,在身体出现一些成风吹草动的时候就认为是肺癌,特别是在出现剧烈咳嗽的时候,其实出现剧烈咳嗽也并不完全是肺癌发生。</p>
    " +
                    "			</div>
    " +
                    "</body>
    " +
                    "</html>");
            Transport.send(message);
        }
        static Message createHtmlMessage(Session session,String from,String to,String subject,String body) throws MessagingException{
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipient(Message.RecipientType.TO,new InternetAddress(to));
            message.setSubject(subject,"UTF-8");
            message.setText(body,"UTF-8","html");
            return message;
        }
    }
    
    ### 2.5发送带附件的邮件 ```#java package com.email;

    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.mail.;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import java.io.
    ;

    public class SendMailWithAttachment {
    public static void main(String[] args) throws Exception{
    SendMail sender = new SendMail("smtp.qq.com","123456678@qq.com","abcdefghjik");
    Session session = sender.createSSLSession();
    //创建一个带附件的邮件
    Message message = createMessageWithAttachment(session,"123456678@qq.com","红米note5图片","为什么成功了","/src/main/resources/1.jpg","123456789@qq.com","987654321@qq.com","123456789@126.com");
    Transport.send(message);
    File f = new File(".");
    System.out.println(f.getCanonicalFile());
    File nf = new File(f.getCanonicalFile()+"/src/main/resources/1.jpg");
    if(nf.exists()){
    System.out.println(nf+"存在");
    }else{
    System.out.println(nf+"不存在");
    }

    }
    static Message createMessageWithAttachment(Session session, String from, String subject,String body, String filename, String... to) throws MessagingException,IOException {
        //本质上还是一个MimeMessage对象,但不能通过setText设置正文,需要使用MimeMultipart
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        for(String s:to){
            message.setRecipient(Message.RecipientType.TO,new InternetAddress(s));
        }
    
        message.setSubject(subject);
        //通过Multipart将内容分为2部分
        Multipart multipart = new MimeMultipart();
        //text
        BodyPart textpart = new MimeBodyPart();
        textpart.setContent(body,"text/html;charset=utf-8");//body表示邮件正文
        multipart.addBodyPart(textpart);
        //再次创建一个MimeBodyPart上传附件
        BodyPart imagePart = new MimeBodyPart();
        imagePart.setFileName(filename);
        DataHandler dh1 = new DataHandler(new FileDataSource(new File(".").getCanonicalPath()+filename));
        imagePart.setDataHandler(dh1);//如何获取附件的数据
        multipart.addBodyPart(imagePart);
    
        message.setContent(multipart);
        return message;
    }
    

    }

    <h1 style="color:blue">使用输入流发送附件</h1>
    <p style="color:red">确保图片在resource目录下</p>
    
    ```#java
    package com.email;
    
    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.mail.*;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import javax.mail.util.ByteArrayDataSource;
    import java.awt.*;
    import java.io.ByteArrayInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class SendMailWithAttachment {
        public static void main(String[] args) throws Exception{
            SendMail sender = new SendMail("smtp.qq.com","123456789@qq.com","abcdefghjkik");
            Session session = sender.createSSLSession();
            //创建一个输入流
            try(InputStream input = SendMailWithAttachment.class.getResourceAsStream("/1.jpg")){
                //创建一个带附件的邮件
                Message message = createMessageWithAttachment(session,"123456789@qq.com","红米note5图片","为什么成功了","1.jpg",input,"123456789@qq.com","987654321@qq.com","123456789@126.com");
                Transport.send(message);
            }
        }
        static Message createMessageWithAttachment(Session session, String from, String subject,String body, String filename,InputStream input, String... to) throws MessagingException,IOException {
            //本质上还是一个MimeMessage对象,但不能通过setText设置正文,需要使用MimeMultipart
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            for(String s:to){
                message.setRecipient(Message.RecipientType.TO,new InternetAddress(s));
            }
    
            message.setSubject(subject);
            //通过Multipart将内容分为2部分
            Multipart multipart = new MimeMultipart();
            //text
            BodyPart textpart = new MimeBodyPart();
            textpart.setContent(body,"text/html;charset=utf-8");//body表示邮件正文
            multipart.addBodyPart(textpart);
            //再次创建一个MimeBodyPart上传附件
            BodyPart imagePart = new MimeBodyPart();
            imagePart.setFileName(filename);
            imagePart.setDataHandler(new DataHandler(new ByteArrayDataSource(input,"Application/octet-stream")));
            multipart.addBodyPart(imagePart);
            message.setContent(multipart);
            return message;
        }
    }
    

    2.6如何把附件嵌入到正文中

    package com.csj2018;
    
    import javax.activation.DataHandler;
    import javax.mail.*;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import javax.mail.util.ByteArrayDataSource;
    import java.io.InputStream;
    
    public class SendMailWithInnerImage {
        public static void main(String[] args) throws Exception{
            SendMail sender = new SendMail("smtp.qq.com", "815379479@qq.com", "oovtbkpfvfzobdag");
            Session session = sender.createSSLSession();
            try(InputStream input = SendMailWithInnerImage.class.getResourceAsStream("/RedmiNote5-1.png")){
                Message message = createMessageWithInnerImage(session,"815379479@qq.com","chenshanju01@126.com","带图片测试","<h1><hello/h1><p><img src="cid:img01" ></p><p>这是一封带图片的测试邮件</p>","1.png",input);
                Transport.send(message);
            }
        }
        static Message createMessageWithInnerImage(Session session, String from, String to, String subject, String body, String filename, InputStream input) throws Exception{
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipient(Message.RecipientType.TO,new InternetAddress(to));
            message.setSubject(subject,"UTF-8");
            Multipart multipart = new MimeMultipart();
            BodyPart textpart = new MimeBodyPart();
            textpart.setContent(body,"text/html;charset=utf-8");
            multipart.addBodyPart(textpart);
    
            BodyPart imagepart = new MimeBodyPart();
            imagepart.setFileName(filename);
            imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(input,"application/x-png")));
            //对一个图片内容设置Content-ID,就可以在邮件中引用它,引用方式是<img src="cid:img01">
            imagepart.setHeader("Content-ID","<img01>");
            multipart.addBodyPart(imagepart);
            message.setContent(multipart);
            return message;
        }
    }
    

    content-type类型对应表:http://tool.oschina.net/commons/

    3.总结

    使用JavaMail API发送邮件本质上是一个MUA软件,类似outlook
    Java发送Email:

    • 用Maven引入javamail依赖
    • 确定SMTP服务器信息:域名/端口/使用明文/SSL/TLS
    • 调用相关API发送Email(无需关心底层TCP Socket连接)
    • 设置debug模式可以查看通信详细内容
  • 相关阅读:
    flex 遍历Object或者JSON对象内容的实现代码
    Flex Vector使用(转)
    Flex——Array,ArrayCollection,Vector性能比较(转)
    SQLSERVER远程备份、恢复(转)
    隐藏Jquery dialog 按钮
    GSM 短信相关AT指令(转)
    SQL Server 父子迭代查询语句,树状查询(转)
    js framework comparation
    eventEmitter
    调试 shell script 方法
  • 原文地址:https://www.cnblogs.com/csj2018/p/11186739.html
Copyright © 2011-2022 走看看