- 推荐序一
- 推荐序二
- 推荐序三
- 推荐语
- 前言
- 第1章 基础知识
- 第2章 微服务构建:Spring Boot
- 第3章 服务治理:Spring Cloud Eureka
- 第4章 客户端负载均衡:Spring Cloud Ribbon
- 第5章 服务容错保护:Spring Cloud Hystrix
- 第6章 声明式服务调用:Spring Cloud Feign
- 第7章 API网关服务:Spring Cloud Zuul
- 第8章 分布式配置中心:Spring Cloud Config
- 第9章 消息总线:Spring Cloud Bus
- 第10章 消息驱动的微服务:Spring Cloud Stream
- 附录 A Starter POMs
- 后记
参数绑定
在上一节的示例中,我们使用Spring Cloud Feign实现的是一个不带参数的REST服务绑定。然而现实系统中的各种业务接口要比它复杂得多,我们会在HTTP的各个位置传入各种不同类型的参数,并且在返回请求响应的时候也可能是一个复杂的对象结构。在本节中,我们将详细介绍Feign中对几种不同形式参数的绑定方法。
在开始介绍 Spring Cloud Feign 的参数绑定之前,我们先扩展一下服务提供方hello-service。增加下面这些接口定义,其中包含带有Request参数的请求、带有Header信息的请求、带有RequestBody的请求以及请求响应体中是一个对象的请求。
@RequestMapping(value="/hello1",method=RequestMethod.GET)
public String hello(@RequestParam String name){
return "Hello "+name;
}
@RequestMapping(value="/hello2",method=RequestMethod.GET)
public User hello(@RequestHeader String name,@RequestHeader Integer age){
return new User(name,age);
}
@RequestMapping(value="/hello3",method=RequestMethod.POST)
public String hello(@RequestBody User user){
return "Hello "+user.getName()+","+user.getAge();
}
User对象的定义如下,这里省略了getter和setter函数,需要注意的是,这里必须要有User的默认构造函数。不然,Spring Cloud Feign根据JSON字符串转换User对象时会抛出异常。
public class User {
private String name;
private Integer age;
public User(){
}
public User(String name,Integer age){
this.name=name;
this.age=age;
}
//省略getter和setter
@Override
public String toString(){
return "name="+name+",age="+age;
}
}
在完成了对 hello-service 的改造之后,下面我们开始在快速入门示例的feign-consumer应用中实现这些新增的请求的绑定。
- 首先,在feign-consumer中创建与上面一样的User类。
- 然后,在 HelloService 接口中增加对上述三个新增接口的绑定声明,修改后,完成的HelloService接口如下所示:
@FeignClient("HELLO-SERVICE")
public interface HelloService {
@RequestMapping("/hello")
String hello();
@RequestMapping(value="/hello1",method=RequestMethod.GET)
String hello(@RequestParam("name")String name);
@RequestMapping(value="/hello2",method=RequestMethod.GET)
User hello(@RequestHeader("name")String name,@RequestHeader("age")Integer age);
@RequestMapping(value="/hello3",method=RequestMethod.POST)
String hello(@RequestBody User user);
}
这里一定要注意,在定义各参数绑定时,@RequestParam、@RequestHeader等可以指定参数名称的注解,它们的value千万不能少。在Spring MVC程序中,这些注解会根据参数名来作为默认值,但是在Feign中绑定参数必须通过value属性来指明具体的参数名,不然会抛出IllegalStateException异常,value属性不能为空。
Caused by: java.lang.IllegalStateException: RequestParam.value()was empty on parameter 0
at feign.Util.checkState(Util.java:128)
- 最后,在ConsumerController中新增一个/feign-consumer2接口,来对本节新增的声明接口进行调用,修改后的完整代码如下所示:
@RestController
public class ConsumerController {
@Autowired
HelloService helloService;
@RequestMapping(value="/feign-consumer",method=RequestMethod.GET)
public String helloConsumer(){
return helloService.hello();
}
@RequestMapping(value="/feign-consumer2",method=RequestMethod.GET)
public String helloConsumer2(){
StringBuilder sb=new StringBuilder();
sb.append(helloService.hello()).append("\n");
sb.append(helloService.hello("DIDI")).append("\n");
sb.append(helloService.hello("DIDI",30)).append("\n");
sb.append(helloService.hello(new User("DIDI",30))).append("\n");
return sb.toString();
}
}
测试验证
在完成上述改造之后,启动服务注册中心、两个hello-service服务以及我们改造过的feign-consumer。通过发送GET请求到http://localhost:9001/feign-consumer2,触发 HelloService 对新增接口的调用。最终,我们会获得如下输出,代表接口绑定和调用成功。
Hello World
Hello DIDI
name=DIDI,age=30
Hello DIDI,30
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论