什么是URL转码
不管是以何种方式传递url时,如果要传递的url中包含特殊字符,如想要传递一个+,但是这个+会被url会被编码成空格,想要传递&,被url处理成分隔符。
尤其是当传递的url是经过Base64加密或者RSA加密后的,存在特殊字符时,这里的特殊字符一旦被url处理,就不是原先你加密的结果了。
url特殊符号及对应的编码:
符号 | url中的含义 | 编码 |
+ | URL 中+号表示空格 | %2B |
空格 | URL中的空格可以用+号或者编码 | %20 |
/ | 分隔目录和子目录 | %2F |
?
| 分隔实际的URL和参数 | %3F |
% | 指定特殊字符 | %25 |
# | 表示书签 | %23 |
& | URL中指定的参数间的分隔符 | %26 |
= | URL中指定参数的值 | %3D |
package com.learn.utils;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
/**
* HttpClient4.3工具类
*/
public class HttpClientUtils {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录
private static RequestConfig requestConfig = null;
static {
// 设置请求和传输超时时间
requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
}
/**
* post请求传输json参数
*
* @param url
* url地址
* @param json
* 参数
* @return
*/
public static JSONObject httpPost(String url, JSONObject jsonParam) {
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
// 设置请求和传输超时时间
httpPost.setConfig(requestConfig);
try {
if (null != jsonParam) {
// 解决中文乱码问题
StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
try {
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
} catch (Exception e) {
logger.error("post请求提交失败:" + url, e);
}
}
} catch (IOException e) {
logger.error("post请求提交失败:" + url, e);
} finally {
httpPost.releaseConnection();
}
return jsonResult;
}
/**
* post请求传输String参数 例如:name=Jack&sex=1&type=2
* Content-type:application/x-www-form-urlencoded
*
* @param url
* url地址
* @param strParam
* 参数
* @return
*/
public static JSONObject httpPost(String url, String strParam) {
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
try {
if (null != strParam) {
// 解决中文乱码问题
StringEntity entity = new StringEntity(strParam, "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
try {
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
} catch (Exception e) {
logger.error("post请求提交失败:" + url, e);
}
}
} catch (IOException e) {
logger.error("post请求提交失败:" + url, e);
} finally {
httpPost.releaseConnection();
}
return jsonResult;
}
/**
* 发送get请求
*
* @param url
* 路径
* @return
*/
public static JSONObject httpGet(String url) {
HttpHost proxy = new HttpHost("localhost", 8888);
RequestConfig config = RequestConfig.custom().setProxy(proxy).setConnectTimeout(10000).setSocketTimeout(15000)
.build();
CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
// get请求返回结果
JSONObject jsonResult = null;
// 发送get请求
HttpGet request = new HttpGet(url);
request.setConfig(requestConfig);
try {
CloseableHttpResponse response = client.execute(request);
// 请求发送成功,并得到响应
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 读取服务器返回过来的json字符串数据
HttpEntity entity = response.getEntity();
String strResult = EntityUtils.toString(entity, "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(strResult);
} else {
logger.error("get请求提交失败:" + url);
}
} catch (IOException e) {
logger.error("get请求提交失败:" + url, e);
} finally {
request.releaseConnection();
}
return jsonResult;
}
}
package learn_b;
import java.net.URLDecoder;
import java.net.URLEncoder;
import com.alibaba.fastjson.JSONObject;
import com.learn.utils.HttpClientUtils;
public class Test001 {
public static void main(String[] args) {
// Java 提供Http协议 特殊字符转码类
String encode = URLEncoder.encode("1+1");
System.out.println("encode:" + encode);
System.out.println("decode:" + URLDecoder.decode(encode));
String userNameUrl = "http://127.0.0.1:8080/indexPage?userName=" + URLEncoder.encode("1+1");
JSONObject result = HttpClientUtils.httpGet(userNameUrl);
System.out.println("result:" + result);
// 注意事项 不要整个URL进行编码,只是针对于参数编码
}
}
package com.learn.api.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.learn.base.BaseApiService;
import com.learn.base.ResponseBase;
// http协议特殊字符处理
@RestController
public class IndexController extends BaseApiService {
// 1. 什么是特殊字符处理(rpc远程通讯 实现加密 + ?) 正好和http特殊相同,导致会转成空格
// 2. 注意事项
@RequestMapping("/indexPage")
public ResponseBase indexPage(String userName) {
System.out.println("userName:" + userName);
return setResultSuccessData(userName);
}
}