实验6 文件上传下载
一、实验目的

  1. 掌握通过Servlet实现文件上传下载功能;

  2. 重点掌握commons-fileupload.jar接收浏览器上传文件,实现上传功能;
    二、实验注意事项

  3. 首先文件上传表单的数据也是被封装到request对象中的。
    request.getParameter(String)方法获取指定的表单字段字符内容,但文件上传表单已经不在是字符内容,而是字节内容,所以失效。
    这时可以使用request的getInputStream()方法获取ServletInputStream对象,它是InputStream的子类,这个ServletInputStream对象对应整个表单的正文部分(从第一个分隔线开始,到最后),这说明需要的解析流中的数据。当然解析它是很麻烦的一件事情,而Apache已经帮我们提供了解析它的工具:commons-fileupload.jar。
    该组件由多个类共同组成,使用该组件实现文件上传功能,只需要了解和使用其中三个类:DiskFileUpload、FileItem、FileUploadException。
    使用fileupload组件的步骤如下:
    创建工厂类DiskFileItemFactory对象:
    DiskFileItemFactory factory = new DiskFileItemFactory()
    使用工厂创建解析器对象:
    ServletFileUpload fileUpload = new ServletFileUpload(factory)
    使用解析器来解析request对象:
    List list = fileUpload.parseRequest(request)

  4. FileItem类,它才是最终要的结果。一个FileItem对象对应一个表单项(表单字段)。一个表单中存在文件字段和普通字段,可以使用FileItem类的isFormField()方法来判断表单字段是否为普通字段,如果不是普通字段,那么就是文件字段了。
    String getName():获取文件字段的文件名称;
    String getString():获取字段的内容,如果是文件字段,那么获取的是文件内容,当然上传的文件必须是文本文件;
    String getFieldName():获取字段名称,例如:,返回的是username;
    String getContentType():获取上传的文件的类型,例如:text/plain。
    int getSize():获取上传文件的大小;
    boolean isFormField():判断当前表单字段是否为普通文本字段,如果返回false,说明是文件字段;
    InputStream getInputStream():获取上传文件对应的输入流;
    void write(File):把上传的文件保存到指定文件中。
    三、实验任务与步骤
    实验任务:利用Apache公司的commons-fileupload.jar接收浏览器上传文件,实现文件上传功能。

  5. 实验步骤
    【步骤1】
    (1)将commons-fileupload.jar、commons-io.jar、cos.jar复制到WEB-INF\lib中,在磁盘上(本例为d:盘)新建文件夹upfile,上传文件将保存在d:\upfile。
    (2)设计一个Servlet类(FileUploadServlet.java),接收浏览器上传的文件,并保存到服务器指定的文件夹中。
    (3)设计一个JSP页面(fileupload.jsp),用于用户通过浏览器选择要上传的文件。
    (4) 设计fileupload_list.jsp,用于显示文件上传结果。
    FileUploadServlet.java参考代码如下:
    package servlet;
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Iterator;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.fileupload.DiskFileUpload;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    public class FileUploadServlet extends HttpServlet {
    public FileUploadServlet() {
    super();
    }
    public void destroy() {
    super.destroy();
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType(“text/html;charset=utf-8”);
    PrintWriter out = response.getWriter();
    //设置保存上传文件的目录

     String uploadDir = "d:/upfile"; //文件上传后的保存路径
     out.println("上传文件存储目录:"+uploadDir);
     File fUploadDir = new File(uploadDir);
     if(!fUploadDir.exists()){
         if(!fUploadDir.mkdir()){
               out.println("无法创建存储目录d:/upfile!");
               return;
             }
        }
     if (!DiskFileUpload.isMultipartContent(request)){
         out.println("只能处理multipart/form-data类型的数据!");
         return;
        }
     DiskFileUpload fu = new DiskFileUpload();
     fu.setSizeMax(1024*1024*200);//最多上传200M数据
     fu.setSizeThreshold(1024*1024);//超过1M的数据采用临时文件缓存
     //fu.setRepositoryPath(...);  //设置临时文件存储位置(如不设置,则采用默认位置)
     fu.setHeaderEncoding("utf-8");//设置上传的文件字段的文件名所用的字符集编码
     List fileItems = null;//创建文件集合,用于保存浏览器表单传来的文件
     try
       {
     	fileItems = fu.parseRequest(request);
       }
       catch(FileUploadException e)
        {
     	out.println("解析数据时出现如下问题:");
     	e.printStackTrace(out);
     	return;
        }
     //下面通过迭代器逐个将集合中的文件取出,保存到服务器上
     Iterator it = fileItems.iterator(); //创建迭代器对象it
     while (it.hasNext())
     {
       FileItem fitem = (FileItem) it.next(); //由迭代器取出文件项
       if (!fitem.isFormField())  //忽略其他不属于文件域的那些表单信息
         try{
            String pathSrc = fitem.getName();
    

//文件名为空的文件项不处理
if(pathSrc.trim().equals(""))continue;
//确定最后的"“位置,以此获取不含路径的文件名
int start = pathSrc.lastIndexOf(’\’);
//获取不含路径的文件名
String fileName = pathSrc.substring(start + 1);
File pathDest = new File(uploadDir, fileName); //构建目标文件对象
fitem.write(pathDest); //将文件保存到服务器上
}
catch (Exception e)
{
out.println(“存储文件时出现如下问题:”);
e.printStackTrace(out);
return;
}
finally //总是立即删除保存表单字段内容的临时文件
{
fitem.delete();
}
}
response.sendRedirect(”./fileupload/fileupload_list.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
doGet(request,response);
}
public void init() throws ServletException {
}
}
FileUploadServlet对应web.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>



FileUploadServlet
servlet.FileUploadServlet


FileUploadServlet
/FileUploadServlet


fileupload.jsp参考代码如下:
<%@ page language=“java”%>
<%@ page contentType=“text/html;charset=utf-8”%>

fileupload_list.jsp参考代码如下:<%@ page contentType="text/html; charset=utf-8" import="java.io.*" %>已上传的文件目录列表
<% String path = "d:/upfile"; File fl = new File(path);File filelist[] = fl.listFiles();out.println("服务器上上传文件的保存路径:"+path+"

");for(int i=0; i < filelist.length; i++){ out.println((i+1)+":"+filelist[i].getName()+"  
"); //如果是图片文件,可用以下语句显示图片。 //out.println("

");}%>
【步骤2】使用下面的URL访问之。http://localhost:8080/prac04_servlet_fileupload/fileupload/fileupload.jsp将出现如图6-1所示表单界面,在图6-1所示界面中单击浏览选择需要上传的文件,单击开始上传,弹出图6-2所示界面,说明文件上传成功。

图6-1

图6-2
打开d:\upfile文件夹,查看上传文件,如图6-4所示。

图6-4

四、思考题

  1. 了解和使用其中三个类:DiskFileUpload、FileItem、FileUploadException ;
  2. 结合本案例理解文件上传过程。
    五、实验总结
    本实验实现了:
  3. JSP页面提交文件数据到Servlet;
  4. Servlet将浏览器上传的文件保存到指定文件夹;
  5. 设计JSP页面,显示文件上传结果。
10-05 10:57