JavaBean是一种基于Java的软件组件。JSP对付在Web 运用中集成JavaBean组件供应了完善的支持。这种支持不仅能缩短开拓韶光(可以直策应用经测试和可信任的已有组件,避免了重复开拓),也为JSP运用带来了更多的可伸缩性。
文件的上传功能在基于B/S的开拓模式中非常普遍。同其他开拓工具比较较,JSP对文件的上传支持并不是很完美,它既不象ASP那样一定须要利用组件来完成,也不像PHP那样直接供应了文件上载的支持。JSP实现文件上传的实现办法是这样的:利用ServletRequest类的getInputStream()方法得到一个客户端向做事器发出的数据流,然后处理这个数据流,从等分析、得到文件上传中通报到做事器的各个参数和数据,然后将个中的文件数据存储为一个文件或插入到数据库中。常日JSP页面中不处理文件的上传功能,而是把这些功能放到Servlet 或JavaBean中去实现。利用Servlet完成文件上传的例子在一些JSP的干系书本中都有所先容,我这里先容利用JeanBean是如何完成文件上传的。JSP中实现文件的上传可以采取两种办法即采取HTTP协议和FTP协议实现,二者在传输的事理上存在很大的差异。以下将结合源代码对它们的实现做大略先容,相信读者会从中有所收成。以下程序已经调试通过。调试的环境:window 2000 server+Apache +tomcat4.0,JavaBean调试环境:JDK1.4+Editplus。
在JSP中利用JavaBean实现基于Web的文件上传功能一样平常须要三种文件结合完成。这三种文件分别是供应界面的HTML页面文件、完成调用实现上传功能的JavaBean的JSP文件和实现JavaBean的Java的类文件。以下我将重点讲述采取HTTP协议和FTP协议实现文件上传功能的JavaBean部分。
一、 采取HTTP协议实现多个文件的上传
在过去的Html中,表单不能实现文件的上传,这多少限定了一些网页的功能。RFC1867规范(即Html中实现基于表单的文件上传)对表单作出了扩展,增加了一个表单元素〈input type=file>。通过利用这个元素,浏览器会自动天生一个输入框和一个按钮,输入框可供用户填写本地的文件名和路径名,按钮可以让浏览器打开一个文件选择框供用户选择文件。详细的表单实现如下:
<FORMMETHOD=\公众POST\公众 ACTION=\公众.jsp\"大众 ENCTYPE=\"大众multipart/form-data\公众>
<INPUT TYPE=\公众FILE\公众 NAME=\"大众FILE1\公众 SIZE=\"大众50\"大众><BR>
<INPUT TYPE=\"大众SUBMIT\"大众 VALUE=\公众Upload\"大众>
</FORM>
当选择了粘贴文件后就直接输入本地文件的绝对路径,表单的action属性值是.jsp,这意味着要求(包括上载的文件)将发送给..jsp文件。在这个过程中实际上就实现了HTTP办法的文件上载。文件从客户端到做事器的上载是由HTTP协议的通用网关界面(CGI)支持的。这种上载办法哀求浏览器和WEBServer两方面都能够支持Rfc1867。JavaBean 通过ServletRequest类的getInputStream()方法得到一个客户端向做事器发出的数据流、剖析上传的文件格式,根据剖析结果将多个文件依次输出做事器真个目标文件中。本例中的JavaBeande的功能是由testUpload类详细实现。TestUpload类的框架如下:
public class testUpload
{
public testUpload(){……}
public final void initialize(ServletConfig config) throws ServletException
{ m_application = config.getServletContext(); }
public void upload() throws testUploadException, IOException, ServletException
{………}
private void getDataSection(){………}
private void getDataHeader(){………}
public int save (String destPathName)
throws SmartUploadException, IOException, ServletException
{………}
……
}
通过initialize()方法初始化Servlet的运行环境。利用upload()方法得到输入流,并剖析上传文件的格式,并将各个上传文件的属性赋给多个File类实例处理,这些File类实例由Files类管理。File类根据各文件的属性调用它的save ()方法将多个文件依次输出做事器真个目标文件中。个中upload()方法是关键,用于剖析http1.1协议传送文件的格式。经由测试,我们得出传输流文件的格式,这对理解upload()方法很有用。例如,上传我的文档\tt.txt文件。格式如下:
//文件分隔符
-----------------------------7d226137250336
//文件信息头
Content-Disposition: form-data; name=\公众FILE1\"大众; filename=\"大众C:\Documents and Settings\Administrator.TIMBER-4O6B0ZZ0\My Documents\tt.sql\"大众
Content-Type: text/plain
//源文件内容
create table info(
content image null);
//下一个文件的分隔符
-----------------------------7d226137250336
Content-Disposition: form-data; name=\"大众FILE2\"大众; filename=\"大众\公众
Content-Type: application/octet-stream
-----------------------------7d226137250336
从以上文件我们可以看出,HTTP协议在上传多个文件时,是将文件全部放到输入流并以一定的分隔符来区分的。实际上upload()方法便是要剖析上面的文件,确定分隔符的内容、各个文件的内容格式、文件的完全路径名称、及其文件的实际数据的始末位置。这里须要解释的一点是分隔符是随机的,它是传输流文件的第一个回车符之前的所有字符。
Upload()方法的实现流程是:首先将输入流文件输出到字节数组m_binArray中,通过下面的代码实现。
m_totalBytes=1024;totalRead=0;
for(; totalRead < m_totalBytes; totalRead += readBytes)
try
{ m_request.getInputStream();
readBytes = m_request.getInputStream().read(m_binArray, totalRead, m_totalBytes - totalRead);
}catch(Exception e){ throw new SmartUploadException(\公众Unable to upload.\"大众);}
这里采取了循环中多字节读取方法,以上循环不断地读取数据直到数组填满为止。如果一个文件可以完备得到,则文件的所有字节也就可以全部得到。但是由于网络速率常日比CPU慢得多,以是程序很随意马虎在所有的数据到来之前就清空网络缓冲区。实际上,多字节读取方法在试图从暂时为空但是开放的网络缓存区读取数据时,该方法会返回0,这表示没有数据存在但网络流没有关闭。这种情形下,单字节方法将阻挡运行程序的实行,以是多字节的行为优于单字节read()方法的行为。接下来将剖析字节数组m_binArray。首先找到分隔符;利用getDataHeader()方法返回文件信息头的值,从中确定源文件的完全路径名、源文件的扩展名和源文件文件内容格式;利用getDataSection()方法返回文件的内容数据,并记录文件数据在字节数组中的起止位置。然后天生一个File类实例,并将文件的完全路径名、源文件的扩展名、源文件文件内容格式和文件的内容数据的起止位置放到File类实例的属性中。找到下一个分隔符,连续重复上述过程,直至剖析完毕。
二、采取FTP协议实现多个文件的上传
FTP协议是Internet上用来传送文件的协议,规定了Internet上文件相互传送的标准。在java中实现这一功能是借助FtpClient类完成的。详细实现过程:首先与FTP做事器建立连接;初始化文件的传输办法,包括ASCII和BINARY两种办法;将文件输出到文件输入流FileInputStream中;FileInputStream中的数据读入字节数组中;字节数组中的数据写入输出流TelnetOutputStream(利用write方法将数据写入到一个网络链接上)。这样和源文件同名的一个文件就复制到了做事器端。本例的JavaBean中通过connectServer()、upload()和closeConnect()三个方法完成文件上传过程。紧张实现如下:
public class ftpUpload
{ String filename;String filename1;FtpClient ftpClient;
public void connectServer(string server,string user,string password,string path)
{
//server:FTP做事器的IP地址;user:登录FTP做事器的用户名
//password:登录FTP做事器的用户名的口令;path:FTP做事器上的路径
try{ ftpClient=new FtpClient();
ftpClient.openServer(server);
ftpClient.login(user, password);
System.out.println(\"大众login success!\公众);
if (path.length()!=0) ftpClient.cd(path);
ftpClient.binary(); }catch (IOException ex) {System.out.println(ex);}
}
public void closeConnect()
{try{ ftpClient.closeServer();
}catch (IOException ex) {System.out.println(ex);}
}
public void upload()
{ filename1=findFileName(filename);
//从filename等分析出文件的名称,作为目标文件的名称,详细方法实现未给出
try {
TelnetOutputStream os=ftpClient.put(filename1);
java.io.File file_in=new java.io.File(filename);
FileInputStream is=new FileInputStream(file_in);
byte[] bytes=new byte[1024];
int c;
while ((c=is.read(bytes))!=-1){ os.write(bytes,0,c); }
is.close(); os.close();
} catch (IOException ex) {System.out.println(ex);}
}
}
connectServer()完成与FTP做事器建立连接的功能,利用FtpClient的openServer(string server)方法打开远程FTP做事器,然后利用FtpClient的login(user, password)方法登录做事器。登录远程FTP做事器有两种办法,一种是注册用户登录,另一种因此匿名办法登录。前者哀求用户首先注册为做事器的客户,做事器会给客户一个登录账号和密码,依据账号和密码贯串衔接到做事器上。后者哀求用户不用注册而利用分外的用户名\"大众annoymous\"大众和\公众guest\公众有限定的访问远程主机的公开文件,现在许多系统哀求用户将Email地址作为口令。出于安全的目的,大部分匿名FTP主机一样平常只许可远程用户下载文件,而不许可上传,这将依赖于FTP做事器的设置。用户可根据实际情形选择利用两种办法。登录完成后利用FtpClient的binary()方法初始化传输办法为字节办法。upload()完成文件的上传功能。创建源文件的文件输入流FileInputStream,将输入流写入到字节数组中,利用TelnetOutputStream的write方法将字节数组中的数据写入到一个网络链接上。由于TelnetOutputStream打开的是FTP做事器上的一个文件,以是数据写入到了目标文件中,这样就完成了文件上传。closeConnect()哀求与做事器断开连接。
以上只是单个文件上传的过程,如果是多个文件可以多次调用此上传过程。由以上两种办法我们可以看出采取FTP协议实现多个文件的上传比较大略,随意马虎实现。利用FTP协议上传文件一样平常是编写的客户真个程序,做事器真个安全设置会比较繁芜;而利用HTTP协议上传文件则是做事器真个运用程序,相对来说安全设置会比较大略。并且通过测试创造FTP上传办法在传输大文件时速率是HTTP上传办法的几十倍乃至几百倍,但在传输小于1M的文件时却比HTTP上传办法稍慢一些。以是说两种传输办法各有上风。