1、当使用 GET 请求时,如果URL中的参数有特殊字符,比如 '#' ,就会导致查询错误。
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
String url = "http://localhost:8180/workbench/questionBank/paper?search=#&query=123";
HttpEntity<?> entity = new HttpEntity<>(headers);
HttpEntity<String> response = restTemplate.exchange(url,HttpMethod.GET,entity,String.class);
System.out.println(response.getBody());
}
2、本来请求中是有参数 search 和 query ,就因为 search 中使用了特殊字符 # , 然而在服务端获取参数时得到的参数只有 search = ;

3、问题出现的原因,查看 RestTemplate 的源码如下
@Override
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {
// 这里进行网络转码,因为我们传递的URL是字符串,最后都要统一转为URL,而且对于字符都应该进行网络编码,
// 问题就出现在这里,我们如果自己手动把参数进行网络编码,那么问题就不会出现
URI expanded = getUriTemplateHandler().expand(url, urlVariables);
return doExecute(expanded, method, requestCallback, responseExtractor);
}
4、解决方案
- 第一种
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
String url = "http://localhost:8180/workbench/questionBank/paper?search=#&query=123";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
URI uri = builder.build().encode().toUri();
HttpEntity<?> entity = new HttpEntity<>(headers);
HttpEntity<String> response = restTemplate.exchange( uri, HttpMethod.GET, entity, String.class);
System.out.println(response.getBody());
}
- 第二种
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("msisdn", msisdn)
.queryParam("email", email)
.queryParam("clientVersion", clientVersion)
.queryParam("clientType", clientType)
.queryParam("issuerName", issuerName)
.queryParam("applicationName", applicationName);
HttpEntity<?> entity = new HttpEntity<>(headers);
HttpEntity<String> response = restTemplate.exchange(
builder.build().encode().toUri(),
HttpMethod.GET,
entity,
String.class);
网友评论