This doc shows how to upload and download files with Jsp& Servlet technology.

author: ZJ 07-3-7
1.客户端上传文件

客户端通过一个Jsp页面,上传文件到服务器,该Jsp页面必须含有File类表单,并且表单必须设置enctype="multipart/form-data"。提交表单时通过内置对象requestrequest.getInputStream();方法获得一个输入流。
在上传文件时,会有附加信息,如下所示:
-----------------------------7d71042a40328
Content-Disposition: form-data; name="fileforload"; filename="C:\Documents and Settings\ZJ\桌面\book.txt"
Content-Type: text/plain
//此处为文件内容
-----------------------------7d71042a40328
Content-Disposition: form-data; name="submit"

 

commit
-----------------------------7d71042a40328--
附加信息大小为297字节(不确定这个值,测试得到),可通过request.getContentLength()>297来判断是否上传了文件还是提交空字符串。
2.测试

fileupload.jsp负责提交文件,accept.jsp负责实现上传功能。
fileupload.jsp

<html>

<head>

  <meta http-equiv="Content-Type" content="text/html; charset=GB18030">

  <title>This page for FileUpload</title>

</head>

<body>

  <p>Choose the file for uploading:

  <form action="accept.jsp" method=post enctype="multipart/form-data">

    <input type=file name=fileforload size=30>

    <br>

    <input type=submit value=commit name=submit>

  </form>

</body>

</html>

 

accept.jsp

<html>

<head>

<%@ page language="java" import="java.io.*" %>

<meta http-equiv="Content-Type" content="text/html; charset=GB18030">

<title>This page for response</title>

</head>

<body>

    <%

    try {

       if (request.getContentLength() > 297) {

           InputStream in = request.getInputStream();

           File f = new File("d:/temp", "test.txt");

           FileOutputStream o = new FileOutputStream(f);

           byte b[] = new byte[1024];

           int n;

           while ((n = in.read(b)) != -1) {

               o.write(b, 0, n);

           }

           o.close();

           in.close();

           out.print("File upload success!");

           } else {

              out.print("No file!");

           }

       } catch (IOException e) {

           out.print("upload error.");

           e.printStackTrace();

       }

    %>

    </body>

</html>

 

服务器端得到的上传文件I like.txt,取名为test.txt

-----------------------------7d75b1540328
Content-Disposition: form-data; name="fileforload"; filename="C:\Documents and Settings\ZJ\桌面\I like.txt"
Content-Type: text/plain

 

我喜欢驾驭着代码在风驰电掣中创造完美;
我喜欢操纵着代码在随心所欲中体验生活;
我喜欢用心情代码编制我小小的与众不同;
每一段新的代码在我手中延生对我来说就象观看刹那花开的感动;
我不需要焦点.因为我就是焦点!

 

-----------------------------7d75b1540328
Content-Disposition: form-data; name="submit"

 

commit
-----------------------------7d75b1540328--
3.去除附加信息

按照HTTP协议,文件表单提交的信息中,前4行和后5行是表单本身的信息,中间部分才是上传的文件的内容。下例对上传的文件进行处理,获取文件名,并去除附加信息。
4.测试

fileupload.jsp不变,accept.jsp修改如下:
<html>

<head>

<%@ page language="java" import="java.io.*" %>

<meta http-equiv="Content-Type" content="text/html; charset=GB18030">

<title>The real file</title>

</head>

<body>

<%try{

    //use sessionid to create a temp file.

    String tempFileName=(String)session.getId();

    //create the temp file.

    File temp=new File("d:/temp",tempFileName);

    FileOutputStream o=new FileOutputStream(temp);

    if(request.getContentLength()>297){

      //write the upload content to the temp file.

      InputStream in=request.getInputStream();

      byte b[]=new byte[1024];

      int n;

      while((n=in.read(b))!=-1){

         o.write(b,0,n);

      }

      o.close();

      in.close();

      //read the temp file.

      RandomAccessFile random=new RandomAccessFile(temp,"r");

      //read Line2 to find the name of the upload file.

      int second=1;

      String secondLine=null;

      while(second<=2){

         secondLine=random.readLine();

         second++;

      }

      //get the last location of the dir char.'\\'.

      int position=secondLine.lastIndexOf('\\');

      //get the name of the upload file.

      String fileName=secondLine.substring(position+1,secondLine.length()-1);

      //relocate to the head of file.

      random.seek(0);

      //get the location of the char.'Enter' in Line4.

      long forthEndPosition=0;

      int forth=1;

      while((n=random.readByte())!=-1&&(forth<=4)){

         if(n=='\n'){

             forthEndPosition=random.getFilePointer();

             forth++;

         }

      }

      File realFile=new File("d:/temp",fileName);

      RandomAccessFile random2=new RandomAccessFile(realFile,"rw");

      //locate the end position of the content.Count backwards 6 lines.

      random.seek(random.length());

      long endPosition=random.getFilePointer();

      long mark=endPosition;

      int j=1;

      while((mark>=0)&&(j<=6)){

         mark--;

         random.seek(mark);

         n=random.readByte();

         if(n=='\n'){

             endPosition=random.getFilePointer();

             j++;

         }

      }

      //locate to the begin of content.Count for 4 lines's end position.

      random.seek(forthEndPosition);

      long startPoint=random.getFilePointer();

      //read the real content and write it to the realFile.

      while(startPoint<endPosition-1){

         n=random.readByte();

         random2.write(n);

         startPoint=random.getFilePointer();

      }

      random2.close();

      random.close();

      //delete the temp file.

      temp.delete();

      out.print("File upload success!");

    }

    else{

       out.print("No file!");

    }

}

catch(IOException e){

    out.print("upload error.");

    e.printStackTrace();

}

%>

</body>

</html>
(注:如果文件名是中文,会出现乱码。)
5.文件下载

Jsp内置对象response调用方法getOutputStream()可以获取一个指向客户的输出流,服务器将文件写入这个流,然后可下载此文件。
6.测试

    download.jsp显示下载选项,LoadFile.javaServlet)负责下载文件。
download.jsp

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=GB18030">

    <title>download page</title>

</head>

<body>

    <a href=loadFile>Download:test.zip</a>

</body>

</html>

 

LoadFile.java

package com.zj.sample;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.OutputStream;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class LoadFile extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

           throws IOException, ServletException {

       OutputStream o = response.getOutputStream();

       byte b[] = new byte[1024];

       // the file to download.

       File fileLoad = new File("d:/temp", "test.rar");

       // the dialogbox of download file.

       response.setHeader("Content-disposition", "p_w_upload;filename="

              + "test.rar");

       // set the MIME type.

       response.setContentType("application/x-tar");

       // get the file length.

       long fileLength = fileLoad.length();

       String length = String.valueOf(fileLength);

       response.setHeader("Content_Length", length);

       // download the file.

       FileInputStream in = new FileInputStream(fileLoad);

       int n = 0;

       while ((n = in.read(b)) != -1) {

           o.write(b, 0, n);

       }

    }

 

    public void doPost(HttpServletRequest request, HttpServletResponse response)  throws IOException, ServletException {

       doGet(request, response);

    }

}

 

web.xml(注册servlet
<servlet>

    <servlet-name>LoadFileServlet</servlet-name>

    <servlet-class>com.zj.sample.LoadFile</servlet-class>

</servlet>

<servlet-mapping>

    <servlet-name>LoadFileServlet</servlet-name>

    <url-pattern>/loadFile</url-pattern>

</servlet-mapping>