您的当前位置:首页正文

在Servlet中使用开源fileupload包实现文件上传功能

2021-11-14 来源:易榕旅网
在Servlet中使用开源fileupload包实现文件上传功能

当我们在 HTML 表单中选择本地文件之后点击“提交”按钮则会将文件上传到服务器中,此时该 HTTP 请求正文的数据类型就是 multipart/form-data 型的。而在 Servlet 技术中,该 HTTP 请求会被 Servlet 容器(如 Tomcat)包装成 HttpServletRequest 对象,再由端所请求的相应 Servlet 进行处理。

但是,如果此时我们在服务器端编写的 Servlet 一点点地解析这个 HTTP 请求,分离出其中的文本表单和上传的文件类型,这未免有点低效。于是,我们可以使用 Apache 开源上传软件包 fileupload 来简化这一过程,直接使用即可。下载地址:http://commons.apache.org/fileupload/

在 fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象;FileItem 对象必须由 ServletFileUpload 类中的 parseRequest() 方法解析 HTTP 请求(即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单和上传文件;而 ServletFileUpload 对象的创建需要依赖于 FileItemFactory 工厂将获得的上传文件 FileItem 对象保存至服务器硬盘,即 DiskFileItem 对象。

呼„把这个 fileupload 包中的关系讲得那么乱,最好还是自己看下载下来的帮助文档。不过,推荐一个免费的 Java 反编译器 JD-GUI ,用它能够很轻松地打开 .jar 文件,除了源代码中的注释,其他的一览无遗,很好用啊。下载地址:http://java.decompiler.free.fr/?q=jdgui 好吧,我们的程序要求:

1、提供一个 HTML 文件,用户可在相应表单中选择需要上传的文件;

2、编写一个名叫 UploadServlet 的Servlet 文件,主要功能是解析上面 HTML 表单所提交的 HTTP 请求,把普通的文本域和文件域分离开来;

3、UploadServlet 根据 web.xml 配置文件中的初始化参数确定好需要在 Web 服务器存放该文件的目录,将上传的文件写入到该存放目录中,在我的这里我把上传的文件保存到 F:\\java\\JavaWeb\\ch05\dFile 目录中,而 F:\\java\\JavaWeb\\ch05\emp 目录则用作该 Web 应用的临时目录。 程序代码: upload.html 文件

1.

2. Servlet 上传文件 3.

4.

6. action=\"upload\"> 7.

8. User Name:>

9. Upload File1:>

10. Upload File2:>

11. 12. 13.

14. 15.

UploadServlet.java 文件

1. import javax.servlet.*; 2. import javax.servlet.http.*; 3. import java.io.*; 4. import java.util.*;

5. import org.apache.commons.fileupload.*;

6. import org.apache.commons.fileupload.servlet.*; 7. import org.apache.commons.fileupload.disk.*; 8.

9. // Servlet 文件上传

10. public class UploadServlet extends HttpServlet 11. {

12. private String filePath; // 文件存放目录 13. private String tempPath; // 临时文件目录 14.

15. // 初始化

16. public void init(ServletConfig config) throws ServletExcept

ion 17. {

18. super.init(config);

19. // 从配置文件中获得初始化参数

20. filePath = config.getInitParameter(\"filepath\"); 21. tempPath = config.getInitParameter(\"temppath\"); 22.

23. ServletContext context = getServletContext(); 24.

25. filePath = context.getRealPath(filePath); 26. tempPath = context.getRealPath(tempPath);

27. System.out.println(\"文件存放目录、临时文件目录准备完

毕 ...\"); 28. } 29.

30. // doPost

31. public void doPost(HttpServletRequest req, HttpServletRespo

nse res)

32. throws IOException, ServletException

33. {

34. res.setContentType(\"text/plain;charset=gbk\"); 35. PrintWriter pw = res.getWriter(); 36. try{

37. DiskFileItemFactory diskFactory = new DiskFileItemF

actory();

38. // threshold 极限、临界值,即硬盘缓存 1M

39. diskFactory.setSizeThreshold(4 * 1024); 40. // repository 贮藏室,即临时文件目录

41. diskFactory.setRepository(new File(tempPath)); 42.

43. ServletFileUpload upload = new ServletFileUpload(di

skFactory);

44. // 设置允许上传的最大文件大小 4M

45. upload.setSizeMax(4 * 1024 * 1024); 46. // 解析HTTP请求消息头

47. List fileItems = upload.parseRequest(req); 48. Iterator iter = fileItems.iterator(); 49. while(iter.hasNext()) 50. {

51. FileItem item = (FileItem)iter.next(); 52. if(item.isFormField()) 53. {

54. System.out.println(\"处理表单内容 ...\"); 55. processFormField(item, pw); 56. }else{

57. System.out.println(\"处理上传的文件 ...\"); 58. processUploadFile(item, pw); 59. }

60. }// end while() 61.

62. pw.close();

63. }catch(Exception e){

64. System.out.println(\"使用 fileupload 包时发生异

常 ...\");

65. e.printStackTrace();

66. }// end try ... catch ... 67. }// end doPost() 68. 69.

70. // 处理表单内容

71. private void processFormField(FileItem item, PrintWriter pw

)

72. throws Exception

73. {

74. String name = item.getFieldName();

75. String value = item.getString(); 76. pw.println(name + \" : \" + value + \"\\r\\n\"); 77. } 78.

79. // 处理上传的文件

80. private void processUploadFile(FileItem item, PrintWriter p

w)

81. throws Exception 82. {

83. // 此时的文件名包含了完整的路径,得注意加工一下 84. String filename = item.getName();

85. System.out.println(\"完整的文件名:\" + filename); 86. int index = filename.lastIndexOf(\"\\\\\");

87. filename = filename.substring(index + 1, filename.lengt

h()); 88.

89. long fileSize = item.getSize(); 90.

91. if(\"\".equals(filename) && fileSize == 0)

92. {

93. System.out.println(\"文件名为空 ...\"); 94. return; 95. } 96.

97. File uploadFile = new File(filePath + \"/\" + filename);

98. item.write(uploadFile);

99. pw.println(filename + \" 文件保存完毕 ...\"); 100. pw.println(\"文件大小为 :\" + fileSize + \"\\r\\n\"); 101. } 102. 103. // doGet 104. public void doGet(HttpServletRequest req, HttpServletR

esponse res)

105. 106. 107. 108. 109.

throws IOException, ServletException {

doPost(req, res); } }

web.xml 文件

1.

2. 3. xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 4. xsi:schemaLocation=\"http://java.sun.com/xml/ns/j2ee http://

java.sun.com/xml/ns/j2ee/web-app_2_4.xsd\" 5. version=\"2.4\"> 6.

7.

8. UploadServlet 9. UploadServlet 10.

11.

12. filepath

13. uploadFile 14. 15.

16. temppath 17. temp 18. 19. 20.

21.

22. UploadServlet 23. /upload 24. 25.

26.

程序运行过程截图:(在 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

因篇幅问题不能全部显示,请点此查看更多更全内容