SpringCloud学习之feign
一、关于feigin
feigin是一种模板化,声明式的http客户端,feign可以通过注解绑定到接口上来简化Http请求访问。当然我们也可以在创建Feign对象时定制自定义解码器(xml或者json等格式解析)和错误处理。
二、添加SpringCloud对feign的支持
gradle配置:
compile('org.springframework.cloud:spring-cloud-starter-feign')
feigin最基本使用方法:
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
} static class Contributor {
String login;
int contributions;
} public static void main(String... args) {
GitHub github = Feign.builder()
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com"); // Fetch and print a list of the contributors to this library.
List<Contributor> contributors = github.contributors("OpenFeign", "feign");
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
feign发送json与xml的格式的http请求:
interface LoginClient { @RequestLine("POST /")
@Headers("Content-Type: application/xml")
@Body("<login \"user_name\"=\"{user_name}\" \"password\"=\"{password}\"/>")
void xml(@Param("user_name") String user, @Param("password") String password); @RequestLine("POST /")
@Headers("Content-Type: application/json")
// json curly braces must be escaped!
@Body("%7B\"user_name\": \"{user_name}\", \"password\": \"{password}\"%7D")
void json(@Param("user_name") String user, @Param("password") String password);
}
注意示例中需要添加对gson的支持
feign发送https信任所有证书的代码:
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
} @Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
} @Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}};
final SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext
.getSocketFactory();
Feign.builder().client(new Client.Default(sslSocketFactory, (s, sslSession) -> true));
三、在SpringCloud中使用Feign
比如说注册中心有如下服务:
1)application.yml的配置:
spring:
application:
name: demo-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka,http://localhost:8081/eureka
server:
port: 8090
2)创建接口
package com.bdqn.lyrk.consumer.demo.api; import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping; @FeignClient("demo")
public interface DemoConfigService { @RequestMapping("/demo.do")
String demoService();
}
注意在接口上加上注解:@FeignClient("demo") 注解里的参数是在eureka注册的服务名
3)编写启动类:
package com.bdqn.lyrk.consumer.demo; import com.bdqn.lyrk.consumer.demo.api.DemoConfigService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext; @EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class DemoConsumerProvider { public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoConsumerProvider.class, args);
DemoConfigService demoConfigService = applicationContext.getBean(DemoConfigService.class);
System.out.println(demoConfigService.demoService());
}
}
注意在启动类上加上@EnableFeignClients来开启Feign功能
运行后输出:
此时我们可以发现使用feign客户端我们访问服务的代码简洁了好多
4) feign多参数设置方法
service-api模块的接口定义: public interface IBillService { @PostMapping("/queryBill")
List<BillDTO> queryOrders(@RequestBody BillsVO billsVO);
} 相关服务实现类: @RestController
public class BillServiceImpl implements IBillService { @Autowired
private BillMapper billMapper; @PostMapping("/queryBill")
@Override
public List<BillDTO> queryOrders(@RequestBody BillsVO billsVO) {
return billMapper.query(BeanMap.create(billsVO));
}
} 注意 需要在接口定义与实现类的参数上加@RequestBody注解
四、feign中的使用Hystrix
1) 在@FeignClient中有两个属性我们值得关注一下,它们分别是fallBack和fallBackFactory,当然我们系统里要添加Hystrix支持并且在属性文件里设置:
feign.hystrix.enabled=true
同样我们要在启动类里加上@EnableCircuitBreaker注解打开Hystrix保护
2) fallBack属性很简单,用来设置降级方法,当feign请求服务失败时所调用的方法, 这里我给出接口的例子:
首先定义一个接口:IOrderService
package com.bdqn.lyrk.service.api; import com.bdqn.lyrk.service.dto.OrderDTO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; public interface IOrderService { @GetMapping("/orderId/{orderId}")
OrderDTO getOrderById(@PathVariable("orderId") Integer orderId); @GetMapping("/errorOrder")
OrderDTO getErrorOrder();
}
其次定义Feign的接口OrderServiceClient继承IOrderService
package com.bdqn.lyrk.order.service.consumer.feign; import com.bdqn.lyrk.service.api.IOrderService;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Primary; @Primary
@FeignClient(value = "ORDER-SERVER", fallBack="FailedOrderServiceClientImpl.class")
public interface OrderServiceClient extends IOrderService { }
由于IOrderService不在同一个项目里,而且SpringCloud不推荐服务端和客户端使用同一个接口,所以我采用继承的方式,注意加上@Primary注解以免使用@Autowired时注入失败
在定义实现类:
package com.bdqn.lyrk.order.service.consumer.feign; import com.bdqn.lyrk.service.dto.OrderDTO;
import org.springframework.stereotype.Component; @Component
public class FailedOrderServiceClientImpl implements OrderServiceClient {
@Override
public OrderDTO getOrderById(Integer orderId) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setId(orderId);
orderDTO.setOrderName("服务中失败的订单,id为:" + orderId);
return null;
} @Override
public OrderDTO getErrorOrder() {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setOrderName("服务中失败的订单");
orderDTO.setId(-1);
return orderDTO;
}
}
最后@FeignClient中设置属性fallBack="FailedOrderServiceClientImpl.class" 就可以了
3) 当我们需要封装服务端的异常信息时,可以指定fallbackFactory属性,请看下面的例子:
package com.bdqn.lyrk.order.service.consumer.feign; import com.bdqn.lyrk.service.dto.OrderDTO;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component; @Component
public class OrderServiceFallbackFactoryImpl implements FallbackFactory<OrderServiceClient> {
@Override
public OrderServiceClient create(Throwable cause) {
return new OrderServiceClient() {
@Override
public OrderDTO getOrderById(Integer orderId) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setOrderName(cause.getMessage());
return orderDTO;
} @Override
public OrderDTO getErrorOrder() {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setOrderName(cause.getMessage());
return orderDTO;
}
};
}
}
注意:FallbackFactory的泛型参数一定要指定为@FeignClient修饰的接口,同时不建议fallback与fallbackFactory同时使用
最后 我贴一下服务端的实现代码:
package com.bdqn.lyrk.springcloud.order.service; import com.bdqn.lyrk.service.api.IOrderService;
import com.bdqn.lyrk.service.dto.OrderDTO;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.TimeUnit; @RestController
public class OrderServiceImpl implements IOrderService { @HystrixCommand(fallbackMethod = "errorDTO",
commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")} )
@GetMapping("/orderId/{orderId}")
@Override
public OrderDTO getOrderById(@PathVariable("orderId") Integer orderId) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setId(orderId);
orderDTO.setOrderName("订单ID为" + orderId + "的订单");
try {
TimeUnit.SECONDS.sleep(orderId);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} return orderDTO;
} @Override
public OrderDTO getErrorOrder() {
System.out.println(1 / 0);
return null;
} public OrderDTO errorDTO(Integer orderId) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setId(-1);
orderDTO.setOrderName("错误的订单,请重试");
return orderDTO;
}
}
对于Hystrix可以参考:SpringCloud学习之Hystrix
SpringCloud学习之feign的更多相关文章
- SpringCloud学习之Feign 的使用(五)
Feign 是一个声明式的伪RPC的REST客户端,它用了基于接口的注解方式,很方便的客户端配置,刚开始使用时还不习惯,感觉是在客户端写服务端的代码,Spring Cloud 给 Feign 添加了 ...
- SpringCloud学习(5)——Feign负载均衡
Feign概述 Feign是声明式的Web服务客户端, 使得编写Web服务客户端变的非常容易, 只需要创建一个接口, 然后在上面添加注解即可. Feign旨在使编写Java Http客户端变的更容易. ...
- SpringCloud学习之Ribbon
一.负载均衡与Ribbon 负载均衡,在集群中是很常见的一个“名词”,顾名思义是根据一定的算法将请求分摊至对应的服务节点上,常见的算法有如下几种: 轮询法:所有请求被依次分发到每台应用服务器上,每台服 ...
- SpringCloud学习笔记(3):使用Feign实现声明式服务调用
简介 Feign是一个声明式的Web Service客户端,它简化了Web服务客户端的编写操作,相对于Ribbon+RestTemplate的方式,开发者只需通过简单的接口和注解来调用HTTP API ...
- SpringCloud学习笔记(9)----Spring Cloud Netflix之声明式 REST客户端 -Feign的使用
1. 什么是Feign? Feign是一种声明式.模板化的HTTP客户端,在SpringCloud中使用Feign.可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到 ...
- SpringCloud学习笔记(六):Feign+Ribbon负载均衡
简介 官网解释: http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign Feign是一个声明式WebS ...
- SpringCloud学习系列之三----- 断路器(Hystrix)和断路器监控(Dashboard)
前言 本篇主要介绍的是SpringCloud中的断路器(Hystrix)和断路器指标看板(Dashboard)的相关使用知识. SpringCloud Hystrix Hystrix 介绍 Netfl ...
- java框架之SpringCloud(4)-Ribbon&Feign负载均衡
在上一章节已经学习了 Eureka 的使用,SpringCloud 也提供了基于 Eureka 负载均衡的两种方案:Ribbon 和 Feign. Ribbon负载均衡 介绍 SpringCloud ...
- SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理
前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...
随机推荐
- 《高级软件测试》web测试实践--12月31日记录
今日的任务进度如上图所示.我们对华科软件学院和计算机学院的网站进行了对比分析,分析的角度包括基本功能分析.前端性能分析.用户调研等.在这里我们简单总结下我们得到的评测结果. 基本功能分析:计算机学院和 ...
- css中的position
一.position语法与结构 position语法: position : static absolute relative position参数:static : 无特殊定位,对象遵循HTML定位 ...
- python之路--day13---函数--三元表达式,递归,匿名函数,内置函数-----练习
1.文件内容如下,标题为:姓名,性别,年纪,薪资 egon male 18 3000 alex male 38 30000 wupeiqi female 28 20000 yuanhao female ...
- EasyUI导航栏。
html: <div data-options="region:'west',split:true" title="导航栏菜单" style=" ...
- Ubuntu命令行连接WPA/WPA2无线网线
一,连接无加密无线网络zhang:sudo ip link set wlan0 up sudo iw dev wlan0 connect zhangsudo dhclient wlan0 二,连接WP ...
- 07_Python的控制判断循环语句1(if判断,for循环...)_Python编程之路
Python的数据类型在前几节我们都简单的一一介绍了,接下来我们就要讲到Python的控制判断循环语句 在现实编程中,我们往往要利用计算机帮我们做大量重复计算的工作,在这样的情况下,需要机器能对某个条 ...
- C# 使用 ffmpeg 进行音频转码
先放一下 ffmpeg 的官方文档以及下载地址: 官方文档:http://ffmpeg.org/ffmpeg.html 下载地址:http://ffmpeg.org/download.html 用 f ...
- 一张图说明 Web Api 参数绑定默认规则
请求如下: 控制器如下: 慎重说明:不管请求方式是 get 还是 post , 简单类型的参数,如 name 和 id ,其值都是从 url 里面去取. Web API 从 url 还是 body 获 ...
- apigw鉴权分析(1-5)亚马逊 - 鉴权分析
一.访问入口 https://developer.amazon.com/public/zh 二.鉴权方式分析 三.分解结论
- 新概念英语(1-32)A fine day
新概念英语(1-33)A fine day Where is the Jones family? It is a fine day today. There are some clouds in th ...