Feign常见的坑总结

1.feign返回参数为map遇到的问题

spring cloud服务之间通过restApi相互调用的时候,如服务A调用服务B

         服务B的controller如下,返回一个Map,其中

userAllMessage.getPoints()的类型为Bigdecimal

@RequestMapping("/sec/getPoints")
public ResponseEntity< Map<String, Object>> getPoints() {
    Map<String, Object> map = new HashMap<>();
    UserAllMessage userAllMessage = userService.getUserById(RequestUtil.getUserId());
    if (userAllMessage != null) {
        map.put("state", 0);
        map.put("points", userAllMessage.getPoints());
    } else {
        map.put("state", 1);
    }
    return new ResponseEntity<>(map, HttpStatus.OK);
}

服务A的的Feign接收为

@FeignClient(name = "user-server")
@Component
public interface UserFeignServiceClient {
    @RequestMapping(value = "/api/user/sec/getPoints",method = RequestMethod.POST)
    Map<String, Object> getPoints();

}


调用该feignClient的代码为

Map<String, Object> map = userFeignServiceClient.getPoints();
Double points = (Double) map.get("points");

代码

Double points = (Double) map.get("points");
进行类型强转  会抛出类型转化异常:不能将Integer类型转化为double类型


解决办法:方法1,将服务B中points类型BigDicmal转化为Double类型

                    方法2,将服务B中返回类型map该为一个实体entity类型,该实体包含两个属性state和points(其中points类型为BigDicmal)

以上方法测试可用


2.feign传递参数遇到的问题

@RequestMapping(value = "/api/user/getInvitation",method = RequestMethod.GET)
 List<Invitation> getInvitation(@RequestParam Long id);


在以前spring使用中@RequestParam不需要指定value值,@RequestMapping也可以直接指定为PostMapping或者GetMapping,在feign中必须指定value值,必须通过method=RequestMethod.GET(POST)的方式进行指定,拥有多个参数的时候可以通过(@RequestParam("id")Long id,@RequestParam("userId")Long userId的形式调用

猜想:拥有多个参数为什么不通过map来调用呢,于是尝试Map调用   A服务为消费者    B服务为服务提供者

A 的部分代码

/**
 * 测试看看
 */
@RequestMapping("/test")
public Map<String, Object> test() throws Exception {
    Map<String,Object> map=new HashMap<>();
    map.put("test1",new Integer(2));
    map.put("test2",new Double(2));
    map.put("test3",new BigDecimal(2));
    workerFeignServiceClient.test(map);
    return map;
}

feign的部分代码

@FeignClient("worker-server")
public interface WorkerFeignServiceClient {
    @RequestMapping(value = "/api/worker/feign/test", method = RequestMethod.GET)
    Worker test(Map<String,Object> map);
}


B 的部分代码

@GetMapping("/test")
public ResponseEntity<Map> test(Map<String,Object> map) {
    int test1=(int) map.get("test1");
    int test2=(Integer) map.get("test1");
    double test5=(double) map.get("test2");
    Integer test6=(Integer)map.get("test3");
    double test3=(double) map.get("test3");
    Double test4=(Double) map.get("test3");
    return new ResponseEntity<>(map, HttpStatus.OK);
}
启动调用:报错了

Caused by: feign.FeignException: status 405 reading WorkerFeignServiceClient#test(Map); content:
{"timestamp":1506147245404,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/api/worker/feign/test"}

报错的意思是不支持GET提交,好的修改提交方式为POST

@FeignClient("worker-server")
public interface WorkerFeignServiceClient {
    @RequestMapping(value = "/api/worker/feign/test", method = RequestMethod.POST)
    Worker test(Map<String,Object> map);
}

@PostMapping("/test")
public ResponseEntity<Map> test(@RequestBody Map<String,Object> map) {
    int test1=(int) map.get("test1");
    int test2=(Integer) map.get("test1");
    double test5=(double) map.get("test2");
    Integer test6=(Integer)map.get("test3");
    double test3=(double) map.get("test3");
    Double test4=(Double) map.get("test3");
    return new ResponseEntity<>(map, HttpStatus.OK);
}


启动执行:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double,错误发生位置为

double test3=(double) map.get("test3");

Integer test6=(Integer)map.get("test3");
正确


将map的传入参数test2改为以下,其他位置不变

map.put("test2",new Double(2.6555));

启动执行:java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer,错误发生位置为

Integer test6=(Integer)map.get("test3");
从上可以看出当参数为BigDicmal时,存在不稳定性,最好不要传递BigDicmal,如果非要传,应该将BigDicmal放在一个entity对象里面传递,避免放在map里面




调用已经进入到B服务中,之所以出错


持续更新中


猜你喜欢

转载自blog.csdn.net/baidu_38116275/article/details/78066823