需求:最近接触的项目需要和另外的开发团队合作。这就导致了开发模式是调用他们的接口,从而获取数据。

作用: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}**