解决java.util.LinkedHashMap cannot be cast to 实体类…的问题
背景描述
在学习谷粒商城时,使用openfeign进行远程调用,由于有个接口返回的是R<List<·Object>>类型的数据,在调用方使用List<·Object>去接收数据时,出现java.util.LinkedHashMap cannot be cast to xxx数据转换异常错误。可知远程调用会将待转换的数据转换成LinkedHashMap,而将其转换成想要的数据类型,肯定行不通。
解决办法一
使用alibaba提供的fastjson工具中的TypeReference,进行转换。
我们给R增加setData()和getData()方法,在获取data时,使用TypeReference类指明数据类型。然后将map转json字符串,在将json字符串转换成我们想要的数据类型。
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R setData(Object data){
put("data",data);
return this;
}
//利用fastjson进行逆转
public <T> T getData(TypeReference<T> typeReference){
Object data = get("data");//默认是map类型
if(Objects.isNull(data)){
return null;
}
String s = JSON.toJSONString(data);
T t = JSON.parseObject("",typeReference);
return t;
}
调用方
R r = wareFeignService.getSkusHasStock(skuIdList);//远程调用
TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {
};//声明内部类,指明类型
List<SkuHasStockVo> data = r.getData(typeReference);//获取远程调用的data数据
思考
这个问题在之前使用RestTemplate远程调用的时候也出现过,之前解决了这个问题,并没有记录下解决步骤,这次将解决步骤记录下来,防止下次踩坑。
补充解决办法二
最近在回顾之前项目代码的时候,发现了思考中提到的使用RestTemplate远程调用的时候出现的类似问题。当时的解决方案是这样。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
//远程调用,返回指定集合,但这个集合直接使用不了,因为他是一个LinkedHashMap。
List<InnerControl> remoteList = restTemplate.getForObject("url", List.class);
remoteList = transToList(remoteList);//转换之后,就能够正常使用这个集合了。
//定义一个方法,将LinkedHashMap类型转成我们想要的数据类型
private List<InnerControl> transToList(List<InnerControl> list){
String jsonStr = JSON.toJSONString(list);//依旧使用alibaba提供的json转换工具。
return JSONObject.parseArray(jsonStr, InnerControl.class);
}