SpringCloud版本:Hoxton.SR11
SpringBoot版本:2.3.10.RELEASE
原来的feign调用接口
@FeignClient(name = "microservice-user")
public interface UserFeignClient {
@RequestMapping(value = "/user/user", method = RequestMethod.GET)
public List finsdById();
}
调用地方的使用:
public class HotelServiceImpl implements HotelService {
@Autowired
private UserFeignClient userFeignClient;
@Override
public List selectUserLimit(int limitSize) {
List<UserBO>userBOList = userFeignClient.finsdById();
userBOList.stream().filter(userBO -> userBO.getAid() >10).collect(Collectors.toList());
return userBOList;
}
}
报错:
2021-06-17 17:33:41.391 ERROR 15700 --- [nio-8010-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.louyafeng.cloud.study.bo.UserBO] with root cause
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.louyafeng.cloud.study.bo.UserBO
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174) ~[na:1.8.0_221]
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[na:1.8.0_221]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_221]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_221]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_221]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_221]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_221]
at com.louyafeng.cloud.study.service.impl.HotelServiceImpl.selectUserLimit(HotelServiceImpl.java:36) ~[classes/:na]
at com.louyafeng.cloud.study.controller.HotelController.selectUserLimit(HotelController.java:29) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
.......
........
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.45.jar:9.0.45]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]
看报错日志可知,类型转换失败。java.util.LinkedHashMap cannot be cast to bean;
查看数据类型:
这里很奇怪,我调用方,和被调用方都是用的一个bean,而且返回的是list,怎么会出现了LinkedHashMap,然后转换失败呢。查询资料得知:
原因:
因为rpc远程调用在底层还是使用的HTTPClient,所以在传递参数的时候,必定要有个顺序,当你传递集合(list/map)的时候集合里面的值也要有顺序,不然服务层在接的时候就出问题了,所以它才会从list转为linkedhashMap!
然后就在网上找办法,大部分可以分为三种方式:
1.用先转换为json然后再转换为自己的bean类型,
2.调用端ModelMap接收。
3.被调用端,使用泛型返回,然后调用端,用实体类转换。
这里我看到第三个的时候,想了想,我这里被调用端不用泛型返回,只在调用端,用实体类类型接收,feign是不是可以帮我自动转换类型。
然后就尝试了一下,发现是可以的!!!
改动如下:只改动feign接口处即可:
@FeignClient(name = "microservice-user")
public interface UserFeignClient {
@RequestMapping(value = "/user/user", method = RequestMethod.GET)
public List<UserBO> finsdById(); //只需要在这里list这里指定你需要转换的bean
}
再次调用:
转换成功!