欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

上传表单获取文件数据

程序员文章站 2022-06-11 15:09:52
...

  在我们完成项目的过程中,有时候会碰到需要上传图片、音频、视频、文件等保存到数据库,这时候我们就可以用流的方式读取或写入。但是用流的方式需要拿到文件在本机上的路径,而现在大部分的浏览器出于安全考虑是拿不到文件的完整路径的,所以就无法访问到本机上的文件。使用上传表单则可以读取到这个文件,不是使用上传表单有一些限制,跟我们平常的上传表单不完全相同。下面是对限制的说明
  上传对表单的限制:
表单必须加上method="post"属性,表示以post提交方式上传;
必须加上enctype=“multipart/form-data”;表示多部件的表单数据
表单中需要添加文件表单项,什么是文件表单项?就是input标签类型为file的 控件,除了它叫文件表单项,其他的都叫普通表单项。文件表单项:,必须要给name属性。
  上传对Servlet的限制:
获取传递过来的数据,我们使用的request.getParameter(“xxx”);,它的返回类型为String类型,而我们上传的文件到Servlet这边就成了String类型,那肯定是不行的。而且这个方法在表单为enctype="multipart/form-data"时作废了。他永远返回null;不管你传的是文件类型数据还是普通的数据返回的都是null。
这时就提供了另一个方法用来获取传递过来的数据:ServletInputStream in=request.getInputStream();这个方法返回的是流数据,数据包含整个请求的体。
  上面已经说了相关的限制,现在说说servlet怎么拿到对应的数据吧。为了方便拿到数据我这里引用了两个工具jar包,分别是 commons-io-2.5.jar和 commons-fileupload-1.3.2.jar。我们既然要上传文件那肯定要跟流打交道,所以引了个io包,而fileupload包则会帮我们解析request中的上传数据,解析后的结果就是将一个表单项封装到一个FileItem对象中。而我们通常都有多个表单项,所以得出的是一个FileItem集合。我们遍历这个集合调用FileItem的方法就能拿到对应表单项中的数据了。
  下面先给出FileItem对象常用的几个方法:
第一个: isFormField(),上面已经说了一个表单项封装到一个FileItem对象中,也就是一个FileItem对象对应我们前端的一个input控件中的数据。所以有一个方法能判断表单项为普通表单项还是文件表单项。返回true为普通表单项,否则为文件表单项。
第二个:getFieldName()返回表单项的名称,即前端input控件的name属性值,返回类型为String。
第三个:getString(String charset),返回表单项的值,返回类型为String,只适用于普通表单项。charset为编码格式。
第四个:getName(),返回上传的文件名称,返回类型为String。
第五个:getSize(),返回上传的字节数, 返回类型为long。
第六个:getInputStream(),返回上传文件的对应的输入流,返回类型为InputStream。
第七个:write(File destFile),把上传的文件内容保存到指定的文件夹中。destFile为指定的文件夹对象。
上面讲了一堆,想必大家也看烦了,那就直接上干货吧。我这里是一个新增功能:我这就贴出servlet中获取数据并赋值给对象的代码吧。当然图片保存到数据出我给对象赋的是图片的路径,然后用流读写保存。

public void addCommodity(HttpServletRequest request,
		HttpServletResponse response) throws ServletException, IOException {
	String msg = "数据异常!";
	Commodity commodity = new Commodity();
	int sizeThreshold = 1024 * 1024 * 10; // 10MB
	int fileSizeMax = 1024 * 1024 * 100; // 100M
	int sizeMax = 1024 * 1024 * 300; // 300M
	DiskFileItemFactory factory = new DiskFileItemFactory();// 第一步:创建工厂,设置工厂配置
	factory.setSizeThreshold(sizeThreshold); // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中 10M
	factory.setRepository(new File(System.getProperty("java.io.tmpdir")));// 配置临时目录
	ServletFileUpload upload = new ServletFileUpload(factory);//第二步:创建解析器,设置解析器配置
	upload.setHeaderEncoding("utf-8");// 设置编码
	upload.setFileSizeMax(fileSizeMax); // 设置上传文件的最大大小
	upload.setSizeMax(sizeMax); // 设置请求的最大大小
	// 构造临时路径来存储上传的文件,这个路径相对当前应用的目录,也就是此项目的目录
	String uploadPath = this.getServletContext().getRealPath("/upload");
	File uploadDir = new File(uploadPath);
	if (!uploadDir.exists()) {// 如果目录不存在则创建
		uploadDir.mkdir();
	}
	try {
		// 第三步:使用解析器解析表单数据,得到FileItem集合
		List<FileItem> fileItems = upload.parseRequest(request);
		for (FileItem fileItem : fileItems) {// 第四部:遍历FileItem集合,获取数据
			if (!fileItem.isFormField()) {// isFormField 是否为普通表单项
				// 处理路径及保存文件
				String fileName = new File(fileItem.getName()).getName();
				if (fileName != null) {//没有上传文件则不作操作
					String filePath = uploadPath + File.separator + fileName;
					File storeFile = new File(filePath);
					// 保存文件到目录中
					fileItem.write(storeFile);
					commodity.setCommoditypicture(storeFile.getAbsolutePath());
				}
			} else {
				// 获取普通表单项字段以及给对象赋值
				String fieldName = fileItem.getFieldName();
				String val = fileItem.getString("UTF-8");
				if (fieldName.equals("commodityid")) {
					commodity.setCommodityid(Integer.valueOf(val));
				}
				if (fieldName.equals("seasonid")) {
					commodity.setSeasonid(Short.valueOf(val));
				}
				if (fieldName.equals("discount")) {
					commodity.setDiscount(Double.valueOf(val));
				}
				if (fieldName.equals("commoditystylenumber")) {
					commodity.setCommoditystylenumber(val);
				}
				if (fieldName.equals("specialoffer")) {
					if (Boolean.valueOf(val).equals("false")) {
						commodity.setSpecialoffer(false);
					} else {
						commodity.setSpecialoffer(true);
					}
				}
				if (fieldName.equals("putaway")) {
					if (Boolean.valueOf(val).equals("false")) {
						commodity.setPutaway(false);
					} else {
						commodity.setPutaway(true);
					}
				}
			}
		}
		msg = iCommodityService.insert(commodity);//接口新增方法
		PrintWriter out = response.getWriter();
		out.write(msg);
		out.flush();
		out.close();
	} catch (Exception e) {
		e.printStackTrace();
	}
}

  上面普通表单项给对象赋值我删掉了一些,字段有点多就不给大家看了都是差不多的写法,类型不同而已。还有一点大家需要注意,就是boolean类型的数据这边获取时会转成String类型,直接强转好像不行,只能用判断然后赋给定值。值拿到了剩下的就可以交给接口方法去保存了。