enctype就是encodetype就是编码类型的意思。
enctype:规定了form表单在发送到服务器时的编码方式,有如下的三个值。
application/x-www-form-urlencoded:默认的编码方式。只能上传文本格式的文件。不能用于发送文件。在发送前会编码所有字符,即在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,"+"加号转换为空格,特殊符号转换为 ASCII HEX 值)
multipart/form-data:指定传输数据为二进制类型,比如图片,mp3,文件。是将文件以二进制的形式上传,可以实现多种类型的文件上传。不对字符编码,使用包含文件上传控件的表单,必须使用此值
text/plain:纯文本的传输。空格转换为"+"号,但不对特殊字符编码,一般用于email之类的。不能用于发送文件
乱码问题
若使用出现"+"加号转为空格或其它乱码现象,则可检查前端或后台的程序,尝试使用java.net.URLEncoder.encode(value, "UTF-8")对value值进行加密或者使用java.net.URLDecoder.decode(value, "UTF-8")对value值进行解密。
一、application/x-www-form-urlencoded
这是form表单默认的编码格式。当我们没有在form表单中设置 enctype 属性时,它就是默认采用 application/x-www-form-urlencoded 这种编码格式的。application/x-www-form-urlencoded 会将表单中需要发送的数据编码为 "名称/键值" 的形式,这是标准的编码格式。当表单的 method 为 post 请求时,浏览器会将 form 数据封装到 http body 中,然后发送到服务器端;当表单的 method 为 get 请求时,application/x-www-form-urlencoded会将表单的数据拼接为一个字符串(name=coderbolg&key=php),将这个字符串拼接到 url后面,并用 ?分割,随后请求这个新的url。
当我们想要使用 Ajax 像form 表单提交数据那样使用POST请求,就需要设置 请求头为 application/x-www-form-urlencoded 的编码类型,不然服务器端接收不到数据。
// 设置属性 xhr.open('post', '02.post.php'); // 如果想要使用post提交数据,必须添加此行 xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 将数据通过send方法传递 xhr.send('name=fox&age=18');
二、multipart/form-data
这个是专门用来传输特殊数据类型的,如mp3、图片等。这种编码方式不对字符进行编码,数据是通过二进制的形式传送到服务器端的,这时如果用 request 是无法获取到相应表单的值的,应该使用 stream流数据,将传送到服务器端的二进制数据解码,从而读取数据。
form表单代码:
<form action="uploadImage" method="post" enctype="multipart/form-data"> 文件编号:<input name="serialNo"><br> 上传图片:<input type="file" name="image" accept="/image" ><br> <input type="submit" value="上传"> </form>
springMVC中,服务器端获取数据时,可以直接获取相应的表单值,也可以将其封装到自定义对象中一并获取。
@RequestMapping("/uploadImage") public ModelAndView uploadImage(HttpServletRequest request, MultipartFile image,String serialNo) { }
或将表单中的各值封装到自定义对象 UploadImageFile 中:
public class UploadImageFile { private String serialNo; private MultipartFile image; } @RequestMapping("/uploadImage") public ModelAndView uploadImage(HttpServletRequest request, UploadImageFile imageFile) { }
三、text/plain
数据以纯文本方的式编码,其中不包含任何的附件或格式字符。
以上两种方式在服务器端接收数据时都可以采用 request.getParameter(参数名); 方式,但是当定义enctype为text/plain时,则使用以下方式接收数据
@RequestMapping("/uploadImage") public ModelAndView uploadImage(HttpServletRequest request) { try { BufferedReader reader = request.getReader(); char[] buf = new char[512]; int len = 0; StringBuffer nameStr = new StringBuffer(); while((len = reader.read(buf)) != -1) { nameStr.append(buf, 0, len); } String name = nameStr.toString(); if(name == null) { name = ""; } } catch (IOException e) { e.printStackTrace(); } }