使用fileupload组件

1. 进行文件上传时, 表单需要做的准备:

1). 请求方式为 POST: <form action="uploadServlet" method="post" ... >
2). 使用 file 的表单域: <input type="file" name="file"/>
3). 使用 multipart/form-data 的请求编码方式: <form action="uploadServlet" method="post" enctype="multipart/form-data">

<form action="uploadServlet" method="post" enctype="multipart/form-data">
      File: <input type="file" name="file"/>
            <input type="submit" value="Submit"/>
</form>

4). 关于 enctype:

     > application/x-www-form-urlencoded:表单 enctype 属性的默认值。

        这种编码方案使用有限的字符集,当使用了非字母和数字时,必须用”%HH”代替(H 代表十六进制数字)。

        对于大容量的二进制数据或包含非 ASCII 字符的文本来说,这种编码不能满足要求。

     > multipart/form-data:form 设定了enctype=“multipart/form-data”属性后,表示表单以二进制传输数据

2. 服务端:

1). 不能再使用 request.getParameter() 等方式获取请求信息. 获取不到,

     因为请求的编码方式已经改为 multipart/form-data, 以二进制的方式来提交请求信息.

2). 可以使用输入流的方式来获取. 但不建议这样做.

3). 具体使用 commons-fileupload 组件来完成文件的上传操作.

I. 搭建环境: 加入
   commons-fileupload-1.2.1.jar
   commons-io-2.0.jar

II. 基本思想:

> commons-fileupload 可以解析请求, 得到一个 FileItem 对象组成的 List
> commons-fileupload 把所有的请求信息都解析为 FileItem 对象, 无论是一个一般的文本域还是一个文件域.
> 可以调用 FileItem 的 isFormField() 方法来判断是一个 表单域 或不是表单域(则是一个文件域)
> 再来进一步获取信息

if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
...
} 

if (!item.isFormField()) {
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();

InputStream uploadedStream = item.getInputStream();
...
uploadedStream.close();
}

 

III. 如何得到 List<FileItem> 对象.

> 简单的方式

// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Parse the request
List /* FileItem */ items = upload.parseRequest(request);


> 复杂的方式: 可以为文件的上传加入一些限制条件和其他的属性

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();

//设置内存中最多可以存放的上传文件的大小, 若超出则把文件写到一个临时文件夹中. 以 byte 为单位
factory.setSizeThreshold(yourMaxMemorySize);
//设置那个临时文件夹
factory.setRepository(yourTempDirectory);

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

//设置上传文件的总的大小. 也可以设置单个文件的大小. 
upload.setSizeMax(yourMaxRequestSize);

// Parse the request
List /* FileItem */ items = upload.parseRequest(request);

 

upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--以二进制的方式提交请求信息  -->
<form action="uploadServlet"  method="post"  enctype="multipart/form-data">
        File:<input type="file" name="file"/>
        <br>
        <br>
        Desc: <input type="text" name="desc"/>
        <br>
        <br>
        <input type="submit" value="Submit"/>

</form>
</body>
</html>

 

UploadServlet.java

package com.aff.fileupload.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*
         * InputStream is = request.getInputStream();
         * 
         * Reader reader = new InputStreamReader(is); BufferedReader
         * bufferedReader = new BufferedReader(reader);
         * 
         * String str = null; while ((str = bufferedReader.readLine()) != null)
         * { System.out.println(str);
         * 
         * }
         */

        // 1.得到FileItem 的集合 items
        DiskFileItemFactory factory = new DiskFileItemFactory();

        factory.setSizeThreshold(1024 * 500);
        File tempDirectory = new File("d:\\tempDirectory");
        factory.setRepository(tempDirectory);

        ServletFileUpload upload = new ServletFileUpload(factory);

        upload.setSizeMax(1024 * 1021 * 5);

        try {
            List<FileItem> items = upload.parseRequest(request);
            // 2.遍历items: 若是一个一般的表单域,打印信息
            for (FileItem item : items) {
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    String value = item.getString();
                    System.out.println(name + ":" + value);
                }
                // 若是文件域则把文件保存到d:\\files目录下
                else {
                    String fieldName = item.getFieldName();
                    String fileName = item.getName();
                    String contentType = item.getContentType();
                    long sizeInBytes = item.getSize();

                    System.out.println(fieldName);
                    System.out.println(fileName);
                    System.out.println(contentType);
                    System.out.println(sizeInBytes);

                    InputStream is = item.getInputStream();
                    byte[] buffer = new byte[1024];
                    int len = 0;

                    fieldName = "d:\\files\\" + fieldName;
                    System.out.println(fieldName);
                    OutputStream os = new FileOutputStream(fieldName);

                    while ((len = is.read(buffer)) != -1) {
                        os.write(buffer, 0, len);
                    }
                    os.close();
                    is.close();
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }
}

目录

使用fileupload组件

 

上一篇:给博客增加图片上传功能


下一篇:time-based DB