九、声明式 REST 客户端-Feign 的各种调用

来源:互联网 发布:2017手机淘宝修改差评 编辑:程序博客网 时间:2024/06/08 05:37

一、 让调用更轻松
基于 Feign 的特性,我们为每个微服务创建一个新的 API 工程,然后利用 maven 引入该 API 工程,这样调用者就无需关心实际的 REST 接口,就和调本地方法一样调用远程服务。

改造步骤:
1、 新建 Bean 工程,加入 User 实体类
2、 新建 Api 工程,加入 IuserBiz 接口类,利用 maven 引用 Bean 工程 3、 提供者工程删除 User 实体类,利用 maven 引用 Bean 工程
4、 消费者删除 IuserBiz 接口类,利用 maven 应用 Api 工程

说明:
1、 API 工程中,一般要依赖于相关的 bean 类(实体类),可以把 bean 放入到 API 工程,也可以把 bean 独立一个工程,利用 maven 再引入该工程。
2、 要让Spring 扫描到@FeignClient 注解,可以设置:
@EnableFeignClients(basePackages = “包名”) 。

二、 姿势说明
1、 关于@PathVariable
说明:使用@PathVariable 注解的时候,必须要定义里面的 value 或者 name
比如:@PathVariable(value = “id”)或者@PathVariable(name = “id”)

@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) String view1(@PathVariable(name = "id") int id);

2、 返回类型
说明:可以有多种返回形式

@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) Map<String, Object> view2(@PathVariable(value = "id") int id); @RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) User view3(@PathVariable(value = "id") int id); 

3、 传参的问题-没有加@RequestParam 注解的情况下
说明:请求类型将变为 post(即使指定为 get,也变为 post),将通过 Jackson 转换成 json 放到请求体中,这时候只能存在一个没有带注解的参数

@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) User get1(@PathVariable(value = "id") int id, String name); @RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) User get2(@PathVariable(value = "id") int id, Map<String, Object> name);

4、 传参的问题-有@RequestParam 注解的情况下
说明:不指定的 value 的情况下:必须是 Map 的形式,会将其参数转换成键值的形式添加到 URL 中 ,指定 value 的情况下:按照 value 传值

// 不支持该方式传值,启动出错。 //@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) //User get3(@PathVariable(value = "id") int id, @RequestParam String name); @RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) User get4(@PathVariable(value = "id") int id, @RequestParam Map<String, Object> name); @RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) User get5(@PathVariable(value = "id") int id, @RequestParam(value = "name") String name); 

5、 关于复合注解
说明:@ GetMapping,@PostMapping 等在 spring-cloud-netflix-1.3.0.M1 之前是不支持的,现在支持。 出错提示:Caused by: java.lang.IllegalStateException: Method view1 not annotated with HTTP method type (ex. GET, POST)
https://github.com/spring-cloud/spring-cloud-netflix/issues/1201

@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) String view1(@PathVariable(name = "id") int id); 

说明:method 需要指定

@GetMapping(value = "/api/user/{id}") String view1(@PathVariable(name = "id") int id); 

测试代码:

@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)    public User get(@PathVariable int id, @RequestBody(required = false) String json, @RequestParam(required = false) String name, HttpServletRequest request) {        logger.info("请求方法类型:" + request.getMethod() + " RequestBody参数:" + json + " RequestParam参数:" + name);        User user = new User();        user.setId(id);        user.setName("无境");        user.setCreateTime(new Date());        return user;    }