示例代码如下:
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());
}
在请求得url中含有字符#,请求到服务器时被转为search=;也就拿不到后面得参数值了。
问题出现的原因,查看 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);
}
修改后的代码:
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());
}
总结:
网络传输需要进行网络编码,网络编码可以使用如下API:
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);