需求:最近接触的项目需要和另外的开发团队合作。这就导致了开发模式是调用他们的接口,从而获取数据。
作用:springBoot在这个方面已经为我们提供了一种比较方便的方式。那就是使用RestTemplate。
RestTemplate提供了多种访问Http服务的方式,其中最常用的就是Get请求,Post请求。
Post请求使用方式:代码如下
RestTemplate restTemplate = new RestTemplate();
String url = "http://113.207.68.117:9050/history/findByMap?startTime="+startTime+"&endTime="+endTime;
//1.设置请求头
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
//2.设置请求体的参数
JSONObject param = new JSONObject();
param.put("rtuName", rtuName);
param.put("devId",devId);
HttpEntity<String> formEntity = new HttpEntity<String>(param.toString(), headers);
try{
//3.获取接口的数据
ResponseEntity<Object> response = restTemplate.postForEntity( url, formEntity , Object.class );
Object body = response.getBody();
//4.使用实体封装数据
String s = JSON.toJSONString(body);
JSONArray jsonArray = JSONArray.parseArray(s);
List<HistoricalMonitoringDataDto> lists = jsonArray.toJavaList(HistoricalMonitoringDataDto.class);
return lists;
}catch (Exception e){
return null;
}
}
使用说明,分为3步:
首先这个是Post请求的接口。
第一步:需要设置请求头的内容,比如请求数据的格式为 “application/json; charset=UTF-8”。
第二步:如果该接口的请求体中需要的查询参数,比如根据某个属性模糊查询。那就需要在一步使用 JSONObject进行设置。
第三步:获取数据,这里用到了 postForEntity()。在Post请求中,有postForEntity()和getForObject()。
这两个的区别,个人理解就是内容详细与否。postForEntity不仅有业务的信息,还包含了很多response返回的信息。getForObject就直接把Http的业务信息直接转成POJO类 。例如:postForEntity( url, formEntity , “需要封装的实体类” );从而丢失了很多response的信息。这个看具体场景而运用。不过个人比较常用postForEntity。
第四步:信息的封装。例如:我获取到的信息格式是这样的,那封装的时候就需要一个DTO类,字段和这个字段一一对应。
[
{
"id": 1294220103537168385,
"devId": "2006010013", //设备id
"location": null, //安装地址
"devGroup": "井盖位移监测终端", //设备类型(采集组)
"devVersion": "V4.0", //设备版本
"softVersion": "V4.0", //软件版本
"energy": 93, //电量
"rtuSignal": 77, //信号
"tem": 21, //温度
"lng": null, //经度
"lat": null, //纬度
"altitude": null //高程
}
...
{}
]
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GeneralDeviceDto {
private Double id;
private String devId;
private String location;
private String devGroup;
private String devVersion;
private String softVersion;
private Double energy;
private Double rtuSignal;
private Double tem;
private Double xaxis;
private Double yaxis;
private Double zaxis;
private Integer isAlarm;
}
到此为止,就可以获取到第三方接口的数据。后续如何使用这些数据看业务需求。
Post请求遇到的一个小坑:请求头设置查询条件的方式。
这种请求头设置方式,虽然接口能够调用成功,但获取不到数据。具体原因尚未知。
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_UTF8_VALUE));
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.put("devGroup", devGroup);
map.put("devId",devId);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
改成方式二:完美解决。
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
JSONObject param = new JSONObject();
param.put("devGroup", devGroup);
param.put("devId",devId);
HttpEntity<String> formEntity = new HttpEntity<String>(param.toString(), headers);
Get请求使用方式:代码如下
public List<MDDataDto> acceptMDData(String devID, String startTime, String endTime) {
//1.查询参数封装
List<MDDataDto> mdDataList = new ArrayList<>();
RestTemplate restTemplate = new RestTemplate();
Map<String,Object> map = new HashMap<>();
map.put("devId",devID);
map.put("startTime",startTime);
map.put("endTime",endTime);
String url = "http://113.207.68.117:9050/history/listByDevIdByTimes?devId={devId}" +
"&startTime={startTime}&endTime={endTime}";
try {
//2.获取接口数据
Object forObject = restTemplate.getForObject(url, Object.class, map);
//3.数据封装
String s = JSON.toJSONString(forObject);
JSONArray jsonArray = JSONArray.parseArray(s);
MDDataDto mdData = new MDDataDto();
for (int i=0 ; i<jsonArray.size() ; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
DevDto devDto = jsonObject.getObject("devDto", DevDto.class);
JSONArray datas1 = jsonObject.getJSONArray("datas");
List<ChannelDto> datasList = datas1.toJavaList(ChannelDto.class);
mdData.setDev(devDto);
mdData.setDatas(datasList);
mdDataList.add(mdData);
}
return mdDataList;
}catch (Exception e){
return null;
}
}
使用说明:Get请求其实比Post请求要简单的多。这个代码多的原因是数据封装稍微复杂的原因。我简要说一下
Get请求不需要关注请求头,
第一步:如果有查询参数的话,那就使用 Map<String,Object> map = new HashMap<>();
第二步:后续将这个map加入 restTemplate.getForObject(url, Object.class, map);中,这个需要注意的是map的key值要和url中参数一致,例如:devId={devId} &startTime={startTime}&endTime={endTime}**