一洼绿地

Spring clound - Feign 错误的处理

·2 min read
前言

FeignClient 在调用服务时,目标端发生错误。 返回:

{
  "code":"100005",
  "message":"error message",
  "data":""
}

FeignClient 接口定义为:

```java
@FeignClient(name = "feignLogin"")
public interface LoginFeign {

    @GetMapping(value = "/api/feignUser")
    Result<User> feignUser();
}

这是 Feign 在序列化 Result<User> 时,会发生错误, 因为 "" 反序列化 User ,jackson 抛出异常。

经过反复测试,可以在拦截器上做统一的错误处理。

解决
  • FeignClient config 配置
@Slf4j
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignConfig {

    @Bean
    @ConditionalOnMissingBean({Client.class})
    public Client feignClient(okhttp3.OkHttpClient client) {
        return new feign.okhttp.OkHttpClient(client);
    }

    @Bean
    public okhttp3.OkHttpClient okHttpClient() {
        return new okhttp3.OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                // 拦截器
                .addInterceptor(
                  new FeignInterceptor()
                )
                .connectionPool(
                  new ConnectionPool(10, 5L, TimeUnit.MINUTES)
                )
                .build();
    }
  • FeignClient Interceptor 配置
class FeignInterceptor implements Interceptor {

  @NotNull
  @Override
  public Response intercept(@NotNull Chain chain) throws IOException {
    Response response = chain.proceed(request);
    String responseBody = getResponseBody(response);
    Result<?> result = JsonUtil.toObject(responseBody, Result.class);
    // 在此处加入判断,抛出异常
    // 不会进入到 feign 解析 json 流程去
    if (!Result.SUCCESSED.getCode().equals(result.getCode())) {
      throw new BusinessException(result.getCode(), result.getMessage());
    }
    return response;
  };
}