1.参数类型是 MultiValueMap
@RestController
public class HelloWorldController {
@RequestMapping(path = "hi", method = RequestMethod.POST)
public String hi(@RequestParam("para1") String para1, @RequestParam("para2") String para2){
return "helloworld:" + para1 + "," + para2;
};
}
RestTemplate template = new RestTemplate();
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("para1", "001");
paramMap.put("para2", "002");
String url = "http://localhost:8080/hi";
String result = template.postForObject(url, paramMap, String.class);
System.out.println(result);
测试后你会发现事与愿违,返回提示 400 错误
- 实际上,只有当我们发送的 Body 是 MultiValueMap 才能使用表单来提交
- 定义的就是普通的 HashMap,最终是按请求 Body 的方式发送出去的。(json)
//错误:
//Map<String, Object> paramMap = new HashMap<String, Object>();
//paramMap.put("para1", "001");
//paramMap.put("para2", "002");
//修正代码:
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
paramMap.add("para1", "001");
paramMap.add("para2", "002");
2.当 URL 中含有特殊字符
String url = "http://localhost:8080/hi?para1=1#2";
HttpEntity<?> entity = new HttpEntity<>(null);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET,entity,String.class);
System.out.println(response.getBody());
服务器并不认为 #2 是 para1 的内容;para1 丢掉的 #2 实际是以 Fragment 的方式被记录下来了
URL 的格式定义:
protocol://hostname[:port]/path/[?query]#fragment
- Query(查询参数):页面加载请求数据时需要的参数,用 & 符号隔开,每个参数的名和值用 = 符号隔开
- Fragment(锚点):#开始,字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用 Fragment 直接定位到某一名词的解释。例如定位网页滚动的位置,可以参考下面一些使用示例:https://github.com/alu4r/flink-demo/blob/master/pom.xml#L10
修正:
String url = "http://localhost:8080/hi?para1=1#2";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
URI uri = builder.build().encode().toUri();
HttpEntity<?> entity = new HttpEntity<>(null);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET,entity,String.class);
System.out.println(response.getBody());
3.小心多次 URL Encoder
@RestController
public class HelloWorldController {
@RequestMapping(path = "hi", method = RequestMethod.GET)
public String hi(@RequestParam("para1") String para1){
return "helloworld:" + para1;
};
}
RestTemplate restTemplate = new RestTemplate();
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/hi");
builder.queryParam("para1", "开发测试 001");
String url = builder.toUriString();
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
System.out.println(forEntity.getBody());
// 响应
helloworld:%E5%BC%80%E5%8F%91%E6%B5%8B%E8%AF%95001
以上代码:builder.toUriString();restTemplate.getForEntity都进行了一次编码
修正:
RestTemplate restTemplate = new RestTemplate();
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/hi");
builder.queryParam("para1", "开发测试 001");
URI url = builder.encode().build().toUri();
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
System.out.println(forEntity.getBody());