微服务的feign调用header头被丢弃两种解决方案(附源码)

微服务的feign调用header头被丢弃两种解决方案(附源码)

  • 问题背景
  • 解决方案一
  • 解决方案二
  • 解决方案代码示例
  • 总结
  • Lyric: 哪里都是你

问题背景

在使用springcloud的微服务feign调用时,会自动把header自动扔掉,但基本上每个服务都会有一个全局globalId,能够清除调用链路,可以有两种解决方案
注意事项:

  • 可以使用文章的代码自己创建工程,也可下载源码进行参考

解决方案一

1 可以在每次远程调用时,使用@RequestHeader注解重新封装请求头

    @GetMapping("/mem1")
    String mem1(String res, @RequestHeader String globalId);

解决方案二

1 可以使用springcloud提供的feign拦截器RequestInterceptor,拦截请求头重新进行封装

解决方案代码示例

1 feign拦截器配置类

package com.lanran.feignheader.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Description: feign拦截器功能, 解决header丢失问题
 * @Created: IDEA2021
 * @author: 蓝染
 * @createTime: 2022-07-02 21:10
 **/

@Configuration
public class FeignConfig {

    @Bean("requestInterceptor")
    public RequestInterceptor requestInterceptor() {

        RequestInterceptor requestInterceptor = new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                //1、使用RequestContextHolder拿到刚进来的请求数据
                ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

                if (requestAttributes != null) {
                    //老请求
                    HttpServletRequest request = requestAttributes.getRequest();

                    if (request != null) {
                        //2、同步请求头的数据(主要是cookie)
                        //把老请求的cookie值放到新请求上来,进行一个同步
                        String cookie = request.getHeader("Cookie");
                        template.header("Cookie", cookie);
                    }
                }
            }
        };
        return requestInterceptor;
    }

}

2 请求测试接口

package com.lanran.feignheader.controller;

import com.lanran.feignheader.feign.MemFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

/**
 * @Author suolong
 * @Date 2022/7/22 10:58
 * @Version 2.0
 */
@RestController
public class FeignController {

    @Autowired
    MemFeign memFeign;


    @GetMapping("/test1")
    public String test1() {
        //获取当前线程请求头信息(解决Feign异步调用丢失请求头问题)
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //每一个线程都来共享之前的请求数据
        RequestContextHolder.setRequestAttributes(requestAttributes);
        String a = memFeign.mem1("a", "dsahjkdhsakj54646");
        System.out.println(a);
        return "success";
    }

    @GetMapping("/test2")
    public String test2() {
        //获取当前线程请求头信息(解决Feign异步调用丢失请求头问题)
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //调用微服务之前,每一个线程都来共享之前的请求数据
        RequestContextHolder.setRequestAttributes(requestAttributes);
        String a = memFeign.mem2("a");
        System.out.println(a);
        return "success";
    }


}

3 feign调用

package com.lanran.feignheader.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;

/**
 * @Author suolong
 * @Date 2022/7/22 10:59
 * @Version 2.0
 */
@FeignClient("mem")
public interface MemFeign {

    @GetMapping("/mem1")
    String mem1(String res, @RequestHeader String globalId);


    @GetMapping("/mem2")
    String mem2(String res);

}

4 启动类,开启feign

package com.lanran.feignheader;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;


@EnableFeignClients
@SpringBootApplication
public class FeignHeaderApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignHeaderApplication.class, args);
    }

}

5 依赖导入


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.7.2version>
        <relativePath/> 
    parent>
    <groupId>com.lanrangroupId>
    <artifactId>feignHeaderartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>feignHeadername>
    <description>Demo project for Spring Bootdescription>
    <properties>
        <java.version>1.8java.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
            <version>2.2.0.RELEASEversion>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombokgroupId>
                            <artifactId>lombokartifactId>
                        exclude>
                    excludes>
                configuration>
            plugin>
        plugins>
    build>

project>

6 整体目录示例
微服务的feign调用header头被丢弃两种解决方案(附源码)_第1张图片

总结

之前总是获取不到头




作为程序员第 215 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha …

Lyric: 哪里都是你

你可能感兴趣的:(java开发常遇问题,微服务,java,servlet)