随笔-9  评论-168  文章-266  trackbacks-0

 

Jsp中实现文件上传与下载  

1.客户端上传文件
   
客户端通过一个Jsp页面,上传文件到服务器,该Jsp页面必须含有File类表单,并且表单必须设置enctype="multipart/form- data"。提交表单时通过内置对象request,request.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>
<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>
<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;

@SuppressWarnings("serial")
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>


                                                                                 转自--http://blog.csdn.net/lookthesea/archive/2007/05/20/1617633.aspx
posted on 2010-01-03 16:54 紫蝶∏飛揚↗ 阅读(2859) 评论(2)  编辑  收藏 所属分类: JSP

评论:
# re: [转]Jsp中实现文件上传与下载 2011-04-07 21:35 | xin_ny
我要上传图片,怎么写啊!!!  回复  更多评论
  
# re: [转]Jsp中实现文件上传与下载 2014-06-12 11:27 | 小止
我 request.getInputStream 取到有值,但是存入文件就成0字节了  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: