欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

openFeign服務之間調(diào)用保持請求頭信息處理方式

 更新時間:2021年06月25日 08:56:53   作者:zhuwei_clark  
這篇文章主要介紹了openFeign服務之間調(diào)用保持請求頭信息處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

openFeign服務間調(diào)用保持請求頭信息處理

1、注意特殊情況,在定時任務或者內(nèi)部之間調(diào)用,沒有request的時候,不要處理直接返回。

2、在GET請求,參數(shù)確放在Body里面?zhèn)鬟f的情況,restTemplate是不認識的,所以這里要轉(zhuǎn)化下處理,然后清空body數(shù)據(jù)

3、在請求過程中如果出現(xiàn)java.io.IOException: too many bytes written異常,請參考保持請求頭造成請求頭和content-length不一致

/**
 * 解決服務調(diào)用丟失請求頭的問題
 * @author 大仙
 *
 */
@Component
public class FeignConfiguration implements RequestInterceptor{
    private final Logger logger = LoggerFactory.getLogger(getClass());
 
    @Autowired
    private ObjectMapper objectMapper;
 
    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        // 注意: RequestContextHolder依賴于 ThreadLocal, 所以在hystrix的隔離策略為THREAD、MQ的消費者、定時任務調(diào)用feignClient時,此處應為null
        if (attributes == null) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String values = request.getHeader(name);
                template.header(name, values);
            }
        }
        logger.info("保持請求頭");
        //feign 不支持 GET 方法傳 POJO, json body轉(zhuǎn)query
        if (template.method().equals("GET") && template.requestBody().asBytes() != null) {
            try {
                JsonNode jsonNode = objectMapper.readTree(template.requestBody().asBytes());
                Request.Body.empty();
 
                Map<String, Collection<String>> queries = new HashMap<>();
                buildQuery(jsonNode, "", queries);
                template.queries(queries);
            } catch (IOException e) {
                //提示:根據(jù)實踐項目情況處理此處異常,這里不做擴展。
                e.printStackTrace();
            }
        }
    }
 
    /**
     * 改造
     * @param jsonNode
     * @param path
     * @param queries
     */
    private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
        // 葉子節(jié)點
        if (!jsonNode.isContainerNode()) {
            if (jsonNode.isNull()) {
                return;
            }
            Collection<String> values = queries.get(path);
            if (null == values) {
                values = new ArrayList<>();
                queries.put(path, values);
            }
            values.add(jsonNode.asText());
            return;
        }
        // 數(shù)組節(jié)點
        if (jsonNode.isArray()) {
            Iterator<JsonNode> it = jsonNode.elements();
            while (it.hasNext()) {
                buildQuery(it.next(), path, queries);
            }
        } else {
            Iterator<Map.Entry<String, JsonNode>> it;
            it = jsonNode.fields();
            while (it.hasNext()) {
                Map.Entry<String, JsonNode> entry = it.next();
                if (StringUtils.hasText(path)) {
                    buildQuery(entry.getValue(), path + "." + entry.getKey(), queries);
                } else {
                    // 根節(jié)點
                    buildQuery(entry.getValue(), entry.getKey(), queries);
                }
            }
        }
    }
}

保持請求頭造成請求頭和content-length不一致

Request processin g failed; nested exception is feign.RetryableException: too many bytes written

2020-09-08 14:07:14.718 ERROR 16146 --- [io-12000-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processin
g failed; nested exception is feign.RetryableException: too many bytes written executing POST http://pay/wx/create] with root cause
java.io.IOException: too many bytes written
	at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3574) ~[na:1.8.0_212]
	at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3565) ~[na:1.8.0_212]
	at feign.Client$Default.convertAndSend(Client.java:181) ~[feign-core-10.4.0.jar!/:na]
	at feign.Client$Default.execute(Client.java:77) ~[feign-core-10.4.0.jar!/:na]
	at org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer$1.doWithRetry(RetryableFeignLoadBalancer.java:114) ~[spring-cloud-openfeign-core-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
	at org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer$1.doWithRetry(RetryableFeignLoadBalancer.java:94) ~[spring-cloud-openfeign-core-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
	at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287) ~[spring-retry-1.2.5.RELEASE.jar!/:na]
	at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180) ~[spring-retry-1.2.5.RELEASE.jar!/:na]
	at org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer.execute(RetryableFeignLoadBalancer.java:94) ~[spring-cloud-openfeign-core-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
	at org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer.execute(RetryableFeignLoadBalancer.java:54) ~[spring-cloud-openfeign-core-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
	at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:104) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
	at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
	at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
	at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:231) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:228) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144) ~[rxjava-1.3.8.jar!/:1.3.8]
	at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
	at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
	at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.Subscriber.setProducer(Subscriber.java:209) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar!/:1.3.8]
	at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar!/:1.3.8

原因是:body是跟Content-Length 有關(guān)系

復制的時候是所有頭都復制的,可能導致Content-length長度跟body不一致. 所以只需要判斷如果是Content-length就跳過

解決方式:更改復制邏輯

 while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                // 跳過 content-length
                if (name.equals("content-length")){
                    continue;
                }
                String values = request.getHeader(name);
                template.header(name, values);
            }

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring?IOC容器的Bean管理XML自動裝配過程

    spring?IOC容器的Bean管理XML自動裝配過程

    這篇文章主要為大家介紹了spring?IOC容器Bean管理基于XML的自動裝配過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 淺談Java模板引擎性能對比

    淺談Java模板引擎性能對比

    本篇文章主要介紹了淺談Java模板引擎性能對比 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Mybatis步驟分解實現(xiàn)一個增刪改查程序

    Mybatis步驟分解實現(xiàn)一個增刪改查程序

    MybatisPlus是國產(chǎn)的第三方插件, 它封裝了許多常用的CURDapi,免去了我們寫mapper.xml的重復勞動。本文將整合MybatisPlus實現(xiàn)增刪改查功能,感興趣的可以了解一下
    2022-05-05
  • MyBatis工廠類封裝與簡化實現(xiàn)

    MyBatis工廠類封裝與簡化實現(xiàn)

    工廠類的目的是將對象的創(chuàng)建邏輯封裝在一個類中,以便客戶端代碼無需了解具體的實現(xiàn)細節(jié),本文主要介紹了MyBatis工廠類封裝與簡化實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Java中生成唯一ID的方法示例

    Java中生成唯一ID的方法示例

    這篇文章主要介紹了Java中生成唯一ID的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • Java數(shù)據(jù)結(jié)構(gòu)之二叉搜索樹詳解

    Java數(shù)據(jù)結(jié)構(gòu)之二叉搜索樹詳解

    二叉搜索樹作為一個經(jīng)典的數(shù)據(jù)結(jié)構(gòu),具有鏈表的快速插入與刪除的特點,同時查詢效率也很優(yōu)秀,所以應用十分廣泛。本文將詳細講講二叉搜索樹的原理與實現(xiàn),需要的可以參考一下
    2022-06-06
  • mybatis-plus saveOrUpdateBatch踩坑記錄

    mybatis-plus saveOrUpdateBatch踩坑記錄

    這篇文章主要介紹了mybatis-plus saveOrUpdateBatch踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • MyBatisPlus條件構(gòu)造器圖文實例詳解

    MyBatisPlus條件構(gòu)造器圖文實例詳解

    這篇文章主要介紹了MyBatisPlus條件構(gòu)造器,了解內(nèi)部原理是為了幫助我們做擴展,同時也是驗證了一個人的學習能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的
    2023-01-01
  • java必學必會之線程(2)

    java必學必會之線程(2)

    本文對java線程進行深入學習,重點介紹了線程同步問題、線程死鎖問題,感興趣的小伙伴們可以參考一下
    2015-12-12
  • SpringBoot中請求參數(shù)綁定及使用詳解

    SpringBoot中請求參數(shù)綁定及使用詳解

    這篇文章主要介紹了SpringBoot中請求參數(shù)綁定及使用詳解,在Web應用程序中,請求參數(shù)綁定是非常重要的操作,Spring?Boot框架使得請求參數(shù)綁定變得非常簡單,通過使用注解和預定義的類可以輕松地實現(xiàn)此操作,需要的朋友可以參考下
    2023-08-08

最新評論