加油加油。

                    --WZY

一、发送邮件的原理

    在了解其原理之前,先要知道两个协议,SMTP和POP3

      SMTP:Simple Mail Transfer Protocol,即简单邮件传输协议,发送邮件的协议,默认端口,25

      POP3:Post Office Protocol 3,即邮局协议,接收邮件的协议,默认端口,110

    知道了这两个协议,下面来说说邮件发送和接收的原理图,分两种,相同邮件(QQ邮箱给QQ邮箱)和不同邮件(QQ邮箱给163邮箱)是不一样的。

          

       解释:    

          为了方便起见,将新浪邮箱,list@sina.com称为用户A,将搜狐邮箱,wangwu@sohu.com 称为用户B

        用户A(新浪邮箱,list@sina.com)给用户B(搜狐邮箱,wangwu@sohu.com)发送一封邮件,那么整个过程就为图中的实线部分,用户A通过OutLook(浏览器或者客户端)登录自己的邮箱帐号,编写邮件,使用Smtp协议发送给Sina的邮件服务器中的Smtp服务器(专门用来发送的服务器),然后在通过SMTP协议,传输给Sohu的邮件服务器中的Smtp服务器,然后通过Sohu的Smtp服务器将邮件发送给用户B的存储设备进行存储(每个用户都会有一个存储空间用来存储邮件的),到这里,用户A就相当于发送成功了,因为已经到达了目的地,如果B用户需要查看邮件内容,必须通过POP3服务器将从自己的存储设备中拿到,然后返回到浏览器或者客户端中显示。

        用户B给用户A发送一封邮件,那么整个过程就为图中的虚线部分,是和A给B发一样的步骤

        用户A给一个同样使用新浪邮箱的用户C发送一封邮件,那么其过程就简单的多了,先通过Smtp服务器,然后smtp服务器会将其发送到用户C的存储设备上,A发送邮件就成功了,用户C要显示自己邮箱中的邮件,那么就通过POP3服务器从自己存储设备中拿取所有邮件进行查看。

二、通过Java代码实现发送邮件

     2.1、准备jar包

        核心:mail.jar

        依赖:activation.jar, 邮件需要发送附件时使用

     2.2、使用163邮箱发送邮件

        2.2.1、首先在163邮箱中注册一个帐号。有的话就省略这一步

        2.2.2、编写java代码发送邮件,记住三大步

           2.2.2.1、获得连接(连接邮箱的服务器和登录)

                   

        代码

         //0.1 确定连接位置
Properties props = new Properties();
//获取163邮箱smtp服务器的地址,
props.setProperty("mail.host", "smtp.163.com");
//是否进行权限验证。
props.setProperty("mail.smtp.auth", "true"); //0.2确定权限(账号和密码)
Authenticator authenticator = new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
//填写自己的163邮箱的登录帐号和授权密码,授权密码的获取,在后面会进行讲解。
return new PasswordAuthentication("163邮箱帐号","授权码");
}
}; //1 获得连接
/**
* props:包含配置信息的对象,Properties类型
* 配置邮箱服务器地址、配置是否进行权限验证(帐号密码验证)等
*
* authenticator:确定权限(帐号和密码)
*
* 所以就要在上面构建这两个对象。
*/ Session session = Session.getDefaultInstance(props, authenticator);

          2.2.2.2、创建消息(1、发件人,2、收件人,3、邮件标题,4、邮件内容)  

                      

    代码

         //2 创建消息
Message message = new MimeMessage(session);
// 2.1 发件人 xxx@163.com
message.setFrom(new InternetAddress("xxx@163.com"));
/**
* 2.2 收件人
* 第一个参数:
* RecipientType.TO 代表收件人
* RecipientType.CC 抄送
* RecipientType.BCC 暗送
* 比如A要给B发邮件,但是A觉得有必要给要让C也看看其内容,就在给B发邮件时,
* 将邮件内容抄送给C,那么C也能看到其内容了,但是B也能知道A给C抄送过该封邮件
* 而如果是暗送(密送)给C的话,那么B就不知道A给C发送过该封邮件。
* 第二个参数
* 收件人的地址,或者是一个Address[],用来装抄送或者暗送人的名单。或者用来群发。可以是相同邮箱服务器的,也可以是不同的
* 这里我们发送给我们的qq邮箱
*/
message.setRecipient(RecipientType.TO, new InternetAddress("邮箱"));
// 2.3 主题(标题)
message.setSubject("邮件的标题");
// 2.4 正文
String str = "李四: <br/>" +
"您好,您在本论坛注册用户,点击下面url进行激活<br/>" +
"http://ww......<br/>" +
"如果不能点击,请复制直接激活<br/>" +
"如果不是本人,请删除邮件";
//设置编码,防止发送的内容中文乱码。
message.setContent(str, "text/html;charset=UTF-8");

          2.2.2.3、发送邮件

              

    代码

         //3发送消息
Transport.send(message);

          完整代码

 package javamail;

 import java.util.Properties;

 import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; public class Mail163Test {
public static void main(String[] args) throws Exception{
//0.1 确定连接位置
Properties props = new Properties();
//获取163邮箱smtp服务器的地址,
props.setProperty("mail.host", "smtp.163.com");
//是否进行权限验证。
props.setProperty("mail.smtp.auth", "true"); //0.2确定权限(账号和密码)
Authenticator authenticator = new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
//填写自己的163邮箱的登录帐号和授权密码,授权密码的获取,在后面会进行讲解。
return new PasswordAuthentication("163邮箱的帐号","授权码");
}
}; //1 获得连接
/**
* props:包含配置信息的对象,Properties类型
* 配置邮箱服务器地址、配置是否进行权限验证(帐号密码验证)等
*
* authenticator:确定权限(帐号和密码)
*
* 所以就要在上面构建这两个对象。
*/ Session session = Session.getDefaultInstance(props, authenticator); //2 创建消息
Message message = new MimeMessage(session);
// 2.1 发件人 xxx@163.com 我们自己的邮箱地址,就是名称
message.setFrom(new InternetAddress("xxx@163.com"));
/**
* 2.2 收件人
* 第一个参数:
* RecipientType.TO 代表收件人
* RecipientType.CC 抄送
* RecipientType.BCC 暗送
* 比如A要给B发邮件,但是A觉得有必要给要让C也看看其内容,就在给B发邮件时,
* 将邮件内容抄送给C,那么C也能看到其内容了,但是B也能知道A给C抄送过该封邮件
* 而如果是暗送(密送)给C的话,那么B就不知道A给C发送过该封邮件。
* 第二个参数
* 收件人的地址,或者是一个Address[],用来装抄送或者暗送人的名单。或者用来群发。可以是相同邮箱服务器的,也可以是不同的
* 这里我们发送给我们的qq邮箱
*/
message.setRecipient(RecipientType.TO, new InternetAddress("526745683@qq.com"));
// 2.3 主题(标题)
message.setSubject("邮件的标题");
// 2.4 正文
String str = "李四: <br/>" +
"您好,您在本论坛注册用户,点击下面url进行激活<br/>" +
"http://ww......<br/>" +
"如果不能点击,请复制直接激活<br/>" +
"如果不是本人,请删除邮件";
//设置编码,防止发送的内容中文乱码。
message.setContent(str, "text/html;charset=UTF-8"); //3发送消息
Transport.send(message);
}
}

       2.2.3、授权码的解释

         什么是授权码?这个很简单,如果你不是在163的邮箱网址中登录的,而是在一些第三方客户端中登录邮箱帐号密码,那么就必须进行授权,来获取一个授权码,使用该授权码在第三方客户端中进行登录。而该授权码就相当于我们的密码了,帐号是不变的,也就是我们说我们在java代码中想登录邮箱,那么就必须使用授权码进行登录。如果获取授权码呢?

         在网页中登录我们的163邮箱

         

          登录之后肯定显示的是首页,在首页中有一个设置,点击设置,在左面就会显示一系列的设置选项,点击客户端授权密码,就会显示如图中所示,让其设置客户端授权码,如果没开启的话,默认就是关闭的,然后在按照步骤点击开启,一步步设置,就能得到授权码。

          如果不使用授权码,那么java程序会报错,报错信息是验证失败,说明帐号密码不正确,此时就是密码不正确,因为这里密码应该写授权码

          

          

      2.2.4、成功发送邮件。

          

    2.3、使用QQ邮箱发送邮件

        2.3.1、首先在QQ邮箱中注册一个帐号。有的话就省略这一步

        2.3.2、进行三大步,创建连接、创建消息,发送消息

            步骤都是一样的,登录时也是使用授权码登录(获得授权码跟163类似,先登录,后找到设置,里面就有设置授权码的步骤),但是你会发现,写完代码后会报错,报错信息如下

            Exception in thread "main" javax.mail.AuthenticationFailedException: 530 Error: A secure connection is requiered(such as ssl). More information at http://service.mail.qq.com/cgi-bin/help?id=28

            AuthenticationFailedException出现这个权限验证失败异常,看异常信息,说一个安全的连接要像ssl这样被要求,更多的信息访问这个网址:http://service.mail.qq.com/cgi-bin/help?id=28

            访问后,发现只有一个跟SSL相关的问题

            

          点击进去,会发现是关于第三方客户端设置SSL加密的流程图,但是我们可以知道我们出错的原因是QQ邮箱发送或者接收邮件进行SSL加密。所以我就百度了一下,只需要加这四行代码就搞定了

          

      代码

         //QQ邮箱的SSL加密。
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);

          mail.jar中其实已经封装了SSL加密的算法,只需要拿出来用即可。

      完整代码

 package javamail;

 import java.security.GeneralSecurityException;
import java.util.Properties; import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import com.sun.mail.util.MailSSLSocketFactory; public class QQMailTest { public static void main(String[] args) throws AddressException, MessagingException, GeneralSecurityException { //0.5,props和authenticator参数
Properties props = new Properties();
props.setProperty("mail.host", "smtp.qq.com");
props.setProperty("mail.smtp.auth", "true"); //QQ邮箱的SSL加密。
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf); //authenticator参数,登录自己的邮箱帐号密码,
Authenticator authenticator = new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
/**
* 注意,QQ邮箱的规则是如果不是由腾讯的网页或者客户端打开登录的话,在其他任何地方
*登录邮箱,密码必须使用授权码,授权码下面会讲解,vlyvawibbsribgee
*xxxxxxx:自己的QQ邮箱登录帐号,也就是qq号
*yyyyyyy:密码,使用授权码登录,而不能使用原始的QQ密码
*/
return new PasswordAuthentication("qq邮箱帐号","授权码");
}
};
//1、连接
/**
* props
* 连接配置信息,邮件服务器的地址,是否进行权限验证
* authenticator
* 权限验证,也就是帐号密码验证
* 所以需要先配置这两个参数
*/
Session session = Session.getDefaultInstance(props, authenticator); //2、发送的内容对象Mesage
Message message = new MimeMessage(session);
//2.1、发件人是谁
message.setFrom(new InternetAddress("526745683@qq.com"));
// 2.2 , to:收件人 ; cc:抄送 ; bcc :暗送.
/**
* 收件人是谁?
* 第一个参数:
* RecipientType.TO 代表收件人
* RecipientType.CC 抄送
* RecipientType.BCC 暗送
* 比如A要给B发邮件,但是A觉得有必要给要让C也看看其内容,就在给B发邮件时,
* 将邮件内容抄送给C,那么C也能看到其内容了,但是B也能知道A给C抄送过该封邮件
* 而如果是暗送(密送)给C的话,那么B就不知道A给C发送过该封邮件。
* 第二个参数
* 收件人的地址,或者是一个Address[],用来装抄送或者暗送人的名单。或者用来群发。
*/
message.setRecipient(RecipientType.TO, new InternetAddress("收件人的邮箱地址 xxx@qq.com"));
// 2.3 主题(标题)
message.setSubject("hello");
// 2.4 正文
String str = "苦水润喉: <br/>" +
"hah<br/>";
message.setContent(str, "text/html;charset=UTF-8");
//3、发送
Transport.send(message);
} }

    2.4、总结

        上面使用QQ邮箱和163邮箱发送邮件, 其他的一些邮箱服务器,应该也类似,就算有也是一些细微的区别,就好比上面QQ邮箱需要使用SSL加密,而163不需要一样,遇到错误可以百度自己解决一下。然后必须注明一点,上面的发送邮件的前提是,必须要联网,如果不能联网,那就不能够成功发送邮件,并且会报异常,一看这图,就应该明白为什么需要连网,因为不连网,我们连服务器地址都解析不出,就更不能让邮件传送了。

           

        就怕有些人不能连网,那么就不能判断自己编写的代码是否正确,也不能体验到这种能够自己发送邮件的的感觉了。所以下面就介绍在本机上安装邮箱服务器和客户端,那么就不用连网就能够收发邮件了。

三、安装邮箱服务器和客户端

    3.1、邮箱服务器和客户端的类型

       邮箱服务器:eyoumailserverstup.exe  下载地址可以百度一下,CSDN论坛上也有该资源

       客户端:Foxmail_7.0.exe  跟上面同理

              

    3.2、安装邮箱服务器

             安装完后会出现一个

                      

            这个不用管它,不影响使用,安装后的样子

                    

            1、将Admin删除,并且点击设置,设置我们自定义的域名

                    

            2、点击新帐号,创建两个帐号,一个wuhao、一个zhangsan

                    

                    

                    

            3、上面的操作什么意思呢?就相当于我自己创建了一个邮箱服务器,并且在该服务器上注册了两个用户,好比两个人在163邮箱中注册两个帐号。

            4、测试,wuhao给zhangsan发邮件

                    代码根据163的那套,不用使用ssl加密,也不用使用授权码,直接使用我们的登录密码

                    邮箱服务器地址:127.0.0.1  就是本机地址

                    帐号密码:wuhao  123

                    发件人地址:wuhao@wh.cn    wh.cn使我们在服务器中设置的域名

                    收件人地址:zhangsan@wh.cn  

                    关键参数在上面已经说完了,结果如何呢?在服务器中zhangsan这里确实收到了一封邮件,并且看下面注释也能知道,确实是wuhao发送给zhangsan的邮件。

                  

            5、因为这是服务器,是不可以看到邮件内容的,就像我们一开始说的原理图,要想看到邮件内容,则需要安装客户端,通过pop3协议来查看。

     3.3、安装第三方邮箱客户端   

          Foxmail7.0

         3.3.1、安装后,设置邮箱地址,我们需要查看获取zhangsan的邮件,所以填写zhangsan@wh.cn,因为这个服务器是我们自己开的,所以并没有提示。  

                      

        3.3.2、设置帐号密码,和邮箱类型,邮箱类型选择POP3,用来接收邮件协议的

               

        3.3.3、其中接收和发送邮件服务器,都应该写本机地址127.0.0.1,因为我们本机就是一个邮箱服务器,而如果是别的邮箱服务器的话,那就不一样了,比如sohu邮箱服务器,比如qq邮箱服务器,163邮箱服务器类似这种就应该使用pop.163.com,smtp.163.com来获取服务器地址。并且这里注意到没有,有一个使用ssl来接连服务器的选项,记得我们使用qq邮箱时遇到的问题吗,对,如果你绑定的是你的QQ邮箱,那么这里就需要将次选项进行勾选。

              

        3.3.4、设置完成后,就显示出了zhangsan有一张新邮件

                  

            

四、总结

      用javamail发送邮件,到这里就全部讲解完了,你学会了吗?不过这种技术现在都不怎么用了,用的比较多的还是直接用手机号码进行验证,而不是用邮箱。不过学会了还是不错的,比如连续给一个人发送100封邮件。哈哈,不太好吧,总之希望这篇文章对大家有所帮助。也希望大家都能够自己手动实现该功能,自己玩一玩。

            

    

          

          

Java Web(十三) 使用javamail进行发送邮件,(使用QQ,163,新浪邮箱服务器)的更多相关文章

  1. web开发(九) 使用javamail进行发送邮件,(使用QQ,163,新浪邮箱服务器)

    在网上看见一篇不错的文章,写的详细. 以下内容引用那篇博文.转载于<http://www.cnblogs.com/whgk/p/6506027.html>,在此仅供学习参考之用. 一.发送 ...

  2. Java Web(十二) JavaMail发送邮件

    发送邮件的原理 概叙 邮件服务器: 要在 Internet 上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在 Internet 很多 提供邮件服务的厂商:sina.sohu.163 等等他们都 ...

  3. 使用JAVA实现模拟登陆并发送新浪微博(非调用新浪API)

    没有调用新浪的API,在程序中加入自己的帐号和密码就能发送微博,代码完全在后台运行,不用打开浏览器. 用了HtmlUnit这个库来模拟登录还有发送微博. 先上效果图: 这个是刚登陆上获取第一页的信息. ...

  4. java web filter 学习(2)

    本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...

  5. java web filter 之一 基础实现

    本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...

  6. 如何将Java Web项目部署到服务器上

    转自:(此处更详细)http://blog.csdn.net/gulu_gulu_jp/article/details/50994003 一.前言 前面我们已经尝过了在云服务器上部署代码的甜头了,现在 ...

  7. 深入分析Java Web技术内幕(修订版)

    阿里巴巴集团技术丛书 深入分析Java Web技术内幕(修订版)(阿里巴巴集团技术丛书.技术大牛范禹.玉伯.毕玄联合力荐!大型互联网公司开发应用实践!) 许令波 著   ISBN 978-7-121- ...

  8. java web(四)文件上传与下载

     一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...

  9. [转]轻量级 Java Web 框架架构设计

    工作闲暇之余,我想设计并开发一款轻量级 Java Web 框架,看看能否取代目前最为流行的而又越来越重的 Spring.Hibernate 等框架.请原谅在下的大胆行为与不自量力,本人不是为了重造轮子 ...

随机推荐

  1. 1. 初次尝试Core Data 应用程序(Core Data 应用开发实践指南)

    本书以实践的方式讲解 Core Data,不会过早讲一些难懂的话题.从入门知识入手,演示如何为范例程序添加Core Data 支持,后续章节再依次讨论更复杂的话题. 1.1. Core Data 是什 ...

  2. Linux CentOS 安装 httpd

    1.查看并安装服务器是否安装编译器 make gcc gcc-c++ 查看:rpm -q gcc-c++ 2.查看SELinux 和 iptables 的状态 3.在根目录新建文件夹 lamp 4.使 ...

  3. shell 命令合并文本

    之前想把代码打印出来看来着,后来合并完之后放在word里发现有2000多页,然后放弃了~anyway,这个命令还是挺有用的. 比如我有文本a001.dat, a002.dat, a003.dat .. ...

  4. Dockerfile的书写规则及指令使用方法

    Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令.Docker程序将读取Dockerfile,根据指令生成定制的ima ...

  5. LoadRunner相关架构图

    LoadRunner概览图: Lr架构图:

  6. 基于Casperjs的网页抓取技术【抓取豆瓣信息网络爬虫实战示例】

    CasperJS is a navigation scripting & testing utility for the PhantomJS (WebKit) and SlimerJS (Ge ...

  7. 作为测试人员,我是这么报BUG的

    在测试人员提需求的时候,大家经常会看到,测试员和开发一言不合就上BUG.然后开发一下就炸了,屡试不爽,招招致命. 曾经看到有个段子这么写道: 不要对程序员说,你的代码有BUG. 他的第一反应是:1.你 ...

  8. 《JAVASCRIPT高级程序设计》第二章

    把javascript应用在网页中,需要涉及web的核心语言-html:如何让javascript既能与html共存,又不影响页面的显示效果,经过长时间的讨论.试错,最终的决定是为web增加统一的脚本 ...

  9. C++ 构造函数和析构函数的调用顺序、虚析构函数的作用

    构造函数和析构函数的调用顺序 构造函数的调用顺序: 当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达最底层的目标派生类的构造函数为止. 析构函数的调用书序: ...

  10. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...