multipart/form-data 文件上传表单中 传递参数无法获取的原因!
2017-08-25 22:01
881 查看
1.什么是multipart/form-data
首先我们需要明白在html中的enctype属性,enctype:规定了form表单在发送到服务器时候编码方式。他有如下的三个值。
①application/x-www-form-urlencoded。默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
②multipart/form-data 。 指定传输数据为二进制类型,比如图片、mp3、文件。
③text/plain。纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。
2.明确在enctype参数为application/x-www-form-urlencoded的时候post和get请求参数和请求体是什么形式的
get请求请求头:
GET/www.xxx.com?name=%22hello+world%22&**file=temp.png**&submit=submit HTTP/1.1
因为get请求没有请求体,所有他的所有参数都是在url的后边添加。type=file的表单项只能获取到文件的名字,并不能获取文件的内容。
post请求
请求头:
POST /www.baidu.com HTTP/1.1
请求体:
name=%22hello+world%22&file=temp.png&submit=submit
(1)我们可以发现不管是post请求和get请求,他们的参数存在的形式都是不变的,通过key=value的形式存在。
(2)表单项type=filed只能获取获取文件的名字不能获取文件的内容。
2. 明确在enctype参数为multipart/form-data的时候post和get请求参数和请求体是什么形式的
get请求请求头:
GET/www.xxx.com?name=%22hello+world%22&file=temp.png&submit=submit HTTP/1.1
get请求和multipart/form-data结合无效,因为文件上传需要请求体。
post请求:
请求头:
POST /www.xxx.com HTTP/1.1
请求体:
------WebKitFormBoundaryIZDrYHwuf2VJdpHw Content-Disposition: form-data; name="name" "hello world" ------WebKitFormBoundaryIZDrYHwuf2VJdpHw Content-Disposition: form-data; name="file"; filename="temp.png" Content-Type: image/png .PNG . ... IHDR... ..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7. pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`. ------WebKitFormBoundaryIZDrYHwuf2VJdpHw Content-Disposition: form-data; name="submit" submit ------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
通过观察发现这个的请求体就发生了变化。这种请求体被称之为多部件请求体。
什么是多部件请求体:就是把每一个表单项分割为一个部件。
因为表单项分为普通表单项和文件表单项,所以说部件也有区别。
普通表单项:
一个请求头:Content-Disposition: form-data; name=”name”
一个请求体:里面就是我们表单的值”hello world”
文件表单项:
两个请求头:
Content-Disposition: form-data; name="file"; filename="temp.png"
Content-Type: image/png
一个请求体:
.PNG . ... IHDR... ..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7. pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`. ------WebKitFormBoundaryIZDrYHwuf2VJdpHw Content-Disposition: form-data; name="submit" submit ------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
总结:参数获取不到主要是因为在使用multipart/form-data属性之后请求体发生了变化。不是key=value的形式出现所以说获取不到。
解决办法:
(1)我们可以通过js代码来些修改,把我们的参数追加在url的后边。
<form id="upload" name="upload" action="fileftp.jsp" method="post" ENCTYPE="multipart/form-data"> <input type="hidden" name="otherName" id="otherName" value="abcdefg"/> <td nowrap> <input type="file" id="file1" name="file1" value="" size="40" class="sbttn"/> <input type="submit" value="上传" class="sbttn"/> </td> </form>
<script language="javascript"> function formSubmit(){ var action="fileftp.jsp"; action+="?otherName="+document.upload.otherName.value; document.upload.action=action; document.upload.submit(); } </script>
(2)通过修改服务器端代码。前提是利用jar包。
commons-fileupload-1.2.2.jar和commons-io-1.4.jar
//创建工厂 DiskFileItemFactory factoy=new DiskFileItemFactory(); //创建解析器 ServletFileUpload sfu=new ServletFileUpload(factoy); //解析request try { List<FileItem> list=sfu.parseRequest(request); for (FileItem fileItem : list) { fileItem.getFieldName(); System.out.println(fileItem.getString()); } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); }
上传图片示例代码:
<h1>添加图书</h1> <p style="font-weight: 900; color: red">${msg}</p> <form action="<c:url value='/UploadServlet'/>" method="post" enctype="multipart/form-data"> 图书名称:<input style="width: 150px; height: 20px;" type="text" name="bname"/><br/> 图书图片:<input style="width: 223px; height: 20px;" type="file" name="image"/><br/> 图书单价:<input style="width: 150px; height: 20px;" type="text" name="price"/><br/> 图书作者:<input style="width: 150px; height: 20px;" type="text" name="author"/><br/> 图书分类:<select style="width: 150px; height: 20px;" name="cid"> <c:forEach items="${list}" var="cate"> <option value="${cate.cid }">${cate.cname }</option> </c:forEach> </select> <br/> <input type="submit" value="添加图书"/> </form>
package cn.zll.bookstore.adminbook.servlet; import java.awt.Image; import java.io.File; import java.io.IOException; import java.util.List; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.swing.ImageIcon; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import cn.zll.bookstore.adminbook.service.service; import cn.zll.bookstore.book.domain.Book; public class UploadServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { service s=new service(); response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); //文件上传的三部曲 //创建工厂 DiskFileItemFactory factoy=new DiskFileItemFactory(); //创建解析器 ServletFileUpload sfu=new ServletFileUpload(factoy); //设置上传文件的大小 sfu.setFileSizeMax(20*1024); //解析request try { List<FileItem> list=sfu.parseRequest(request); Book b=new Book(); b.setBid(UUID.randomUUID().toString().replace("-", "")); String bname=list.get(0).getString("utf-8"); b.setBname(bname); System.out.println(bname); String price=list.get(2).getString("utf-8"); b.setPrice(price); String author=list.get(3).getString("utf-8"); b.setAuthor(author); String cid=list.get(4).getString("utf-8"); b.setCid(cid); System.out.println(bname+price+author+cid); // 图书名称:<input style="width: 150px; height: 20px;" type="text" name="bname"/><br/> // 图书图片:<input style="width: 223px; height: 20px;" type="file" name="image"/><br/> // 图书单价:<input style="width: 150px; height: 20px;" type="text" name="price"/><br/> // 图书作者:<input style="width: 150px; height: 20px;" type="text" name="author"/><br/> // 图书分类:<select style="width: 150px; height: 20px;" name="cid"> // // //设置图片保存的目录 String path=this.getServletContext().getRealPath("/book_img"); //得到文件名称 String fileName=UUID.randomUUID().toString().replace("-", "")+"_"+list.get(1).getName(); //校验图片的格式 if(!fileName.toLowerCase().endsWith("jpg")){ System.out.println("图片格式不是jpg"); request.setAttribute("msg", "你的图片格式不是jpg格式"); request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response); return; } //使用目录和文件名称创建目标文件 File f=new File(path,fileName); //保存文件 list.get(1).write(f); //校验图片的尺寸 Image image=new ImageIcon(f.getAbsolutePath()).getImage(); if(image.getWidth(null)>200 || image.getHeight(null)>200){ f.delete(); request.setAttribute("msg", "图片的尺寸太大"); request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response); } //设置book的属性 b.setImage("book_img/"+fileName); s.add(b); request.setAttribute("msg", "添加成功"); request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response); System.out.println("fileName:"+fileName); System.out.println(path); } catch (FileUploadException e) { if(e instanceof FileUploadBase.FileSizeLimitExceededException){ System.out.println("你上传的文件大于15K"); request.setAttribute("msg", "你的图片大于15k"); request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response); return; } e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
相关文章推荐
- 简单解决 multipart/form-data 文件上传表单中 传递参数无法获取的办法! (解决办法:动态更改表单提交URL)
- 简单解决 multipart/form-data 文件上传表单中 传递参数无法获取的办法! (解决办法:动态更改表单提交URL)
- enctype="multipart/form-data" 文件上传,获取form 表单参数的问题
- enctype=“multipart/form-data”,Servlet获取参数 原创 2017年03月21日 18:46:44 标签:enctype /servlet文件上传 2094 HTML表
- enctype="multipart/form-data"的表单无法获取表单中除了type=file以外的其他参数 commons-fileupload 获取除file外其他参数
- enctype="multipart/form-data"的表单无法获取表单中除了type=file以外的其他参数 commons-fileupload 获取除file外其他参数
- 文件上传下载时,在form表单中设置属性enctype=“multipart/form-data”的情况下,如何获取表单提交的值?
- 为什么上传文件的表单里面要加一个属性enctype=multipart/form-data?
- 解决multipart/form-data表单中传递参数问题(动态更改表单提交URL)
- spring mvc 通过bean获取form的参数和并且进行服务器验证 ,而且支持多个文件上传的用法。html使用form_data
- Servlet获取form表单上传文件及其他参数
- express获取表单中的文件和其他数据(enctype=multipart/form-data)
- 为什么上传文件的表单里面要加一个属性ENCTYPE=MULTIPART/FORM-DATA?
- JSP学习笔记:用multipart/form-data提交表单get非文件字段获取的解决办法
- 为什么上传文件的表单需要设置enctype="multipart/form-data"
- 【asp】web做文件上传,需要在表单用上 <form Enctype="multipart/form-data"/>
- enctype="multipart/form-data"表单上传文件
- form表单不设置method属性后果很严重,参数无法传递,第二次了搞了半天才找出原因
- 表单同时有中文字段和文件上传,加上enctype="multipart/form-data"后导致的中文乱码问题
- 用JSP分析multipart/form-data基于表单的文件上传