出场演员
前端A
后端B
后端C
Java项目是spring boot的controller,service,dao三层架构。
最近开发了一个需求,其中有个子功能的实现需要我的后端B接收到前端A发来的get请求,这个get请求有query参数(形如: http://url?param1=value1)。再从后端B发出一个get请求携带query参数去后端C请求数据。
在实现上述子功能的过程中出现了get请求query参数加不上去的问题。
出现问题的过程:
在后端B中的controller层解析了param1,并创建
HashMap<String, String> paramMap = new HashMap<>();
paramMap.put(“param1”, value1);
将paramMap传递到controller,再传递到dao中,在dao层调用restTemplate.exchange()发送请求。
最开始的时候查到RestTemplate中的这个方法 (重载方法1)
Public ResponseEntity exchange(String url, HttpMethod method, @Nullable HttpEntity requestEntity, Class responseType, Map uriVariables) {}
调用了restTemplate.exchange(url, HttpMethod.GET, req, String.class, paramMap);来向后端C请求数据,结果一直报错,返回参数异常。排查下来发现,就是query没带上(预期http://urlToC?param1=value1,实际上只发出去http://urlToC )
继续往后排查
尝试直接用字符串拼接的方式将query拼接到url的后面,然后调用另外一个exchange的重载方法 (重载方法2),restTemplate.exchange(url, HttpMethod.GET, req, String.class);
也就是说发送get请求,这个过程本身没有问题,问题出在重载方法1中query参数没有成功拼接到url之后。
再往后查,发现重载方法1需要配合模板来使用。
public static void main(String[] args) {
// 创建RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
// 设置请求的带参URL模板
String url = "https://api.example.com/data?param1={param1}¶m2={param2}";
// 设置查询参数
Map<String, String> params = new HashMap<>();
params.put("param1", "value1");
params.put("param2", "value2");
// 发送GET请求
ResponseEntity<String> responseEntity = restTemplate.exchange(
url,
HttpMethod.GET,
null,
String.class,
params
);
// 处理响应
String responseBody = responseEntity.getBody();
System.out.println(responseBody);
}
这个方法并不通用(它只能用在params key确定的场景)
对一个params不确定的场景,应该用UriComponentsBuilder来处理query的拼接
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.queryParam(entry.getKey(), entry.getValue());
}
String urlWithParams = builder.toUriString();
得到urlWithParams之后,通过重载方法2发送get请求。
完结。
同步更新到自己的语雀
https://www.yuque.com/dirackeeko/wxkg90/gro46ro52bt3qvb3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。