1. Feign介绍
通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下
Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。
而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix,可以让我们不再需要显式地使用这两个组件。
Feign具有如下特性:
- 支持可插拔的HTTP编码器和解码器;
- 支持Hystrix和它的Fallback;
- 支持Ribbon的负载均衡;
- 支持HTTP请求和响应的压缩。
有点像我们springmvc模式的Controller层的RequestMapping映射。这Feign是用@FeignClient来映射服务的。
2. Feign的使用
接前面的文章,再新建一个项目FeignTest,这里把OpenFeign勾选上
FeignTest项目核心代码
部分代码从之前的项目中直接拷贝
package com.springcloud.consumer.service;import com.springcloud.consumer.pojo.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;/**** @date 2020/7/28 12:27* @author wei.heng*/
@FeignClient("PRODUCT-PROVIDER")
public interface ProductService {/*** 获取产品对象* @param id 主键ID* @return com.springcloud.consumer.pojo.Product* @date 2020/7/28 12:27* @author wei.heng*/@GetMapping("/product/{id}")Product getProduct(@PathVariable Long id);/**** 新增产品对象* @param product 产品对象* @return org.springframework.http.ResponseEntity* @date 2020/7/28 12:27* @author wei.heng*/@PostMapping("/product")ResponseEntity addProduct(@RequestBody Product product);
}
package com.springcloud.consumer;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;/**** @date 2020/7/28 10:45* @author wei.heng*/
@SpringBootApplication
@EnableFeignClients
public class ConsumerApplication {/**** 初始化 RestTemplate - @LoadBalanced做多节点负载均衡* @return org.springframework.web.client.RestTemplate* @date 2020/7/27 16:57* @author wei.heng*/@LoadBalanced@Bean(name = "restTemplate")public RestTemplate initRestTemplate(){return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}}
package com.springcloud.consumer.controller;import com.springcloud.consumer.pojo.Product;
import com.springcloud.consumer.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;/**** @date 2020/7/27 14:58* @author wei.heng*/
@RestController
public class ProductController {private ProductService productService;@Autowiredpublic ProductController(ProductService productService) {this.productService = productService;}@GetMapping("/product/{id}")public ResponseEntity<Product> product(@PathVariable Long id){Product product = productService.getProduct(id);return ResponseEntity.ok(product);}@PostMapping("/product")public ResponseEntity products(@RequestBody Product product){return productService.addProduct(product);}}
application.yml
server:port: 8003eureka:client:# 默认拉取服务列表,这里不做配置了register-with-eureka: falseservice-url:# 服务中心地址defaultZone: http://localhost:7000/eureka/,http://localhost:8000/eureka/
在product-provider服务项目中新增方法
@PostMapping("/product")public ResponseEntity product(@RequestBody Product product){int i = productService.inserProduct(product);ResponseEntity responseEntity;if(i > 0){responseEntity = new ResponseEntity(HttpStatus.CREATED);} else {responseEntity = new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);}return responseEntity;}
postman测试
feign post 传递单个字符串示例
feign
@PostMapping(value = "/update2ApplySuccess", consumes = MediaType.TEXT_PLAIN_VALUE)Boolean update2ApplySuccess(@RequestBody String transactionNo);
controller
@PostMapping("/update2ApplySuccess")public Boolean update2ApplySuccess(@RequestBody String transactionNo)
亲测OK