Jsp/Servlet:实现文件上传与下载

This doc shows how to upload and download files with Jsp& Servlet technology.
author: ZJ 07-3-7
Blog: [url]http://zhangjunhd.blog.51cto.com/[/url]
1 .客户端上传文件
客户端通过一个 Jsp 页面,上传文件到服务器,该 Jsp 页面必须含有 File 类表单,并且表单必须设置 enctype="multipart/form-data" 。提交表单时通过内置对象 request request.getInputStream(); 方法获得一个输入流。
在上传文件时,会有附加信息,如下所示:
-----------------------------7d 71042a 40328
Content-Disposition: form-data; name="fileforload"; filename="C:\Documents and Settings\ZJ\ 桌面 \book.txt"
Content-Type: text/plain
// 此处为文件内容
-----------------------------7d 71042a 40328
Content-Disposition: form-data; name="submit"
 
commit
-----------------------------7d 71042a 40328--
附加信息大小为 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.java Servlet )负责下载文件。
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" , "attachment;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 >

你可能感兴趣的:(jsp,servlet,下载,上传,文件)