一、窗体的HTTP调用的四个问题
- 代码不可读
- 复杂的url难以维护
- 难以响应需求的变化
- 编程体验不统一
什么是Feign
Feign是Netflix开源的声明式HTTP客户端。
靠声明来表达想要什么,用feign来把想要的东西转换称对应的http请求,并将结果返回转化。
代码执行速度上会变慢。
使用Feign改善代码
order-service调用product-service
1. 导入依赖
order-service中
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
2. 启动类上加注解
order-service中启动类上加注解@EnableFeignClients
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
}
3. 编写声明式接口
这里的接口就是product-service和order-service互相调用的接口
@FeignClient(name = "product-service")
public interface ProductServiceFeignClient {
@GetMapping("/product/getProductById")
Product getProductById(@RequestParam(name = "id") Integer id);
@PostMapping(path = "/product/updateProduct")
ResultVO updateProduct(Product product);
}
4. 调用接口
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private ProductServiceFeignClient productServiceFeignClient;
@Override
public ResultVO createOrder(OrderForm orderForm, Integer userId) {
Random random = new Random();
Long orderNo = Long.parseLong((String.valueOf(System.currentTimeMillis()) + (random.nextInt(900000) + 100000)));
BigDecimal totalPrice = BigDecimal.ZERO;
Product product = productServiceFeignClient.getProductById(productForm.getProductId());
}
}
注意:
product-service接收order-service传过来的参数时出现错误feign.FeignException$MethodNotAllowed: status 405 reading
错误原因:
- feign如果发现请求body里面有数据会把请求转换为post再发送
- body有数据的原因是方法传参数
方法:
-
找办法让feign不传,参考链接:feign.FeignException$MethodNotAllowed: status 405 reading
-
feign如果发现请求body里面有数据会把请求转换为post再发送,那就(对方)product-service改为post请求来接受
-
@RequestParam注解可以使请求还保持为get,参数正确携带