你希望在jsp中建立一个邮件发送收取工具吗?下面将介绍的就是在jsp中建立一个邮件发送收取工具。在这篇文章中你可以了解到JavaMail API的一些要点以及如何在JSP中使用它。本文中还包括了在JSP中使用JavaMail的实例。JavaMail是JSP应用软件中相当强大的API。

阅读这篇文章需要对JSP、JavaBeans和JavaMail有一定的初步了解。当然,有关于JavaMail的知识你可以通过阅读这篇文章来获得。如果你对于以上三项一无所知,但你所使用的服务器支持JSP和JavaMail的话,你可以仅仅通过复制/粘贴来使用它们。


什么是JavaMail


JavaMail是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。


虽然JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(Java Development Kit),这就意味着你在使用前必须另外下载JavaMail文件。除此以外,你还需要有Sun的JavaBeans Activation Framework (JAF)。JavaBeans Activation Framework的运行很复杂,在这里简单的说就是JavaMail的运行必须得依赖于它的支持。在Windows 2000下使用需要指定这些文件的路径,在其它的操作系统上也类似。


接下来要讲解的是这篇指南的最难理解的部分。


这篇指南包括三部分:HTML表格、关于JavaMail、JavaMail和JSP的结合。


第一部分:HTML表格


第一部分提供了一个最基本的基于HTML的email发送收取程序的例子。第二部分则讲述JavaMail的工作原理。第三部分则介绍将JavaMail加入JSP,创建一个基本的email发送收取程序。


划分组件


JSP最重要的特性是能将整个网页划分成一些细小的组件。这里使用的组件包括:


●一个用来将email的信息发送给JSP的HTML表格;


●一个JSP页面用来处理和发送信件。


第一步,就是创建一个HTML表格用来给JSP页面发送信息。你可以将以下的HTML代码复制到你的电脑上:


用来发送email的HTML源代码


<HTML>

<BODY>

<FORM action="sendmail.jsp" method="post">

<TABLE align="center">

<TR>

<TD width="50%">

To:<BR><INPUT name="to" size="25">

</TD>

<TD width="50%">

From:<BR><INPUT name="from" size="25">

</TD>

</TR>

<TR>

<TD colspan="2">

Subject:<BR><INPUT name="subject" size="50">

</TD>

</TR>

<TR>

<TD colspan="2">

<P>Message:<BR><TEXTAREA name="text" rows=25 cols=85></TEXTAREA></P>

</TD>

</TR>

</TABLE>

<INPUT type="submit" name="cb_submit" value=" Send ">

<INPUT type="reset" name="cb_reset" value=" Clear ">

</FORM>

</BODY>

</HTML>

以上这段程序将创建一个包含email基本信息(例如:收件地址、发送地址、主题和内容)的文件。当然你可以根据你自己的需要来决定这个文件包含那些信息。


这个HTML文件的使用有两点要求:第一点是生成的文件必须发送给接下来将介绍的程序使用。在这个例子中就是sendmail.jsp,但在你使用时,必须用这个文件在系统里的URL来代替它;第二点是必须有空间来允许用户发送email。


第二部分将对JavaMail的特征进行一些分析,为在第三部分创建JSP程序作准备。所以接下来我们将学习JavaMail。


第二部分:关于JavaMail

文档的使用


下载的JavaMail API中带的文档是很有用的。你可以在JavaMail下的/docs/javadocs/index.html找到它。第二部分主要将分析邮件程序的组件。你可以通过阅读文档来获得更多这方面的信息。


组件发送邮件需要使用JavaMail,它使对邮件的操作变得简单易用。

属性对象


JavaMail需要创建一个格式为"mail.smtp.host"的文件用来发送信息。


Properties props = new Properties ();


props.put("mail.smtp.host", "smtp.jspinsider.com"); 对话对象


所有的基于JavaMail的程序都至少需要一个或全部的对话目标。


Session sendMailSession;


sendMailSession = Session.getInstance(props, null);


传输


邮件的传输只有送出或受到两种状态。JavaMail将这两种不同状态描述为传输和储存。传输将送出邮件,而储存将收取邮件。


Transport transport;


transport = sendMailSession.getTransport("smtp");


使用JavaMail能为我们节约大量的时间。JavaMail能代替所有的SMTP的工作。


注意:JavaMail并不能完全的支持所有的邮件发送收取工作。它目前仅支持IMAP、SMTP和POP3,除此以外你只有等待新的JavaMail版本或自己开发协议。


信息对象


信息对象将把你所发送的邮件真实的反映出来。


Message newMessage = new MimeMessage(sendMailSession);


这就是我们所需要的全部四个对象。下一步将是如何将对象加入到JSP中。


第三部分:JavaMail和JSP的结合


创建JSP

下面我们将开始将他们结合在一起。最重要的一点是要确认根据页面指示分类。还要记得在邮件上标注java.util.date。


<%@ page

import= " javax.mail.*, javax.mail.internet.*, javax.activation.*, java.util.*"

%>

其次,创建邮件发送的确认信息。确认信息可以是任意的,一般常用"你的邮件已经发送出去了(Your mail has been sent)。"


信息是如何创建和发送的


我们在第二部分里已经讨论过信息对象的创建。我们下面将对信息进行操作。这就和设置信息对象的属性一样简单。你可以通过下面的程序来实现这项操作。


newMessage.setFrom(new InternetAddress(request.getParameter("from")));


newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("to")));


newMessage.setSubject(request.getParameter("subject"));


newMessage.setSentDate(new Date());


newMessage.setText(request.getParameter("text"));


现在将开始发送信息。通过JavaMail来实现它非常简单。


transport.send(newMessage);


将所有的组件结合在一起


现在所有的组件都已经齐全了。现在将它们都放在JSP里面。要注意每一个错误信息,并将它反馈给用户。代码如下,你可以通过复制它们直接使用:


Sample JSP email Utility Using JavaMail

<%@ page

import=" javax.mail.*, javax.mail.internet.*, javax.activation.*,java.util.*"

%>

<html>

<head>

<TITLE>JSP meets JavaMail, what a sweet combo.</TITLE>

</HEAD>

<BODY>

<%

try{

Properties props = new Properties();

Session sendMailSession;

Store store;

Transport transport;

sendMailSession = Session.getInstance(props, null);

props.put("mail.smtp.host", "smtp.jspinsider.com");

Message newMessage = new MimeMessage(sendMailSession);

newMessage.setFrom(new InternetAddress(request.getParameter("from")));

newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("to")));

newMessage.setSubject(request.getParameter("subject"));

newMessage.setSentDate(new Date());

newMessage.setText(request.getParameter("text"));

transport = sendMailSession.getTransport("smtp");

transport.send(newMessage);

%>

<P>Your mail has been sent.</P>

<%

}

catch(MessagingException m)

{

out.println(m.toString());

}

%>

</BODY>

</HTML>

你会很快体会到JavaMail的方便之处,JSP和JavaMail将是未来的希望。



文件/图片上传
package uploadfile;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.FileOutputStream;
import java.io.*;
import java.util.Hashtable;
import java.util.*;

public class FileUploadBean {

private String savePath=null; //文件上传保存的路径
private String contentType=""; //内容类型
private String charEncode=null; //字符编码
private String boundary=""; //分界线
private String fileName=null; //本地文件名字
private Hashtable dic=new Hashtable(); //用于保存"元素名--元素值"对
private int totalSize=0; //上传文件总大小
private String path=""; //保存文件的路径
private String newFileName=""; //存入随机产生的文件名


///////////////////////////////////////////////////
//设置文件上传保存的路径
public void setSavePath(String s) {
s=path+s;
savePath=s;
System.out.println("上传路径:"+savePath);
}

///////////////////////////////////////////////////
//取文件上传保存的路径
public String getSavePath() {
return savePath;

}

////////////////////////////////////////////////////
//设置文件名字,也可以为它命名,暂时先用它原来的名字
public void setFileName(String s) {
int pos=s.indexOf("\"; filename=\"");
if (pos>0) {
s=s.substring(pos+13,s.length()-3); //去 " 和 crlf
pos=s.lastIndexOf("\\");
if (pos<0)
pos=s.lastIndexOf("/");
if (pos<0)
fileName=s;
fileName=s.substring(pos+1);
}
}

////////////////////////////////////////////////////
//取得文件名
public String getFileName() {
System.out.println("得到文件名"+newFileName);
return newFileName;

}
///////////////////////////
//以时间为种子数产生新文件名
public String getNewFileName() {
int pos=0; //.的位置
long seed=0; //随机种子数
String ext=""; //存入文件扩展名
System.out.println("upload file name:"+fileName);
pos=fileName.lastIndexOf(".");
ext=fileName.substring(pos); //得到扩展名
seed=new Date().getTime();
Random rand=new Random(seed);//以时间为种子产生随机数作为文件名
newFileName=Long.toString(Math.abs(rand.nextInt()))+ext; //生成文件名
System.out.println("new file name:"+newFileName);
return newFileName;

}
//////////////////////////////////////////////////////
//设置字符的编码方式
public void setCharEncode(HttpServletRequest req) {
charEncode=req.getCharacterEncoding();
}




/////////////////////////////////////////////////
//设置得ContentType
public void setBoundary(HttpServletRequest req) {
//传递的参数值类似"multipart/form-data; boundary=---------------------------7d21441a30013c"
//传过来的分界线比实际显示在上传数据中的要多两个"--"

boundary=req.getContentType();
//System.out.println("boundary"+boundary);
int pos=boundary.indexOf("boundary=");
//加上这两个"--"
boundary="--"+boundary.substring(pos+9);


}

////////////////////////////////////////////////////
//取得ContentType
public String getBoundary(){
//返回值类似"-----------------------------7d21441a30013c"
return boundary;
}


/////////////////////////////////////////////
//设置ContentType
public void setContentType(String s) {
int pos =s.indexOf(": ");
if (pos!=-1)
contentType=s.substring(pos+2);
}

////////////////////////////////////////////
//取得ContentType
public String getContentType() {
return contentType;
}

/////////////////////////////////////////////
//初始化
public void init(HttpServletRequest req) {
setCharEncode(req);
setBoundary(req);

}


////////////////////////////////////////////////////
//取哈希表中的数据
public String getFieldValue(String s) {
String temp="";
if(dic.containsKey(s)) //判断表中是否存在s键,不判断则返回nullpointerException
{
temp=(String)dic.get(s);
temp=temp.trim();
}else
temp="";
return temp;
}



////////////////////////////////////////////////
////用指定的编码方式生成字符串
public String newLine(byte oneLine[],int sp,int i,String charEncode)
throws java.io.UnsupportedEncodingException {
sp=0; // start position
String lineStr=null;
if (charEncode!=null) {
return lineStr=new String(oneLine,sp,i,charEncode); //用指定的编码方式生成字符串
}
else {
return lineStr=new String(oneLine,sp,i);
}
}

///////////////////////////////////////////////
//得到上传文件的大小
public int getTotalSize() {
return totalSize/1000;
}
///////////////////////////////////////
//删除指定路径的文件
public boolean delFiles(String fn) //fn为要删除的文件名,不包括路径
{
try
{
File file=new File(savePath+fn);
System.out.println(savePath+fn);
if(file.exists())
{
file.delete();
System.out.println(file.getPath()+"delete file successfully!");
return true;
}else
{
System.out.println("the file is not existed!");
return true;
}
}catch(Exception e)
{
System.out.println(e.toString());
return false;
}
}

////////////////////////////////////////////////
//文件列表
public String[] listFiles(String fp)
{
String[] lf=null;
try{
savePath=path+fp;
File file=new File(savePath);
lf=file.list(new DirFilter());
for(int i=0;i<lf.length;i++)
System.out.println(lf[i]);
}catch(Exception e){ e.printStackTrace();}
return lf;
}
/////////////////////////////////////////////////
//开始上传文件
public boolean doUpload(HttpServletRequest req)
throws java.io.IOException {

String fieldValue=""; //表单元素值
String fieldName=""; //表单元名称
int pos=-1; //临时变量,用于记录位置
int pos2=-1; //临时变量,用于记录位置
String lineStr=null; //用oneLine[]生成的每行字符串
byte oneLine[] =new byte[4096]; //用于每次读取的数据
FileOutputStream fos=null; //文件输出流
init(req); //初始化
ServletInputStream sis=req.getInputStream();
int i=sis.readLine(oneLine,0,oneLine.length); //返回实际读取的字符数,并把数据写到oneLine中
while (i!=-1) {
lineStr=newLine(oneLine,0,i,charEncode); //生成字符串
if (lineStr.indexOf(getBoundary()+"--")>=0)
break;

if (lineStr.startsWith("Content-Disposition: form-data; name=\"")) {
//分离数据,因为表单元素也一并上传,还有其它数据,对我们有用的只是
//文件的内容,表单元素及表单元素对应的值
if (lineStr.indexOf("\"; filename=\"")>=0) { //是文件输入域
//设置文件名
setFileName(lineStr);
if (!fileName.equals("")) { //如果文件名为空则跳过

//提取表单元素名称及表单元素对应的值
pos=lineStr.indexOf("name=\"");
pos2=lineStr.indexOf("\"; filename=\"");
//表单元素名字
fieldName=lineStr.substring(pos+6,pos2);
//表单元素值
fieldValue=lineStr.substring(pos2+13,lineStr.length()-3);
//加入哈希表中
dic.put(fieldName,fieldValue);
sis.readLine(oneLine,0,oneLine.length); //读取的数据类似"Content-Type: text/plain"
sis.readLine(oneLine,0,oneLine.length); //空行
//建立文件输出
fos=new FileOutputStream(new File(getSavePath(),getNewFileName()));
//开始读上传文件数据
i=sis.readLine(oneLine,0,oneLine.length);
while(i!=-1) {
totalSize=i+totalSize;
lineStr=newLine(oneLine,0,i,charEncode);
if (lineStr.indexOf(getBoundary())>=0)
break; //表明这个文件区的数据读取完毕
fos.write(oneLine,0,i);
i=sis.readLine(oneLine,0,oneLine.length);
}//end while
fos.close();
}//end if (!getFileName().equals(""))
}
else { //非文件输入域
pos=lineStr.indexOf("name=\"");
//表单元素名字
fieldName=lineStr.substring(pos+6,lineStr.length()-3);
//读空行
sis.readLine(oneLine,0,oneLine.length);
//这行含有元素值,如里元素值为空,则这行也是空行,也要读的
String temp="";
i=sis.readLine(oneLine,0,oneLine.length);
while(i!=-1)
{
temp=newLine(oneLine,0,i,charEncode);
if (temp.indexOf(getBoundary())>=0)
break;
fieldValue=fieldValue+temp;
i=sis.readLine(oneLine,0,oneLine.length);
}
//加入哈希表中
dic.put(fieldName,fieldValue);
fieldValue="";
}
}
i=sis.readLine(oneLine,0,oneLine.length);
}//end while

sis.close();

return true;
} //end doUpload


//////////////////////////
//清空Hashtable
public void clearDic() {
dic.clear();
if (dic.isEmpty()) {
System.out.println("empty");
}
else {
System.out.println("not empty");
}

}
//////////////////////////////////
//测试用的主函数
public static void main(String args[])
{
String[] fileList=null;
try{
FileUploadBean fub=new FileUploadBean();
fileList=fub.listFiles("/avatars/");
for(int i=0;i<fileList.length;i++)
System.out.println(fileList[i]);

}catch(Exception e){ e.printStackTrace();}
}

}


///////////////////////////////////
////文件目录过滤内部类
class DirFilter implements FilenameFilter {

public boolean accept(File dir, String name) { //dir为目录名,name 为包含路径的文件名

File f = new File(dir,name); //生成文件对象
if(f.isDirectory())
return false;
return true;
}
}