Feign:Decoder与ErrorDecoder

Feign在spingcloud架构中,各微服务之间的调用工具,它整合了ribbon的负载均衡,采用声明调用,使服务之间的调用更加简单。

@FeignClient( value = "product",configuration = FeignBaseConfiguration.class)
public interface ProductClient {

    @RequestMapping("/product/connect")
    String connectProductService();


}

在value=xxx中配置对端服务名,将从eureka注册中心获取servername=product的微服务,根据负载均衡策略(如果是集群情况)调用product集群的微服务。

在当下的springcloud中多数引用的是openfeign:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

它是feign(已停止维护)的一层包装与功能完善:

<dependency>     
	   <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

Feign中有两大解析器:Decoder与ErrorDecoder

Decoder用于“正向解析”(我编的),response被默认的messageConverter把内容解析成声明的返回类型。通过decoder源码可以看出当返回状态码不是404和204的情况下,将走进该解析器。也就是常见的正常状态了。此外404状态可以允许被走进该解析器如果你在feignclient中配置decode404=true

        public Object decode(Response response, Type type) throws IOException {
            if (response.status() != 404 && response.status() != 204) {
                if (response.body() == null) {
                    return null;
                } else {
                    return byte[].class.equals(type) ? Util.toByteArray(response.body().asInputStream()) : super.decode(response, type);
                }
            } else {
                return Util.emptyValueOf(type);
            }
        }

ErrorDecoder:请求异常解析,对端返回的非正常状态码例如40x,50x等状态码,response将会被该解析器解析,一般如果你不重新定义解析器,它将会抛出匹配到的状态码的错误异常(FeignException)。

我们可以通过配置configuration在feignclient注解中指明来重定义这两个解析器。只需要将其定义成@Bean,feign将自动替换,当然你也可以实现该接口。

@Configuration
@Slf4j
public class FeignBaseConfiguration {

    @Bean
    public Decoder decoder(){
        return (response, type) -> {
            log.warn("response status is:{}",response.status());
            return new Decoder.Default().decode(response,type);
        };
    }

    @Bean
    public ErrorDecoder errorDecoder(){
        return (s, response) -> {
            log.warn("response status is:{}",response.status());
            return new ErrorDecoder.Default().decode(s,response);
        };
    }

}

重新定义后,你可以指定新的解析器来为数据进行特定的处理,例如xml格式的转换;可以抛出业务异常。在这里可以做的事情很多。
当然以上两个解析器都是在服务可达情况下,在服务不可达的情况下(服务挂了),两个解析器是没有任何反应的包括errorDecoder,他会直接抛出fegin默认的请求client(HttpClient)的异常,例如:java.net.ConnectException: Connection refused: connect,因为这是http请求client抛出的底层异常,而不是来自feign业务。
这里就要用@ExceptionHandler进行捕获了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值