java邮件开发

 

                     

 

                   服务器端(请点击跳转)

 

背景介绍:

曾经邮件服务器的开发很赚钱,如丁磊就是做邮件服务发家的。

比较有意义的项目时将邮件内容发布成bbs的帖子。

办公自动化项目(OA)都要附带发送邮件的功能,如发送通知等。

许多网站项目也都需要附带发送邮件的功能,如:给新注册的用户自动发送一封包含其注册信息的欢迎E-Mail、给过生日的注册会员自动发送一封表示祝贺的E-Mail、将网站的最新活动信息通过E-Mail发送给所有的注册会员。

主要分为:发送与接收邮件、创建与解析邮件内容。

邮件服务器主要提供以下功能:

(1)接收用户投递的邮件;

(2)将用户投递进来的邮件转发给目标邮件服务器;

(3)接收其他邮件服务器转发来的邮件并把邮件存储到其管理的用户邮中;

(4)为前来读取邮件的用户提供读取服务。

邮件服务器按通讯协议可以划分为:

(1)SMTP服务器。用于替用户发送邮件和接收外面发送给本地用户的邮件。

(2)POP3/IMAP服务器。用于帮助用户读取SMTP服务器接收进来的该用户的邮件。

image

开发环境准备:

>提前在sina和sohu上开设一个免费的账号;

>获取smtp和pop3服务器的名称;

>在outlook中配置sina账户;

>使用outlook发送和接收邮件。

1. 如何获取sina的smtp和pop3服务器地址?

进入邮箱的登录页面,新浪邮箱如下:

image

点击右下角的“帮助”

image

点击左侧边栏的“免费邮箱pop3和smtp服务器”选项

image

 

页面给出了新浪的服务器地址。

其他的邮箱如Gmail的可能不太一样,不过也很好找,在此我就不说明了,可以google。

2.配置outlook(此处我尝试以自己的Gmail做例子)。

打开Outlook Express,点击“工具”、“账户”、“添加”、“邮件”、弹出对话框

SNAGHTML46365d

输入“gmail”、输入邮箱地址

SNAGHTML467fe9

输入pop3和smtp地址

SNAGHTML46c53f

填写邮箱的用户名和密码

SNAGHTML47291a

然后完成添加账户。同样可以添加多个邮箱账号。

注:因为本人用的是Gmail邮箱,还需要设置下账户的属性,点“属性”,

SNAGHTML4770f0

点“高级”

SNAGHTML47b329

将smtp设为465,pop3设为995,然后点击“确定”。

点击“工具”、“发送和接收”、“接收全部邮件”

SNAGHTML47f3fb

就完成了outlook和Gmail邮箱的关联。

  • 此处是搜狐向新浪邮箱传邮件(可以大致

  • 了解,此处只是说明outlook用smtp服务器发送

  • 邮件的原理

注:SMTP服务器的通信过程(“>>”用户向服务器发送信息,“<<”服务器向用户发送信息。)

image

查询本机ip地址:192.168.216.1;

连接gmail的smtp服务器(注意,邮件的端口为25)

image

输入“ehlo 192.168.216.1”,显示如下:

SNAGHTML199c35a

以上是如sohu这样的smtp服务器的地址解析。

输入“nslookup”、“set type=mx”、“google.com”来解析gmail的smtp服务器的地址,如下:

image

退出之后连接gmail服务器“telnet google.com.s9a2.psmtp.com”

image

ps:忘了在后面加25端口了,尴尬!!

image

输入“ehlo 192.168.1.8 ”,如下:

image

以上是如sina的smtp服务器的地址解析。

下面开始写邮件:(此处gmail邮箱写邮件失败,具体原因我下面会介绍!以下是sina服务器下的写邮件)

image

最后就可以去outlook中查看收件箱了。

如果发送出错,可以勾选下面窗口中的“我的服务器要求身份验证”一项

SNAGHTML1e0181d

sina服务器的运行原理

image

————————因为是用gmail做的实验,所以在后面写信息的时候是不畅通的,具体原因一会介绍,———————————————

———————— 但是获取smtp服务器地址的步骤是正确的。—— —— —————————————————————————————————————————————————————————————

问题:Gmail的smtp服务器写信息不畅通的原因?

问题解决:Gmail需要SSL 验证,所以我们只能用outlook这种客户端软件来连接服务器发送邮件。

问题:为什么要用 Gmail 的 SMTP 服务器?

问题解决:一般的网站都不会自己建 SMTP 服务器,毕竟有些麻烦。而且也不是随便建一个 SMTP 服务器就能得到其它邮件服务器的认可。例如:你购买的网站空间是与其它网站共享一个 IP 地址(动态 IP),这样即使你建一个 SMTP 服务器,也很容易被其它邮件服务器认为不可靠。这就好比一个没有自己办公地点的公司,与拥有大面积厂房或者写字楼的公司相比,哪个更可靠?这种动态 IP 的 SMTP 服务器很容易被认为是“垃圾邮件发送者”。例如,spamhaus.org 这个网站就很容易将你的 SMTP “私服”列入黑名单,很多邮件服务器会到这个名单上核对,如果发现来信的 IP 已列入 spamhaus 黑名单,你的邮件就会被拒收。

举例来说,与你共享 IP 的其它某个网站自己建了 SMTP 服务器,发送了恶意邮件,被接收方标记为“垃圾邮件”并提交给 spamhaus,那么这个 IP 上所有的网站都受牵连。你建的 SMTP 服务器一样被拒绝,因为 spamhaus 名单上只写 IP 。

因此,我建议使用其它免费邮件商提供的 SMTP 服务。在这么多免费邮件中,我推荐使用 Gmail 的 SMTP 服务。

Gmail 帐号不仅是一个邮件帐号,它更是“Google 帐号”。拥有了 Gmail 帐号,就能登录Google 的网站流量分析系统、Google Group、Gtalk 即时通讯工具、Google Code、Google Calendar 等等在线服务。你就相当于拥有了一个使用范围很广的 Passport 通行证。

单就邮件功能来说,Gmail 也是非常不错的。默认 6GB 空间,强大的邮件搜索功能,使得你几乎不用删除邮件。同一主题的邮件往来以会话(Thread)形式叠联显示,也是一大创举。它还提供了免费的 POP3 和 SMTP 服务,方便用户通过 Outlook Express 等邮件客户端软件收发邮件。

问题:Gmail 的 SMTP 邮件限量?

问题解决:为了防止有人利用 Gmail 的免费 SMTP 服务发送大量垃圾邮件,Gmail 规定:每个帐号通过 SMTP 每天只能发给 100 个收件人(注意:不是 100 封邮件,这个限制更严格),超过这个数量就被封号24小时;如果你登录到 Gmail 的 web 界面,则每天可以发给 500 个收件人,超过这个数量也会被封号 24 小时。

如果你的网站注册人数很多,或者论坛发帖量很大,则每天发送的激活/通知邮件很容易超过 100 封,这就违反了 Gmail 的规定,会被停用帐号 24 小时。

这样来说,Gmail 的 SMTP 不能用在大型网站。如果你的网站每天发送的激活/通知邮件不超过 100,我推荐使用 Gmail SMTP;如果超过这个数量,就需要寻找其它不限量的 SMTP,或者自己搭建一个 SMTP 了 —— 大型网站都会这么做。

问题:自己搭建 SMTP 服务器?

问题解决:搭建了一个 SMTP 服务器,用的是 Postfix for FreeBSD 程序。在测试时发现两个问题,就是下面提醒里面的,目前都已经解决。

自己搭建 SMTP 服务器的好处是:没有信件限量,或者说作为 Postmaster 你有完全的权限控制限量多少。另外,速度也很快,如果你没有开设大量帐号的话。

借助开源的 ExtMail 软件,你还可以给你的邮件服务器创建 Web 界面,这样你就得到一个名副其实的电子邮局了。如果你想给会员权限来注册免费电邮都可以。

最后提醒一下:

1)、如果你自己搭建的 SMTP 发送邮件时发现被拒收,很可能是因为被 spamhaus.org 列入黑名单,你可以到他们网站进行搜索。如果证实被误判为垃圾邮件发送源,就可以申诉,请求解除封锁。已经有热心网友撰写了《spamhaus的PBL申诉图解》 ,你可以参考一下。

2)、发往 Hotmail 的邮件会被微软服务器进行反向解析,如果解析失败就拒收。因此自己搭建 SMTP 服务器时注意必须同时做好反向解析。

3)、如果你用 Gmail 或其他要求 SSL 连接的 SMTP 服务器时,发现设置正确但是无法发出邮件,请检查一下你的网站服务器是否支持以 SSL 协议访问外部 URL —— 问问你的空间商吧。

 

当然,这里我们需要自己用java来编写smtp服务

 

器,所以以上知识点仅供建立网站时候使用。

3.什么是java mail?

JavaMail是sun公司为方便java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如smtp、pop3、impa。用javamail编程就不需要考虑底层细节了。分为message类(创建和解析邮件内容的api)、transport类(发送邮件api)、store(接收邮件的api)、session类(用于定义应用程序所需的环境信息以及收集客户端与邮件服务器建立网络连接的会话信息)。

去网上下载javamail。

4.主要照着给的pdf文档学习。

/*这是一个最简单的发送邮件客户端*/
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Demo1 {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        /*props.setProperty("mail.smtp.ssl.enable", "true");*//*如果是由ssl验证的,可以设置这个属性为true*/
        props.setProperty("mail.smtps.auth", "true");/*写信时要通过身份验证,就设置属性为true*/
        props.setProperty("mail.transport.protocol", "smtps");/*如果想用通信协议生效,就设置这个属性为true*/
        Session session = Session.getInstance(props);/*首先建立个会话*/
        session.setDebug(true);

        Message msg = new MimeMessage(session);/*第二步,建立message*/
        msg.setText("你好吗?");
        msg.setFrom(new InternetAddress("[email protected]"));

        Transport transport = session.getTransport();/*最后建立连接*/
        transport.connect("smtp.gmail.com",465, "p330316117", "py8907935");
        transport.sendMessage(msg, new Address[] { new InternetAddress(
                "[email protected]") });

        // transport.send(msg,new Address[]{new
        // InternetAddress("[email protected]")});
        transport.close();
    }

}

/*一共就3步,我们可以去api文档中查看所需要的类和它们的方法*/

 

/*
可发送给多个收件人*/
import java.io.FileInputStream;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Demo2 {

    /**
     * @param args add by zxx ,Feb 5, 2009
     */
    public static void main(String[] args) throws Exception{
        /*只是Demo1的改写*/
        Properties props = new Properties();
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.host", "smtp.gmail.com");/*服务器的地址*/
        props.setProperty("mail.smtp.ssl.enable", "true");
        Session session = Session.getInstance(props,
                new Authenticator()
                {
                    protected PasswordAuthentication getPasswordAuthentication()
                    {
                        return new PasswordAuthentication("p330316117","py8907935");
                    }
                }
        );
        session.setDebug(true);
    /*    Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("[email protected]"));//发件人
        msg.setSubject("中文主题");
        msg.setRecipients(RecipientType.TO,
                InternetAddress.parse("[email protected],[email protected]"));//发送多个收件人
        msg.setContent("<span style='color:red'>中文呵呵呵</span>", "text/html;charset=gbk");
        msg.setContent("你好", "text/html;charset=gbk");
        Transport.send(msg);*/
        Message msg = new MimeMessage(session,new FileInputStream("resouce//demo3.eml")); /*读取Demo3写的一封复杂的邮件发送出去*/
        Transport.send(msg,InternetAddress.parse("[email protected]"));
    }

}

image

 

image

image 

项目目录结构

image

/*
一封复杂的邮件*/
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Session;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

public class Demo3 {

    /**
     * @param args add by zxx ,Feb 5, 2009
     */
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        Session session = Session.getInstance(new Properties());
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("/"" + MimeUtility.encodeText("老潘") + "/" <[email protected]>"));
        msg.setSubject("你们的Java培训真的是最牛的吗?");       
        msg.setReplyTo(new Address[]{new InternetAddress("[email protected]")});
        msg.setRecipients(RecipientType.TO,InternetAddress.parse(MimeUtility.encodeText("黎活明") + " <[email protected]>," + MimeUtility.encodeText("张孝祥") + " <[email protected]>"));
        MimeMultipart msgMultipart = new MimeMultipart("mixed");
        msg.setContent(msgMultipart);

        MimeBodyPart attch1 = new MimeBodyPart();       
        MimeBodyPart attch2 = new MimeBodyPart();       
        MimeBodyPart content = new MimeBodyPart();
        msgMultipart.addBodyPart(attch1);       
        msgMultipart.addBodyPart(attch2);       
        msgMultipart.addBodyPart(content);

        DataSource ds1 = new FileDataSource(
                "resource//bookmark.txt"   
            );
        DataHandler dh1 = new DataHandler(ds1 );/*数据处理,用来包装附件文件*/
        attch1.setDataHandler(dh1);
        attch1.setFileName(
                MimeUtility.encodeText("bookmark.txt")/*附件名称*/
                );
        DataSource ds2 = new FileDataSource(
                "resource//slogo.gif"       
            );
        DataHandler dh2 = new DataHandler(ds2 );
        attch2.setDataHandler(dh2);       
        attch2.setFileName("slogo.gif");
        MimeMultipart bodyMultipart = new MimeMultipart("related");
        content.setContent(bodyMultipart);
        MimeBodyPart htmlPart = new MimeBodyPart();       
        MimeBodyPart gifPart = new MimeBodyPart();       
        bodyMultipart.addBodyPart(htmlPart);
        bodyMultipart.addBodyPart(gifPart);       

        DataSource gifds = new FileDataSource(
                "resource//logo.gif"   
            );
        DataHandler gifdh = new DataHandler(gifds);       
        gifPart.setDataHandler(gifdh);
        gifPart.setHeader("Content-Location", "http://www.itcast.cn/logo.gif");/*图片代表的位置*/
        htmlPart.setContent("这可是我自己用程序生成和发送的邮件哦!<img src='http://www.itcast.cn/logo.gif'>"
                    , "text/html;charset=gbk");
        msg.saveChanges();
        OutputStream ips = new FileOutputStream("resource//demo3.eml");
        msg.writeTo(ips);
        ips.close();
    }

}

用servlet来作为邮件客户端

这里我们做一个demo2.jar也就是用上面第二个程序来发送邮件。将它导入到新建web project项目的lib中。这里一定要注意       

Message msg = new MimeMessage(session,new FileInputStream("resouce//demo3.eml")); /*读取Demo3写的一封复杂的邮件发送出去*/

将demo3.eml的路径改成绝对路径(在jar包中指引绝对路径),如果你想指引相对路径,就要做如下操作:请访问我“jar包中访问资源”。

 

文件目录如下

image

servlet代码:

package com.JavaMailExplOnNet;

import java.io.IOException;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.JavaMailExpl.Demo2;

public class SendMailServlet extends HttpServlet {

    /**
     * The doGet method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to get.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to post.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        try {
            Demo2.main(new String[]{});
            /*以下是tomcat的jndi发送邮件的需要,在META-INF中的context.xml是它的配置文件*/
            /*Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            Session session = (Session) envCtx.lookup("mail/Dog");

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("[email protected]"));
            InternetAddress to[] = new InternetAddress[1];
            to[0] = new InternetAddress("[email protected]");
            message.setRecipients(Message.RecipientType.TO, to);
            message.setSubject("ha");
            message.setText("test");
            //Transport.send(message);
            Transport transport = session.getTransport();
            transport.connect("smtp.gmail.com", "p330316117", "py8907935");
            transport.sendMessage(message, to);
            transport.close();*/
            response.getWriter().print("ok!");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace(response.getWriter());
        }
    }

}

然后改写web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>SendMailServlet</servlet-name>
    <servlet-class>com.JavaMailExplOnNet.SendMailServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SendMailServlet</servlet-name>
    <url-pattern>/servlet/SendMailServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

将mail包放入/WEB-INF/lib目录中,然后部署到tomcat上运行,在浏览器中输入“http://localhost:8080//JavaMailExplOnNet/servlet/SendMailServlet”,得到一封邮件。

 

一般我们是将邮件交给servlet,然后让servlet发送邮件,而我们只是给它发指令,功能图如下:

image

tomcat本身也提供了对java mail的支持,请看jndi的帮助文档。(这个我不想介绍了!)

只需要写一个META-INF/context.xml:

<Context>
  <Resource name="mail/Dog" auth="Container"
            type="javax.mail.Session"
            mail.smtp.host="smtp.sina.com" mail.smtp.auth="true"
            mail.transport.protocol="smtp"
            />
</Context>

然后结合上面servlet被注释段代码就可以了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章