上传文件

2022-09-14 21:15:06 浏览数 (1)

1、文件上传的作用

例如网络硬盘!就是用来上传下载文件的。

往百度网盘上传一个文件就是文件上传。

2、文件上传对页面的要求

上传文件的要求比较多,需要记一下:

  • 必须使用表单,而不能是超链接;
  • 表单的method必须是POST,而不能是GET;
  • 表单的enctype必须是multipart/form-data;
  • 在表单中添加file表单字段,即<input type="file”…/>

例如:

代码语言:javascript复制
    <form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data">
    	用户名:<input type="text" name="username"/><br/>
    	文件1:<input type="file" name="file1"/><br/>
    	文件2:<input type="file" name="file2"/><br/>
    	<input type="submit" value="提交"/>
    </form>

3、文件上传对Servlet的要求

当提交的表单是文件上传表单时,那么对Servlet也是有要求的。

首先我们要肯定一点,文件上传表单的数据也是被封装到request对象中的。

**request.getParameter(String)**方法获取指定的表单字段字符内容,但文件上传表单已经不在是字符内容,而是字节内容,所以失效。

这时可以使用request的getInputStream()方法获取ServletInputStream对象,它是InputStream的子类,这个ServletInputStream对象对应整个表单的正文部分(从第一个分隔线开始,到最后),这说明我们需要的解析流中的数据。当然解析它是很麻烦的一件事情,而Apache已经帮我们提供了解析它的工具:commons-fileupload。

可以尝试把request.getInputStream()这个流中的内容打印出来看看

代码语言:javascript复制
public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		InputStream in = request.getInputStream();
		String s = IOUtils.toString(in); //使用apache的commons的io组件,把流中的数据读取出来转换成字符串
		System.out.println(s);
	}
代码语言:javascript复制
-----------------------------7ddd3370ab2
Content-Disposition: form-data; name="username"

hello
-----------------------------7ddd3370ab2
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

aaa
-----------------------------7ddd3370ab2
Content-Disposition: form-data; name="file2"; filename="b.txt"
Content-Type: text/plain

bbb
-----------------------------7ddd3370ab2--

4、commons-fileupload工具介绍

4.1、fileupload概述

fileupload是由apache的commons组件提供的上传组件。它最主要的工作就是帮我们解析request.getInputStream()。

fileupload组件需要的JAR包有:

  • commons-fileupload.jar,核心包;
  • commons-io.jar,依赖包。

4.2、fileupload简单应用

fileupload的核心类有:DiskFileItemFactory、ServletFileUpload、FileItem。

使用fileupload组件的步骤如下:

  • 创建工厂类DiskFileItemFactory对象:DiskFileItemFactory factory = new DiskFileItemFactory()
  • 使用工厂创建解析器对象:ServletFileUpload fileUpload = new ServletFileUpload(factory)
  • 使用解析器来解析request对象:List list = fileUpload.parseRequest(request)

隆重介绍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):把上传的文件保存到指定文件中。

4.3、简单上传示例

写一个简单的上传示例:

  • 表单包含一个用户名字段,以及一个文件字段;
  • Servlet保存上传的文件到uploads目录,显示用户名,文件名,文件大小,文件类型。

第一步:

完成index.jsp,只需要一个表单。注意表单必须是post的,而且enctype必须是mulitpart/form-data的。

代码语言:javascript复制
	<form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data">
    	用户名:<input type="text" name="username"/><br/>
    	文件1:<input type="file" name="file1"/><br/>
    	<input type="submit" value="提交"/>
    </form>

第二步:

完成FileUploadServlet

代码语言:javascript复制
public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 因为要使用response打印,所以设置其编码
		response.setContentType("text/html;charset=utf-8");
		
		// 创建工厂
		DiskFileItemFactory dfif = new DiskFileItemFactory();
		// 使用工厂创建解析器对象
		ServletFileUpload fileUpload = new ServletFileUpload(dfif);
		try {
			// 使用解析器对象解析request,得到FileItem列表
			List<FileItem> list = fileUpload.parseRequest(request);
			// 遍历所有表单项
			for(FileItem fileItem : list) {
				// 如果当前表单项为普通表单项
				if(fileItem.isFormField()) {
					// 获取当前表单项的字段名称
					String fieldName = fileItem.getFieldName();
					// 如果当前表单项的字段名为username
					if(fieldName.equals("username")) {
						// 打印当前表单项的内容,即用户在username表单项中输入的内容
						response.getWriter().print("用户名:"   fileItem.getString()   "<br/>");
					}
				} else {//如果当前表单项不是普通表单项,说明就是文件字段
					String name = fileItem.getName();//获取上传文件的名称
					// 如果上传的文件名称为空,即没有指定上传文件
					if(name == null || name.isEmpty()) {
						continue;
					}
					// 获取真实路径,对应${项目目录}/uploads,当然,这个目录必须存在
					String savepath = this.getServletContext().getRealPath("/uploads");
					// 通过uploads目录和文件名称来创建File对象
					File file = new File(savepath, name);
					// 把上传文件保存到指定位置
					fileItem.write(file);
					// 打印上传文件的名称
					response.getWriter().print("上传文件名:"   name   "<br/>");
					// 打印上传文件的大小
					response.getWriter().print("上传文件大小:"   fileItem.getSize()   "<br/>");
					// 打印上传文件的类型
					response.getWriter().print("上传文件类型:"   fileItem.getContentType()   "<br/>");
				}
			}
		} catch (Exception e) {
			throw new ServletException(e);
		} 
	}

0 人点赞