浏览器如何处理带上传控件的表单及服务器如何获取参数值

POST /servlet/testServlet HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="image"; filename="jetty配置.png"
Content-Type: image/png
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="comments"
截屏jetty配置

----WebKitFormBoundaryE19zNvXGzXaLvS5C

有文件上传时,表单提交方式必须是POST,且enctype必须是multipart/form-data

提交后,浏览器将表单的数据处理为一条消息,以控件为单元,用分隔符分开。

既可以上传键值对,也可以上传文件:

处理普通键值对控件的结果是一个请求头  Content-Disposition:form-data;name=属性名

                                            属性值

处理上传控件的结果是两个请求头        Content-Disposition:form-data;name=属性名;fileName=文件名称 

                                           Content-Type:上传文件的MIME类型

                                            文件流

1.get方式
get方式提交的话,表单项都保存在http header中,格式是
http://localhost:8080/hello.do?name1=value1&name2=value2这样的字符串。server端通过request.getParameter是可以取到值的。
2.post方式(enctype为缺省的application/x-www-form-urlencoded)
表单数据都保存在http的正文部分,格式类似于下面这样:用request.getParameter是可以取到数据的
name1=value1&name2=value2
3.post方式(enctype为multipart/form-data,多用于文件上传)
表单数据都保存在http的正文部分,各个表单项之间用分界线隔开,分界线格式类似于下面这样。这时用request.getParameter是取不到数据的,而是需要调用request.getInputStream()方法来取数据,不过取到的是个InputStream,所以无法直接获取指定的表单项(需要自己对取到的流进行解析,才能得到表单项以及上传的文件内容等信息)。这种需求属于比较共通的功能,所以有很多开源的组件可以直接利用。比如:apache的fileupload组件,smartupload等。通过这些开源的upload组件提供的API,就可以直接从request中取得指定的表单项了。
-----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="userfile1";
filename="C:\my.txt"
Content-Type:application/octet-stream
abbXXXccc
-----------------------------7d33a816d302b6
Content-Disposition: form-data;
name="name1" value1
-----------------------------7d33a816d302b6
Content-Disposition: form-data;
name="name2" value2
-----------------------------7d33a816d302b6

protected void doPost(HttpServletRequest request, HttpServletResponse response) {
	response.setCharacterEncoding("utf-8");
	String fileDir = "";
	String serverFileName = "";
	String serverFilePath = "";
	PrintWriter writer = null;
	try {
		writer = response.getWriter();
		if (ServletFileUpload.isMultipartContent(request)) {
			DiskFileItemFactory factory = new DiskFileItemFactory(); // 基于磁盘文件项目创建一个工厂对象
			ServletFileUpload upload = new ServletFileUpload(factory); // 创建一个新的文件上传对象
			int size = 100 * 1024 * 1024; // 最大上传文件,不超过10M
			List<FileItem> fileItemList = new ArrayList<FileItem>();
			fileItemList = upload.parseRequest(request);
			// 解析上传请求
			System.out.println(fileItemList.size());
			for (FileItem fileItem : fileItemList) {
				if (fileItem.isFormField()) {// 判断是否为文件域
					System.out.println("属性名是:" + fileItem.getFieldName());
					System.out.println("属性值是:" + fileItem.getString("utf-8"));
				} else {
					String fileName = fileItem.getName(); // 获取文件名
					if (fileName != null && !fileName.equals("")) { // 判断是否选择了文件
						long upFileSize = fileItem.getSize(); // 上传文件大小
						System.out.println("上传文件" + (upFileSize / 1024 / 1024) + "M");
						if (upFileSize > size) {
							writer.write("文件超出上限100M,上传失败");
							return;
						}
						String suffix = fileName.substring(fileName.lastIndexOf("."));// 取文件名的后缀
						// 得到不重复的文件名,这一步是为了防止同时上传两个同名文件而做的,避免文件名重复
						Date dt = new Date(System.currentTimeMillis());
						SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
						serverFileName = fmt.format(dt);
						serverFileName = serverFileName + suffix;
						serverFilePath = fileDir + "/" + serverFileName;
						File serverFile = new File(serverFilePath);
						fileItem.write(serverFile);
					} else {
						writer.write("您未选择文件,请重新选择文件");
						return;
					}
				}
			}
			writer.write("操作成功");
		} else {
			writer.write("前端传文件enctype属性设置错误");
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		if (writer != null) {
			writer.flush();
			writer.close();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值