项目场景:
今天帮助项目现场排查一个问题,之前应用通过定制,调用第三方接口结果返回正常,但是最近第三方代码进行重构后,接口的名称、请求参数、返回结果都没改变,而且使用curl、postman对接口进行调用,结果都是正常的,但是现场应用使用之前相同的参数却拿不到对的结果了,之前开发的同事离职了,这事就落在我身上了(微笑)。问题描述:
下面是同事之前的代码,整体代码没太大问题,可以看到这是一个Get请求,但是传参却像在使用post的方式,将参数放到HttpEntity的body中,乍一看没啥问题,但是这样发过去,第三方接口真的会解析你的参数吗?答案是 NO!!! public Map<String,Object> queryCamerasFromThirdPartyCamdos(String externalIndexCode){
//设置http的header
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//设置访问参数
HashMap<String, Object> params = new HashMap<>();
params.put("offset", 1);
params.put("limit", 1000);
params.put("externalIndexCode", externalIndexCode);
//设置访问的Entity
HttpEntity entity = new HttpEntity<>(params, headers);
ResponseEntity<String> result = null;
Map<String,Object> cameraCategory = new LinkedHashMap<>();
try {
//发起一个Get请求
logger.info("调用第三方请求参数externalIndexCode:" + externalIndexCode);
result = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
logger.info("调用第三方返回结果:" + result.getBody());
}catch(Exception e) {
logger.error("调用失败: " + e.getMessage());
}
原因分析:
使用exchange GET请求头部body携带json数据
①:当使用get请求需要携带 body中的参数的时候 需要重写Http 版本号必须是4.3以上
②:定义HttpGetRequestWithEntity实现HttpEntityEnclosingRequestBase抽象类,
以支持GET请求携带body数据
--转载自 https://blog.csdn.net/fenduo/article/details/109846438
解决方案:
从上述原因分析,我们可以看出,如果Get请求需要在body中携带json数据,不仅对版本号有要求,而且还要实现抽象类,简单的问题复杂化。我们常见的Get请求方式是怎么样呢?如下// Get请求样式
https://editor.csdn.net/md?not_checkout=1&articleId=121684233
是url的拼接了请求参数,这也是我们最常用的手段,因此对代码进行修改:
public Map<String,Object> queryCamerasFromThirdPartyCamdos(String externalIndexCode){
//设置http的header
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//设置访问参数
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("offset", "1");
params.add("limit", "1000");
params.add("SBBM", externalIndexCode);
//这里的作用就是将参数拼接到url后,只不过方式更加优雅
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
URI requestURL = builder.queryParams(params).build().encode().toUri();
//设置访问的Entity
HttpEntity entity = new HttpEntity<>(null, headers);
ResponseEntity<String> result = null;
Map<String,Object> cameraCategory = new LinkedHashMap<>();
try {
//发起一个Get请求
logger.info("调用第三方一机一档请求参数externalIndexCode:" + externalIndexCode);
result = restTemplate.exchange(requestURL, HttpMethod.GET, entity, String.class);
logger.info("调用第三方一机一档返回参数:" + result);
JSONArray datas = JSONObject.parseObject(result.getBody()).getJSONArray("CameraList");
测试通过,问题解决!