之前http调用都是自己封装的HttpClients,比较麻烦。最近发现有新的API:RestTemplate可以直接调用接口,非常方便,省得自己封装请求了。
开始使用:
String url = targetInfoUrl +"?userId={userId}";
Map paramMap = new HashMap(1);
paramMap.put("userId",userId);
Response response = new RestTemplate().getForObject(url, Response.class, paramMap);
被请求接口的返回值是Response类,结构如下:
public class Response {
public String code;
public String msg;
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public T data;
}
其中data具体的值是一个List
public class MemberInfoAndTargetInfo {
private String userId;
/**
* 用户目标信息
*/
private List targetInfos;
}
我在获取到Response时,进行强制转换失败,编译不会报错,运行期报错
List data1 = (List) response.getData();
报错原因是Map不能被强制转换为List。这才发现自己忘记反序列化了,被getForObject方法:
@Override
@Nullable
public T getForObject(String url, Class responseType, Map uriVariables) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
的第二个参数迷惑了,自以为它会帮我反序列化。其实返回的是Response类型的json格式数据,需要我自己再反序列化。查看源码,这个responseType也仅表示类的名称等类型信息。于是自己就反序列化一下:
String stringObject = new RestTemplate().getForObject(url, String.class, paramMap);
Object data = JSONObject.parseObject(stringObject).get(ConstantConfig.DATA);
List targetInfos = JSONArray.parseArray(data.toString(), MemberInfoAndTargetInfo.class);
转化的过程,又发现MemberInfoAndTargetInfo类的属性有一个List
public void setTargetInfos(List targetInfos) {
this.targetInfos = targetInfos;
}
于是查看TargetInfoBean类,发现它少了一个无参的构造方法,补上后,成功。