@TOC
问题背景
在使用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 依赖导入
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lanran</groupId>
<artifactId>feignHeader</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>feignHeader</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
6 整体目录示例
总结
之前总是获取不到头
作为程序员第 215 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha ...