RestTemplate请求url中包含特殊字符被转义问题,RestTemplate发送请求带有特殊字符,RestTemplate发送请求的坑

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

问题一请求url中包含%被转义为%25

resteTemplate中url如果带%被被转义成%25无法正确的访问资源

例如: http://localhost:8080/aa?param=sdlfjdl&name=%123
会被转为http://localhost:8080/aa?param=sdlfjdl&name=%25123

问题代码

String url = "http://localhost:8080/aa?param=sdlfjdl&name=%123";
try{
    restTemplate.getForEntity(url, String.class);
}catch (Exception e){

}

问题原因
restTemplate的exchange方法若参数url是String类型在发送请求之前会先将String类型的url转为URI类型的url在这个过程中会对url进行转义如下面的restTemplate的源码中的方法

@Nullable
public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Map<String, ?> uriVariables) throws RestClientException {
    URI expanded = this.getUriTemplateHandler().expand(url, uriVariables);
    return this.doExecute(expanded, method, requestCallback, responseExtractor);
}

因此这里直接采用restTemplate传参为URI的方法将url的字符串编码转成URI就可以了

@Nullable
public <T> T execute(URI url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
   return this.doExecute(url, method, requestCallback, responseExtractor);
}

问题解决
注意若get请求参数中包含特殊字符&则下面的这个解决方法还是有问题的要想解决请求参数包含&可以参考下面问题二中的解决方法

String url = "http://localhost:8080/aa?param=sdlfjdl&name=%123";
try{
	URI uri = URI.create(url);
    restTemplate.getForEntity(uri, String.class);
}catch (Exception e){

}

问题二RestTemplate发送get请求请求参数中包含特殊字符&

解决方法

所有发送get请求请求中包含特殊字符如% & + = 空格 等都可以使用以下解决方法目前没发现异常

public String get(String url, List<NameValuePair> params, List<NameValuePair> headerParams){
	String response = "";
	log.info("请求地址{}请求头参数{}请求参数{}",url,headerParams,params);
	try {
		HttpHeaders headers = new HttpHeaders();
		if(!CollectionUtils.isEmpty(headerParams)){
			headerParams.forEach(p ->
					headers.add(p.getName(),p.getValue())
			);
		}
		HttpEntity<String> httpEntity = new HttpEntity<>(null,headers);
		URI uri = URI.create(url);
		if(!CollectionUtils.isEmpty(params)){
			String param = URLEncodedUtils.format(params, StandardCharsets.UTF_8);
			uri = URI.create(url+"?"+param);
		}
		//url中若带了参数不要使用String url的方式传入里面的+ = % &等符号会被转义或替换掉所以传入URI对象
		response = restTemplate.exchange(uri, HttpMethod.GET, httpEntity , String.class).getBody();
	}catch (Exception e){
		log.error("请求:"+url+"时发生未知异常"+e.getMessage(),e);
	}
	return response;
}

调用

List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("name", "tom"));
params.add(new BasicNameValuePair("age", "&%24"));

String response = get("http://localhost/8080/aa",params,null);

URL中的特殊字符

有些符号在URL中是不能直接传递的如果要在URL中传递这些特殊符号那么就要使用他们的编码了。编码的格式为%加字符的ASCII码即一个百分号%后面跟对应字符的ASCII16进制码值。对于ASCII码不了解的同学可以参考ASCII码 http://c.biancheng.net/c/ascii/例如 空格的编码值是"%20"。

下表中列出了一些URL特殊符号及编码

符号含义转义后
+URL 中+号表示空格%2B
空格URL中的空格可以用+号或者编码%20
/分隔目录和子目录%2F
?分隔实际的URL和参数%3F
%指定特殊字符%25
#表示书签%23
&URL 中指定的参数间的分隔符%26
=URL 中指定参数的值%3D
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

“RestTemplate请求url中包含特殊字符被转义问题,RestTemplate发送请求带有特殊字符,RestTemplate发送请求的坑” 的相关文章