使用RestTemplate进行http调用格式转换问题

之前http调用都是自己封装的HttpClients,比较麻烦。最近发现有新的API:RestTemplate可以直接调用接口,非常方便,省得自己封装请求了。

开始使用:

String url = targetInfoUrl +"?userId={userId}";
Map<String,Object> paramMap = new HashMap(1);
paramMap.put("userId",userId);
Response response = new RestTemplate().getForObject(url, Response.class, paramMap);

被请求接口的返回值是Response类,结构如下:

public class Response<T> {

    public String code;

    public String msg;

    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    public T data;
}

其中data具体的值是一个List<MemberInfoAndTargetInfo>。这个MemberInfoAndTargetInfo类的属性又有一个List<TargetInfoBean>

public class MemberInfoAndTargetInfo {

    private String userId;

    /**
     * 用户目标信息
     */
    private List<TargetInfoBean> targetInfos;
}

我在获取到Response时,进行强制转换失败,编译不会报错,运行期报错

List<MemberInfoAndTargetInfo> data1 = (List<MemberInfoAndTargetInfo>) response.getData();

报错原因是Map不能被强制转换为List。这才发现自己忘记反序列化了,被getForObject方法:

	@Override
	@Nullable
	public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
		RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
		HttpMessageConverterExtractor<T> 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<MemberInfoAndTargetInfo> targetInfos = JSONArray.parseArray(data.toString(), MemberInfoAndTargetInfo.class);

转化的过程,又发现MemberInfoAndTargetInfo类的属性有一个List<TargetInfoBean>无法反序列化,报错说缺少构造方法。我查看代码,发现MemberInfoAndTargetInfo类有方法:

public void setTargetInfos(List<TargetInfoBean> targetInfos) {
    this.targetInfos = targetInfos;
}

于是查看TargetInfoBean类,发现它少了一个无参的构造方法,补上后,成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章