URL编码及Java发起URL请求的问题详解

前言
今天我们来讲一下URL编码(同时被称为Percent-encode,百分比编码)。虽然它相对简单,但是非常的重要,至于为什么,通过我后面的介绍也许你就会明白。 虽然叫做URLEncode,但是它普遍用于“统一资源标识符(URI)”中,熟悉HTTP协议的同学应该知道,URL是URI的一部分。同时,URL编码还被用在html页面的表单提交上,通常HTTP协议会先将表单数据进行编码,然后再执行POST或者GET请求。 实际上我们每天都能够看到URL编码和解码,可能你没有发现而已。最简单的一个例子,我们知道表单在传输数据的时候是采用键值对的方式,即key-value,拼装参数的时候就是key1=value1&key2=value2。**如果我们的key1=1&value(这是一个整体),然后key2=value2,如果不进行编码,传递的时候就成了key1=1&value&key2=value2,看到了吧,这就会造成语义上的歧义,我们在接收表单数据的时候就无法正常接收。**当然,作为普通用户来说,一般不会遇到这个问题,那是因为开发人员已经处理过了,但是我们就是这些开发人员,所以必须了解。 为了避免出现这种歧义,我们应该怎么做呢?
URL字符类型
我们在说解决方案之前,还是先来看看W3C是如何规定URL的格式的。 像“&”这种字符,在URL中被作为保留的编码,和java中的关键字保留是一样的,这些我们都是不能直接使用的,想要使用必须转义。这种保留符号还有很多,下表中列出的就是这些保留字符。

如果需要在值中用到这些保留字符,则需要将这些值进行百分转换,这也是百分比编码的由来。除去保留字符,还有空格字符也需要转义,转义后为“%20”。

当然,在一些特定的场合,比如后端需要解析前端经过编码后的值时,如果传递中文,就需要将中文编码。关于这一点,我会在代码中说明。
代码转义
首先,我们肯定不能在传值的时候去看转义后的字符,这简直太麻烦了,好在JDK给我们提供了一个URLEncoder类,让我们用来URL编码。 正常的后端代码是不会用到URL编码的,直接接收参数操作就好了,但是特殊的情况,如发起网络连接的时候,添加参数,就需要用到编码。多用于网络爬虫一类的应用程序(想起了当年用网络爬虫爬取内涵图的经历,但是那个网站做了反爬虫,现在没法用了。。)
最后,我给出一个URLConnection类,拼装参数,然后发起连接即可。
/**
* 发起url连接工具类
* @author 言立慧
* @date 2018/9/9 10:43
public class UrlConnectionUtil {
public static void getConnection(String domain, String lastUrl, HashMap<String, Object> params) {
StringBuffer bufferUrl = new StringBuffer();
// 拼装ip地址
bufferUrl.append(domain);
bufferUrl.append("/");
bufferUrl.append(lastUrl);
bufferUrl.append("?");
// 拼装各种参数,使用迭代器进行遍历
Iterator it = params.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = entry.getKey().toString();
String value = entry.getValue().toString();
bufferUrl.append(key);
bufferUrl.append("=");
// 如果需要对中文进行转义的话,只需要写成:
// bufferUrl.append(URLEncoder.encode(value,"UTF-8"));
bufferUrl.append(value);
bufferUrl.append("&");
bufferUrl.delete(bufferUrl.length() - 1, bufferUrl.length());
System.out.println(bufferUrl.toString());
// 尝试建立连接
try {
URL url = new URL(bufferUrl.toString());
//打开连接
URLConnection urlConnection = url.openConnection();
//发送连接请求
urlConnection.connect();
//获取服务器响应
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),
"utf-8"));
String lineData = bufferedReader.readLine();
System.out.println(lineData);
} catch (Exception e) {
e.printStackTrace();
public static void main(String[] args) {