用Java建立WEB邮件系统

 

JavaMail库可轻松恢复邮件,但你还需要用它做点什么。这是一个基于servletWEB邮件应用程序。 

上个月我们发表过用JavaMail制作简单的邮件恢复器这篇文章,但对恢复的邮件,我们没有做过多的处理。本月,我们取来那段代码,把它组合在servlet中,并向你们展示如何轻松地让那个servlet代码作为网络应用程序运行。

在你接触Tomcat或其它的web服务器之前,让我向你介绍Jetty。Jetty是一个成熟的Java HTTP服务器及servlet容器(servlet container),从开发人员的观点来看,它小巧、资料齐全、非常容易掌握,是理想的开发工具。

在安装Jetty之前,我们要创建一个servlet。Servlet是一个响应请求的简单类。HttpServlet是 Servlet的一个子类,它响应HTTP的GET、POST及其它请求。在javax.servlet和javax.servlet.http package中你可找到所有这些类。我们需要做的第一件事情是子类HttpServlet:

import javax.servlet.*;

import javax.servlet.http.*;

public class MailServlet extends HttpServlet {

在获得邮件前,我们需要前面在命令行中传递的四个值的参数,以方便我们安装MailRetriever。当Servlet开始运行,进入服务时,它的init()方法由包含服务器提供的ServletConfig实例调用。

private MailRetriever mailretriever;

public void init(ServletConfig config) throws ServletException {

super.init(config);

你必须调用超级类init()方法,否则下面的servlet管理就不能被初始化。用ServletConfig和其它的一些方法,我们就能恢复指定的InitParameters

String emailuser=config.getInitParameter("emailuser");

String emailpassword=config.getInitParameter("emailpassword");

String emailserver=config.getInitParameter("emailserver");

String emailprovider=config.getInitParameter("emailprovider

我们稍后会回来讨论如何设定这些init参数,但现在,我们先假定它们返回有效值。现在我们就可以创建MailRetriever实例

mailretriever=new MailRetriever(emailuser,emailpassword,

emailserver,emailprovider);

}

那是用于init()的。现在,当HttpServlet被一个HTTP请求调用时,一个基于HTTP方法(GET、POST、PUT或 DELETE)的doXXX方法被使用。为恢复页面,则呼叫doGet()方法。它把参数当作请求对象,通过它你可以了解浏览器要求什么,再填充一个响应 对象,并将它送回给浏览器。

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

现在,当doGet被调用时,我们可以查看请求的路径来了解它在寻找什么。在此例中,如果我们查看根目录“/”,则我们想送HTML给页面。

if(request.getPathInfo().equals("/")) {

现在我们就可以建立一个响应。要做的第一件事情是设定所返回的内容类型,此例为HTML文本:

response.setContentType("text/html;charset=UTF-8");

然后进一步将HTML文本送至:

PrintWriter out = response.getWriter();

我们已经作好准备。除了一件事情,即我们还没有得到邮件。因此我们使用在init()中创建的mailretriever并从中得到最近的信息。

mailretriever.getMail();

Renderable msg=mailretriever.getLatestMessage();

现在,我们必须处理返回零值的可能性。我们这样处理,给响应的Writer写一个简单的错误页面,发出,关闭后返回。

if(msg==null) {

out.println("Error

Error: No valid mail in mailbox");

out.close();

return;

}

最后,我们开始输出邮件页面。这没什么复杂的,只是一些基本的HTML标识。

out.println("

"+msg.getSubject()+"

");

out.println("

"+msg.getSubject()+"

");

String bodytext=msg.getBodytext();

out.println(bodytext);

但我们不能忘记附件。我们想使这些附件可通过浏览器进行访问。稍后我们讨论如何传送它们的内容。现在,你只需知道附件的内容可以参考它的文件名(因 此附件X.JPG可在/X.JPG处得到)。这里我们输出那些附件链接的HTML列表,然后完成HTML文档,关闭编写器并返回。

out.println("


");

out.println("Attachments :

    ");

    for(int i=0;i

    Attachment attachment=msg.getAttachment(i);

    out.println(

    "

  • + attachment.getFilename() + "">"

    + attachment.getFilename() + ""

    );

    }

    out.println("");

    out.close();

    return;

    } else {

    现在,实际的邮件显示出来。如果请求的路径信息不是“/”,我们假设要求的是一个附件的文件名。这次我们只得到最近的信息,不用尝试即可获得邮件。

    Renderable msg=mailretriever.getLatestMessage();

    如果得到一个非零值并且要求一个文件,我们从响应的pathinfo中提取文件名,然后我们仔细搜寻所有附件,找出那个文件名的附件。

    if(msg!=null && request.getPathInfo().startsWith("/")) {

    String image=request.getPathInfo().substring(1);

    for(int i=0;i

    Attachment attachment=msg.getAttachment(i);

    if(attachment.getFilename().equals(image)) {

    现在,我们准备建立一个响应。我们需要设定响应的内容类型。在这个简单的例子中,我们可以转到在MailMessage中解析邮件时获得的内容类型。

    response.setContentType(attachment.getContenttype

    然后我们可以得到响应的OutputStream(不是前面提到的Writer;我们不想打印过程混淆源字节流)。并且写下附件的内容,关闭字节流并返回。

    OutputStream os=response.getOutputStream();

    os.write(attachment.getContent());

    os.close();

    return;

    }

    }

    }

    }

    当然,如果你没有做到那一点,你需要产生一个错误。这样我们就发送一个页面没找到的404错误。

    response.sendError(response.SC_NOT_FOUND);

    }

    到现在为止,我们已完成servlet。记住,我们想将这个servlet用作一个网络应用程序的一部分。要做到那样,最简单的情况,我们需要一个 web.xml文件。这个文件描述一个网络应用,在哪里找到它的servlet,应该设置哪些参数与值,何时调用servlet。让我们看一看我们的 web.xml文件。首先,最基本的是设定XML类型。

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3/EN"

    "http://java.sun.com/dyd/web-app_2_3.dtd">

    现在我们定义“网络应用”(web-app)。第一个要设定的是显示名,这样网络应用就有一个易读的名称,用于登录。

    Mail Page

    接下来我们需要定义servlet。Servlet应该有一个可以参考的servlet名,以及一个指向实际servlet代码的servlet类。

    mailpage

    com.runstate.mailpage.MailServlet

    现在,记得在前面的servlet init()方法中,我们使用了一些参数。好了,现在我们来设定它们。Init-param元素包含param-mane和param-value来定义一个参数:

    emailprovider

    pop3

    用值pop3定义一个称为emailprovider的初始参数。其它三个参数也重复这一步骤,然后关闭此servlet定义。

    这就是定义servlet的过程。但现在我们需要知道服务器何时调用此servlet。我们有servlet映射元素来做到这一点。它最简单要有被调用的servlet的名称和一个URL模式,也就是这样:

    mailpage

    /*

    对任何URL请求,“/*”,我们呼叫mailpage servlet来处理它。那几乎是为网络应用包装它。

    我们将这个文件保存在webapp/mailpage/WEB-INF/web.xml中。

    现在我们需要一个main()方法,它一旦被调用,将建立一个网络服务器并让它使用那个web.xml文件。这时Jetty开始起运行。你需要下载 Jetty核心分配,并从jetty lib目录添加org.mortbay.jetty.jar和javax.servlet.jar。你还需要ext目录中的commons- logging.jar、jasper-runtime.jar和jasper-compiler.jar。将所有这样文件拷贝到例子的库(lib)目 录。尽管我们没有做任何JSP,还是需要jasper库来支持这些支持网络应用的JSP页面。在实际代码中,我们建立一个服务器

    jettyServer = new Server();

    再告诉服务器听从哪个端口或地址。这里我们使用8081端口。

    jettyServer.addListener(":8081");

    接下来我们添加一个网络应用。在服务页面的整体层次中,第一个参数是网络应用程序出现的地方;第二个参数间接指向那个web.xml文件;实际的目录可能包含静态或jsp网页;应用程序的设置保存在WEB-INF子目录中。

    jettyServer.addWebApplication("/","./webapp/mailpage/");

    一切妥当后,现在就可以运行服务器。

    jettyServer.start();

    我们运行Start.java main()方法来运行系统(如果你正在使用可下载的例子,只需运行“ant start”)。Jetty服务器将启动。要检测它是否运行,在浏览器中输入http://localhost:8081,你会看到一封电子邮件显示出来 (当然,假定你已经正确设定web.xml中的参数)。

    但是如果我们发送一个带图像的HTML电子邮件,会存在这样的问题:


你可能感兴趣的:(用Java建立WEB邮件系统)