@OpenFeign的使用
花开堪折直需折,莫待无花空折枝
- 不甘于做简单和无聊的事——我不想只会CRUD
主启动类加注解:@EnableFeignCilent
@EnableFeignClients //开启feign
@SpringBootApplication
public class OrderFeignMain85 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain85.class, args);
}
}
(在客户端)编写服务接口:
接口定义:
-
(客户端)定义的服务接口是和(服务端)服务提供方的接口一一对应的;
- 比如服务提供方的接口为:
@GetMapping("/get/{id}") public CommonResult getPaymentById(@PathVariable("id") int id){ Payment res=paymentService.getPaymentById(id); logger.info("***** 查询结果:"+res); if (res!=null){ return new CommonResult(200,"查询数据成功!,serverPort:"+serverPort,res); }else{ return new CommonResult(500,"没有对应查询记录:ID:!"+id,null); } }
- 那么客户端定义的服务接口为:**如getPaymentById与服务提供方的getPaymentById定义一样;**客户端自定义接口,接口的实现可以理解为服务提供方去实现,
//加上@FeignClient注解即代表为一个组件,不需要再加@Component //@Component @FeignClient(value = "CLOUD-PAYMENT-SERVICE")//value内容为配置的服务名 public interface IPaymentFeignService { @GetMapping("/payment/get/{id}") CommonResult getPaymentById(@PathVariable("id") int id); }
-
需要指定微服务的名称(即指定服务端的服务名):@FeignClient(value = “CLOUD-PAYMENT-SERVICE”)
-
完整代码:
package com.ld.springcloud.service;
import com.ld.springcloud.pojo.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @Classname PaymentFeignService
* @Date 2020/11/28 22:43
* @Created by LD
*/
//加上@FeignClient注解即代表为一个组件,不需要再加@Component
//@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")//value内容为配置的服务名
public interface IPaymentFeignService {
@GetMapping("/payment/get/{id}")
CommonResult getPaymentById(@PathVariable("id") int id);
}
编写Controller:
- controller中使用的是定义的FeignService接口进行服务的调用
@RestController
@RequestMapping(value="/consumer",produces = {"application/json;charset=UTF-8"})
public class OrderController {
@Autowired
IPaymentFeignService paymentFeignService;
@GetMapping("/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") int id){
//controller中使用的是定义的FeignService接口进行服务的调用
CommonResult commonResult= paymentFeignService.getPaymentById(id);
return commonResult;
}
}
过程描述:
-
在主启动类加上@EnableFeignCilent:开启Feign
-
定义服务接口(需要与服务端的接口定义一致),同时需要指定微服务的名称;
-
指定微服务名称就相当于指定了服务提供方,Feign会从服务注册表中获取当前的服务注册实列,并找到指定的微服务
-
定义与服务端一致的接口就是在指定服务接口地址,比如上面定义的服务接口:
当我们访问这个地址:http://CLOUD-PAYMENT-SERVICE/payment/get/2
CLOUD-PAYMENT-SERVICE:指定的服务名称,由于Feign集成了Ribbon,所以带有负载均衡的功能,CLOUD-PAYMENT-SERVICE会被解析成对应的端口号;
payment/get/2:就是在客户端上面定义的 “@GetMapping("/payment/get/{id}")“
-
根据这个流程可以发现:Feign可以看成时Ribbon+RestTemplate的一个封装,带有负载均衡以及(基于http)服务调用的功能
-
问题:使用Feign返回结果是xml:
问题:Feign返回结果是xml
解决:
- 在请求映射(@RequestMapping、@Get/PostMapping)加上返回的注解:"produces = {“application/json;charset=UTF-8”}"
@RestController
//加上返回类型:
@RequestMapping(value="/consumer",produces = {"application/json;charset=UTF-8"})
public class OrderController {
@Autowired
IPaymentFeignService paymentFeignService;
@GetMapping("/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") int id){
CommonResult commonResult= paymentFeignService.getPaymentById(id);
return commonResult;
}
}