• Feign远程调用丢失请求头问题


    Feign远程调用丢失请求头

    feign远程调用接口,会新创建request导致丢失请求头 

     解决方法需要获取原请求头并同步

     使用 feign 自带请求拦截器 RequestInterceptor,在该拦截器中同步请求头

    1. package com.hdb.pingmoweb.order.config;
    2. import feign.RequestInterceptor;
    3. import feign.RequestTemplate;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.Configuration;
    6. import org.springframework.web.context.request.RequestAttributes;
    7. import org.springframework.web.context.request.RequestContextHolder;
    8. import org.springframework.web.context.request.ServletRequestAttributes;
    9. import javax.servlet.http.HttpServletRequest;
    10. @Configuration
    11. public class FeignConfig {
    12. @Bean
    13. public RequestInterceptor requestInterceptor(){
    14. return new RequestInterceptor() {
    15. @Override
    16. public void apply(RequestTemplate requestTemplate) {
    17. ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    18. HttpServletRequest request = requestAttributes.getRequest();
    19. if(request !=null){
    20. String cookie = request.getHeader("Cookie");
    21. requestTemplate.header("Cookie",cookie);
    22. }
    23. }
    24. };
    25. }
    26. }

    Feign异步调用丢失上下文

    解决方案:使用异步编排需要给线程重新设置上下文,通过使用RequestContextHolder,获取和设置上下文

    由于RequestContextHolder 内部维护了ThreadLocal,不同线程ThreadLocal 获取数据不同

    下面是异步编排和RequestContextHolder使用代码

    1. @Autowired
    2. private CouponFeignService couponFeignService;
    3. @Autowired
    4. private ThreadPoolExecutor executor;
    5. @RequestMapping("/feign")
    6. public R feign(HttpServletRequest request) throws ExecutionException, InterruptedException {
    7. Map> map = new HashMap<>();
    8. RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    9. CompletableFuture future1 = CompletableFuture.runAsync(() -> {
    10. System.out.println("线程:"+Thread.currentThread().getId());
    11. RequestContextHolder.setRequestAttributes(requestAttributes);
    12. List list1 = couponFeignService.info2(1L);
    13. map.put("list1", list1);
    14. }, executor);
    15. CompletableFuture future2 =CompletableFuture.runAsync(()->{
    16. System.out.println("线程:"+Thread.currentThread().getId());
    17. RequestContextHolder.setRequestAttributes(requestAttributes);
    18. List list2 = couponFeignService.info2(1L);
    19. map.put("list2",list2);
    20. },executor);
    21. CompletableFuture future = CompletableFuture.allOf(future1, future2);
    22. future.get();
    23. return R.ok();
    24. }

  • 相关阅读:
    [附源码]Python计算机毕业设计Django财务管理系统
    ​软考-高级-系统架构设计师教程(清华第2版)【第14章 云原生架构设计理论与实践(P496~526)-思维导图】​
    Elasticsearch的概述和安装以及常见概念
    动态树的最值
    VBA复制区域数据
    ServletContext对象
    MSQL系列(九) Mysql实战-Join算法底层原理
    区块链的两个核心概念之一签名, 另一个是共识.
    Python判断一个整数是否是回文数的三种方法
    前端学习 Nginx
  • 原文地址:https://blog.csdn.net/qq_29385297/article/details/127552790