問(wèn)題:為啥調(diào)用rpc遠(yuǎn)程服務(wù)后,返回的響應(yīng)類的結(jié)果無(wú)法向下轉(zhuǎn)型?具體報(bào)錯(cuò)
java.util.LinkedHashMap cannot be cast to com.huibo.framework.domain.ucenter.ext.AdminLite
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.huibo.framework.domain.ucenter.ext.AdminLite
有博主說(shuō)關(guān)于springcloud中使用feign出現(xiàn)LinkedHashMap can not be cast to xxx 的問(wèn)題是因?yàn)椋篺eign默認(rèn)是根據(jù)返回的數(shù)據(jù)解析為L(zhǎng)inkedHashMap這種key value的格式,但是我們項(xiàng)目中一般會(huì)有自定義的Result<T,E>這樣的復(fù)雜類型的對(duì)象,這樣的話,feign就不能像dubbo這樣的rpc那樣得到我們自己想要的Result<T,E>對(duì)象。
解決用 自定義FeignClient,覆蓋提供的FeignClient。我覺(jué)得不一定有用,但是用使用fastjson將對(duì)象和字符串進(jìn)行轉(zhuǎn)換就可以恢復(fù)原樣,不過(guò)太消耗性能。
@Configuration
public class FeignConfig {
@Bean
public Decoder feignDecoder() {
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(objectMapper());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
@Bean
public Encoder feignEncoder(){
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(objectMapper());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new SpringEncoder(objectFactory);
}
public ObjectMapper objectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
return objectMapper;
}
}
// 將對(duì)象轉(zhuǎn)換成為字符串
String str = JSON.toJSONString(infoDo);
// 將字符串轉(zhuǎn)換成為對(duì)象
InfoDo infoDo = JSON.parseObject(strInfoDo, InfoDo.class);
// 將對(duì)象集合轉(zhuǎn)換成為字符串
String users = JSON.toJSONString(users);
//將字符串轉(zhuǎn)換成為對(duì)象集合
List<User> userList = JSON.parseArray(userStr, User.class);
都說(shuō)是feign的問(wèn)題,但是SpringCloud 復(fù)雜對(duì)象接收時(shí)候?qū)ο笞兂蒐inkeHashMap。通過(guò)使用泛型參數(shù),實(shí)際類型信息完全丟失到運(yùn)行時(shí)并且無(wú)法推斷。它本質(zhì)上最終是相同的
Object。當(dāng)Gson發(fā)現(xiàn)你想要一個(gè)Object類型時(shí),它使用aMap來(lái)放置JSON信息。這樣,如果你重新序列化該對(duì)象實(shí)例,數(shù)據(jù)將被保留。所以在定義接口的時(shí)候返回的泛型必須確定。其中BaseResult的范性應(yīng)該為L(zhǎng)ist<UserVO> ,如果沒(méi)有寫,那么返回的結(jié)果就會(huì)變成List<LinkedHashMap>,這樣就導(dǎo)致一些去參數(shù)錯(cuò)誤。
// 錯(cuò)誤實(shí)例
@PostMapping("/user/queryUserByAccountStatus")
BaseResult queryUserByAccountStatus(@RequestBody AccountsTenantIdStatusArg arg);
// 正確實(shí)例
@PostMapping("/user/queryUserByAccountStatus")
BaseResult<List<UserVO>> queryUserByAccountStatus(@RequestBody AccountsTenantIdStatusArg arg);