URLDecoder 和 URLEncoder
在了解URLDecoder和URLEncoder之前,有必要先了解Content-Type中application/x-www-form-urlencoded 和 multipart/form-data的区别及用法
一、Form表单语法
在Form元素的语法中,EncType表明提交数据的格式。用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型。 例如:
- application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。
- multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分,这个一般文件上传时用。
- text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
二、常用的编码方式
form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。
1.x-www-form-urlencoded
当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url。
2.multipart/form-data
当action为post时候,浏览器把form数据封装到http body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。
但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。
每一段——WebKitFormBoundaryh2rFWhmmPZSuKvgf–为对应一部分消息
enctype=”multipart/form-data”是上传二进制数据;它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传输的都是大量的数据,所以规定上传文件必须是post方法,的type属性必须是file。form里面的input的值以2进制的方式传过去,所以request就得不到值了。传输到你的servlet里是二进制数据,包括那个title,所以你用request.getParameter(“title”)是得不到值的,必须把数据再换为String的。而struts2里就可以了,因为它自动给你转换了。
三、URLDecoder/URLEncoder 使用场景概述
URLDecoder 和 URLEncoder 用于完成普通字符串 和 application/x-www-form-urlencoded MIME 字符串之间的相互转换。在介绍 application/x-www-form-urlencoded MIME 字符串之前,我们先考虑如下场景,如下图所示:
我们知道,在我们向客户端发起请求时,浏览器会根据请求URL生成相应的请求报文发送给服务器。在这个过程中,如果我们在浏览器中的地址栏中所输入的URL包含中文字符时,浏览器首先会将这些中文字符进行编码然后再发送给服务器。实际上,浏览器会将它们转换为 application/x-www-form-urlencoded MIME 字符串,如下图所示:
更确切的,当URL地址里包含非西欧字符的字符串时,浏览器都会将这些非西欧字符串转换成application/x-www-form-urlencoded MIME 字符串。在开发过程中,我们可能涉及将普通字符串和这种特殊字符串的相关转换,这就需要使用 URLDecoder 和 URLEncoder类进行实现,其中:
URLDecoder类包含一个decode(String s,String enc)静态方法,它可以将application/x-www-form-urlencoded MIME字符串转成普通字符串;
URLEncoder类包含一个encode(String s,String enc)静态方法,它可以将普通字符串转换成application/x-www-form-urlencoded MIME字符串。
下面程序示范了普通字符串转与 application/x-www-form-urlencoded MIME 字符串之间的转化。
public class URLDecoderTest {
public static void main(String[] args) throws Exception {
// 将application/x-www-form-urlencoded字符串转换成普通字符串
// 其中的字符串直接从上图所示窗口复制过来,chrome 默认用 UTF-8 字符集进行编码,所以也应该用对应的字符集解码
System.out.println("采用UTF-8字符集进行解码:");
String keyWord = URLDecoder.decode("%E5%A4%A9%E6%B4%A5%E5%A4%A7%E5%AD%A6+Rico", "UTF-8");
System.out.println(keyWord);
System.out.println("\n 采用GBK字符集进行解码:");
System.out.println(URLDecoder.decode("%E5%A4%A9%E6%B4%A5%E5%A4%A7%E5%AD%A6+Rico", "GBK"));
// 将普通字符串转换成application/x-www-form-urlencoded字符串
System.out.println("\n 采用utf-8字符集:");
String urlStr = URLEncoder.encode("天津大学", "utf-8");
System.out.println(urlStr);
System.out.println("\n 采用GBK字符集:");
String urlStr2 = URLEncoder.encode("天津大学", "GBK");
System.out.println(urlStr2);
}
}/* Output:
采用UTF-8字符集进行解码:
天津大学 Rico
采用GBK字符集进行解码:
澶╂触澶у Rico
采用utf-8字符集:
%E5%A4%A9%E6%B4%A5%E5%A4%A7%E5%AD%A6
采用GBK字符集:
%CC%EC%BD%F2%B4%F3%D1%A7
*///:~
特别地,仅包含西欧字符的普通字符串和application/x-www-form-urlencoded MIME字符串无须转换,而包含中文字符的普通字符串则需要转换,转换的方法是每个中文字符占2个字节,每个字节可以转换成2个十六进制的数字,所以每个中文字符将转换成“%XX%XX”的形式。
当然,采用不同的字符集时,每个中文字符对应的字节数并不完全相同,所以使用URLEncoder和URLDecoder进行转换时也需要指定字符集。特别地,字符串应以同样的字符集进行编码和解码,否则会产生意想不到的结果,如上述程序示例所示。
引用:
使用 URLDecoder 和 URLEncoder 对中文字符进行编码和解码
关于Content-Type中application/x-www-form-urlencoded 和 multipart/form-data的区别及用法
下一篇: 表单同时提交多条记录的技术实现