feign Response只能讀一次問題 和 feign response 返回值攔截

前言

spring cloud 對feign調用對返回值做了包裝處理,通過一些列Decoder來處理feign訪問的返回值。
具體流程 從SynchronousMethodHandler中的decoder開始會經歷如下幾個decoder:

OptionalDecoder -> ResponseEntityDecoder -> SpringDecoder

可以在 FeignClientsConfiguration 看到有對上面三個decoder的定義,有興趣的可以自行閱讀源碼。

feign返回值攔截 + response只能讀取一次處理

feign返回值攔截只需要自定義一個coder,替換 FeignClientsConfiguration 中的 decoder定義即可,具體代碼如下:
配置自定義decoder:

/**
 * feign返回值攔截
 * @author liufei
 */
public final class ResultStatusDecoder implements Decoder {
    public static final String CONTENT_KEY = "content";
    final Decoder delegate;

    public ResultStatusDecoder(Decoder delegate) {
        Objects.requireNonNull(delegate, "Decoder must not be null. ");
        this.delegate = delegate;
    }

    @Override
    public Object decode(Response response, Type type) throws IOException {
        // 判斷是否返回參數是否是異常
        String resultStr = IOUtils.toString(response.body().asInputStream(), StandardCharsets.UTF_8);
        // 拿到返回值,進行自定義邏輯處理
        log.info("do business ,result msg ->{}",resultStr);
        // 回寫body,因爲response的流數據只能讀一次,這裏回寫後重新生成response
        return delegate.decode(response.toBuilder().body(resultStr, StandardCharsets.UTF_8).build(), type);
    }
}

由於response中的body只能讀取一次,所以最後需要把body回寫,再重新生成response傳遞到下一個decoder

配置自定義bean:

@Configuration
public class SupportAutoConfiguration {

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;
    
    @Bean
    public Decoder feignDecoder() {
        return new ResultStatusDecoder(new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters))));
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章