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只能获取获取文件的名字不能获取文件的内容。

3. 明确在enctype参数为multipart/form-data的时候post和get请求参数和请求体是什么形式的

get请求

请求头:

GET/www.xxx.com?name=%22hello+world%22&file=temp.png&submit=submit HTTP/1.1

get请求

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();
}
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 文件上传表单中 传递参数无法获取的原因!的更多相关文章

  1. spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)

    一,表单中有多个文件域时如何实现说明和文件的对应? 1,说明和文件对应 文件上传页面中,如果有多个文件域又有多个相对应的文件说明时, 文件和说明如何对应? 我们在表单中给对应的file变量和text变 ...

  2. python 处理form/data文件上传

    处理multipart/form-data 的java serverlet请求接口通过python实现 记住不要在头加:"Content-Type":"multipart ...

  3. 上传漏洞科普[1]-文件上传表单是Web安全主要威胁

    为了让最终用户将文件上传到您的网站,就像是给危及您的服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种 常见的要求,因为它有助于提高您的业务效率.在Facebook ...

  4. 【Flask】 结合wtforms的文件上传表单

    表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...

  5. 利用Formdata实现form提交文件上传不跳转页面

    作者:幻月九十链接:https://www.zhihu.com/question/19631256/answer/119911045来源:知乎著作权归作者所有,转载请联系作者获得授权. $('form ...

  6. Multipart/form-data POST文件上传详解

    Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form ...

  7. Multipart/form-data POST文件上传详解(转)

    Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form ...

  8. 构建multipart/form-data实现文件上传

    构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...

  9. form里面文件上传并预览

    其实form里面是不能嵌套form的,如果form里面有图片上传和其他input框,我们希望上传图片并预览图片,然后将其他input框填写完毕,再提交整个表单的话,有两种方式! 方式一:点击上传按钮的 ...

随机推荐

  1. 易初大数据——2019年10月17日 王庆超 spss

    开放数据库链接是为解决异构数据库间的数据共享而产生, 现已成为WOSA的主要部分和基于windows环境的一种数据库访问接口和标准ODOC为异构数据库访问提供统一接口,允许应用程序以SOL.为数据存取 ...

  2. 深入理解计算机系统 第八章 异常控制流 Part1 第二遍

    第二遍读这本书,每周花两到三小时时间,能读多少读多少(这次看了第 500~507 页,共 8 页) 第一遍对应笔记链接 https://www.cnblogs.com/stone94/p/101651 ...

  3. 015.Kubernetes二进制部署所有节点kubelet

    一 部署 kubelet kubelet 运行在每个 worker 节点上,接收 kube-apiserver 发送的请求,管理 Pod 容器,执行交互式命令,如 exec.run.logs 等. k ...

  4. Verilog模块概念和实例化#转载自Jason from Lofter

    Verilog模块概念和实例化 模块的概念 模块(module)是verilog最基本的概念,是v设计中的基本单元,每个v设计的系统中都由若干module组成. 1.模块在语言形式上是以关键词modu ...

  5. go中的关键字-defer

    1. defer的使用 defer 延迟调用.我们先来看一下,有defer关键字的代码执行顺序: func main() { defer func() { fmt.Println("1号输出 ...

  6. 标准库bufio个人详解

    本文是我有通俗的语言写的如果有误请指出. 先看bufio官方文档 https://studygolang.com/pkgdoc文档地址 主要分三部分Reader.Writer.Scanner 分别是读 ...

  7. ubuntu 16.04上源码编译glog和gflags 编写glog-config.cmake和gflags-config.cmake | compile glog and glags on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/977f5125/,欢迎阅读! compile glog and glags on ubuntu 16.04 Series comp ...

  8. mybatis精讲(三)--标签及TypeHandler使用

    目录 话引 XML配置标签 概览 properties 子标签property resource 程序注入 settings 别名 TypeHandler 自定义TypeHandler EnumTyp ...

  9. 新闻实时分析系统 Spark Streaming实时数据分析

    1.Spark Streaming功能介绍1)定义Spark Streaming is an extension of the core Spark API that enables scalable ...

  10. 【Luogu P2515】软件安装

    Luogu P2515 这道题的题面与P2146有点像.一些不同地方就是P2146是无环的,这题是有环的. 很显然,如果有几个软件的依赖关系形成环,那么这几个软件就可以被看成是一个大软件,其价值和空间 ...