使用 Apache 开源上传软件包 fileupload,在fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象;FileItem 对象必须由 ServletFileUpload 类中的 parseRequest() 方法解析 HTTP 请求(即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单和上传文件;而 ServletFileUpload 对象的创建需要依赖于 FileItemFactory 工厂将获得的上传文件 FileItem 对象保存至服务器硬盘,即 DiskFileItem 对象。
upload.html 文件
- <html>
- <head> <title>Servlet 上传文件</title></head>
- <body >
- <form name="uploadForm" method="POST"
- enctype="MULTIPART/FORM-DATA"
- action="upload">
- User Name:<input type="text" name="username" size="30"/>
- Upload File1:<input type="file" name="file1" size="30"/>
- Upload File2:<input type="file" name="file2" size="30"/>
- <input type="submit" name="submit" value="上传">
- <input type="reset" name="reset" value="重置">
- </form>
- </body>
- </html>
UploadServlet.java 文件
- import javax.servlet.http.*;
- import java.io.*;
- import java.util.*;
- import org.apache.commons.fileupload.*;
- import org.apache.commons.fileupload.servlet.*;
- import org.apache.commons.fileupload.disk.*;
- // Servlet 文件上传
- public class UploadServlet extends HttpServlet
- {
- private String filePath; // 文件存放目录
- private String tempPath; // 临时文件目录
- // 初始化
- public void init(ServletConfig config) throws ServletException
- {
- super.init(config);
- // 从配置文件中获得初始化参数
- filePath = config.getInitParameter("filepath");
- tempPath = config.getInitParameter("temppath");
- ServletContext context = getServletContext();
- filePath = context.getRealPath(filePath);
- tempPath = context.getRealPath(tempPath);
- System.out.println("文件存放目录、临时文件目录准备完毕 ...");
- }
- // doPost
- public void doPost(HttpServletRequest req, HttpServletResponse res)
- throws IOException, ServletException
- {
- res.setContentType("text/plain;charset=gbk");
- PrintWriter pw = res.getWriter();
- try{
- DiskFileItemFactory diskFactory = new DiskFileItemFactory();
- // threshold 极限、临界值,即硬盘缓存 1M
- diskFactory.setSizeThreshold(4 * 1024);
- // repository 贮藏室,即临时文件目录
- diskFactory.setRepository(new File(tempPath));
- ServletFileUpload upload = new ServletFileUpload(diskFactory);
- // 设置允许上传的最大文件大小 4M
- upload.setSizeMax(4 * 1024 * 1024);
- // 解析HTTP请求消息头
- List fileItems = upload.parseRequest(req);
- Iterator iter = fileItems.iterator();
- while(iter.hasNext())
- {
- FileItem item = (FileItem)iter.next();
- if(item.isFormField())
- {
- System.out.println("处理表单内容 ...");
- processFormField(item, pw);
- }else{
- System.out.println("处理上传的文件 ...");
- processUploadFile(item, pw);
- }
- }// end while()
- pw.close();
- }catch(Exception e){
- System.out.println("使用 fileupload 包时发生异常 ...");
- e.printStackTrace();
- }// end try ... catch ...
- }// end doPost()
- // 处理表单内容
- private void processFormField(FileItem item, PrintWriter pw)
- throws Exception
- {
- String name = item.getFieldName();
- String value = item.getString();
- pw.println(name + " : " + value + "\r\n");
- }
- // 处理上传的文件
- private void processUploadFile(FileItem item, PrintWriter pw)
- throws Exception
- {
- // 此时的文件名包含了完整的路径,得注意加工一下
- String filename = item.getName();
- System.out.println("完整的文件名:" + filename);
- int index = filename.lastIndexOf("\\");
- filename = filename.substring(index + 1, filename.length());
- long fileSize = item.getSize();
- if("".equals(filename) && fileSize == 0)
- {
- System.out.println("文件名为空 ...");
- return;
- }
- File uploadFile = new File(filePath + "/" + filename);
- item.write(uploadFile);
- pw.println(filename + " 文件保存完毕 ...");
- pw.println("文件大小为 :" + fileSize + "\r\n");
- }
- // doGet
- public void doGet(HttpServletRequest req, HttpServletResponse res)
- throws IOException, ServletException
- {
- doPost(req, res);
- }
- }
web.xml 文件
- <?xml version="1.0" encoding="gb2312"?>
- <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
- version="2.4">
- <servlet>
- <servlet-name>UploadServlet</servlet-name>
- <servlet-class>UploadServlet</servlet-class>
- <init-param>
- <param-name>filepath</param-name>
- <param-value>uploadFile</param-value>
- </init-param>
- <init-param>
- <param-name>temppath</param-name>
- <param-value>temp</param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>UploadServlet</servlet-name>
- <url-pattern>/upload</url-pattern>
- </servlet-mapping>
- </web-app>
程序运行过程截图:( 在 web.xml 文件中我们把UploadServlet 映射为 upload )1、启动 Tomcat ,在浏览器输入 URL 并填写 HTML 表单,如下:2、点击“上传”,发出一个包含了上传文件的复杂 HTTP 请求,由 UploadServlet 进行处理:先看下 Tomcat 的控制台输出信息:再看一下浏览器的相应输出:最后看上传的文件是否被被保存在指定的目录中:嗯,文件目录和文件保存时间都正确,就是文件大小忘了转化一下…(*^__^*) …小结:1、使用开源的 fileupload 包为我们在 UploadServlet 代码中显式地用繁杂的 request.getParameter(“username”) 语句来获取 HTTP 请求所包含的表单值;2、而且还省去了我们在 UploadServlet 中自己编写判断表单是否是文件或文本类型的代码;3、更重要的是,FileItem 对象的响应方法可以使得我们轻松地获取文件名、文件大小、路径等等;4、最重要的是,使用 JD-GUI 反编译器简单地看看开源的 fileupload 包中的类组织结构,这更加有意思、有用处,:-D