RestTemplate/httpclient请求:请求参数中的特殊字符处理
特殊url:
url中有:SuperPNR_ID%3D202006151522247812 (%3D)
url中有:|(竖线)
http://119.254.234.92:9280/easypay/mobilepay.servlet?OrderAmount=1090&AppType=B2C&BankId=TENPAYGW_MINIPROGRAM&BillNo=2020061500011970&Ext1=10.221.150.211&Ext2=&Lan=CN&Msg=SuperPNR_ID%3D202006151522247812&OrderCurtype=CNY&OrderNo=202006151522389979&OrderType=1|0|&OrgId=XZAIRB2C&OrderDate=20200615&OrderTime=152228&ordername=Xizang+Airlines+e-ticket&Orderinfo=&usrid=o_57z5FJx1rlTpMSzsgsdeiEvKxc&username=&gateid=TENPAYGW_MINIPROGRAM&Version=1.0&ReturnId=id_pay_1000&SIGNATURE=f16fa3e8a299c44ebe41a0c3ea678bf6
请注意url中有%3D,还有|中竖线。
RestTemplate
在使用restTemplate请求时,会对%3D进行转义,
通过UriComponentsBuilder创建URI对象,这样RestTemplate不会自动进行urlencode
// 通过UriComponentsBuilder创建URI对象,这样RestTemplate不会自动进行urlencode UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(requestUrl); 或者 UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(requestUrl); URI uri = uriComponentsBuilder.build(true).toUri();
但同时存在另一个问题,参数中有“|”,竖线,请求失败,直接报错:
java.lang.IllegalArgumentException: Invalid uri 'http://xxxxxx' : Invalid query 异常通过URLEncoder来解决。
这是需要对含有“|”竖线的,参数进行单独转码:
URLEncoder.encode("|","utf-8");
HttpClient
一样的情况,碰到参数“|”,也是会报错(虽然%3D不会被转义了)。
我们需要些个类来处理url中的参数,对"|",进行转码
public class UrlUtils {
public static class UrlEntity {
/**
* 基础url
*/
public String baseUrl;
/**
* url参数
*/
public Map<String, String> params;
}
/**
* 解析url
*
* @param url
* @return
*/
public static UrlEntity parse(String url) {
UrlEntity entity = new UrlEntity();
if (url == null) {
return entity;
}
url = url.trim();
if (url.equals("")) {
return entity;
}
String[] urlParts = url.split("\?");
entity.baseUrl = urlParts[0];
//没有参数
if (urlParts.length == 1) {
return entity;
}
//有参数
String[] params = urlParts[1].split("&");
entity.params = new HashMap();
for (String param : params) {
String[] keyValue = param.split("=");
System.out.println(JSON.toJSONString(keyValue));
if(keyValue.length==1){
entity.params.put(keyValue[0], "");
continue;
}
if(keyValue[1].contains("|")){
try {
keyValue[1] = URLEncoder.encode(keyValue[1],"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
entity.params.put(keyValue[0], keyValue[1]);
}
return entity;
}
public static String getUrl(String url){
UrlEntity params = parse(url);
String baseUrl = params.baseUrl;
StringBuffer strtTotalURL = new StringBuffer();
if(params.params!=null){
for (Map.Entry<String, String> m:params.params.entrySet()){
String temp = null;
if(m.getValue().contains("|")){
try {
temp = m.getKey() + "=" + URLEncoder.encode(m.getValue(),"utf-8") + "&";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}else{
temp = m.getKey() + "=" + m.getValue() + "&";
}
strtTotalURL.append(temp);
}
}
return baseUrl + "?" + strtTotalURL.toString();
}
public void main(String[] args){
String url = "http:\/\/119.254.234.92:9280\/easypay\/mobilepay.servlet?OrderAmount=1090&AppType=B2C&BankId=TENPAYGW_MINIPROGRAM&BillNo=2020061500011970&Ext1=10.221.150.211&Ext2=&Lan=CN&Msg=SuperPNR_ID%3D202006151522247812&OrderCurtype=CNY&OrderNo=202006151522389979&OrderType=1|0|&OrgId=XZAIRB2C&OrderDate=20200615&OrderTime=152228&ordername=Xizang+Airlines+e-ticket&Orderinfo=&usrid=o_57z5FJx1rlTpMSzsgsdeiEvKxc&username=&gateid=TENPAYGW_MINIPROGRAM&Version=1.0&ReturnId=id_pay_1000&SIGNATURE=f16fa3e8a299c44ebe41a0c3ea678bf6";
System.out.println(getUrl(url));