feign が呼び出されたときに均一にトークンを取得し、
ヘッダーを追加するときにエラーを報告します。エラーは次のように報告されます
: スレッドバインドされたリクエストが見つかりません: 実際の Web リクエストの外部のリクエスト属性を参照しているか、外部でリクエストを処理していますか最初に受信していたスレッドの? もしあなたが実際に…
1. すべての偽の@Componentにトークンを追加する方法
public class TokenInterceptor は RequestInterceptor { private Final HttpServletRequest request;を実装します。
@Autowired
public TokenInterceptor(HttpServletRequest request) {
this.request = request;
}
@Override
public void apply(RequestTemplate template) {
String token = request.getHeader("X-Access-Token"); // 从原始请求头中获取 Token
template.header("Authorization", "Bearer " + token); // 将 Token 添加到 Feign 请求头中
template.header("X-Access-Token", token); // 将 Token 添加到 Feign 请求头中
}
}
原則: TokenInterceptor は、Feign によって提供されるインターセプター インターフェイスである RequestInterceptor インターフェイスを実装します。TokenInterceptor を Feign のインターセプターとして登録すると、Feign が呼び出すたびに TokenInterceptor が呼び出されます。
Feign は、リクエストを送信する前に、登録されているすべてのインターセプターを含むインターセプター チェーンを実行します。インターセプター チェーンでは、各インターセプターはリクエストを変更したり、追加の処理ロジックを追加したりできます。
RequestInterceptor インターフェイスは、リクエストを送信する前に呼び出される apply メソッドを定義し、RequestTemplate オブジェクトを通じてリクエスト ヘッダーやリクエスト パラメータなどのリクエストの関連情報を変更できます。
したがって、TokenInterceptor を Feign のインターセプターとして登録すると、各 Feign 呼び出しが開始される前に apply メソッドが呼び出されます。そこで、トークン処理ロジックを追加し、リクエスト ヘッダーに Token を追加して、トークンが Feign 呼び出しで自動的に伝送されます。 。
Feign クライアントを有効にするには、TokenInterceptor を Bean として登録し、Spring コンテナに追加する必要があることに注意してください。具体的な方法は、使用する Spring Boot のバージョンと構成方法によって異なります。
要約すると、TokenInterceptor は RequestInterceptor インターフェイスを実装し、インターセプター チェーン内で呼び出されてリクエストを変更し、追加の処理ロジックを追加するため、Feign 呼び出しをインターセプトできます。
実際の Web リクエストなしで Feign インターフェイスが呼び出された場合、HttpServletRequest オブジェクトは取得されず、例外がスローされます。
スレッドバインドされたリクエストが見つかりません: 実際の Web リクエストの外部のリクエスト属性を参照していますか? それとも最初に受信したスレッドの外部でリクエストを処理していますか? 実際に ...この問題を回避するには、HttpServletRequest オブジェクトを次のようにカプセル化できます。
次のようなThreadLocal
解決:
public class TokenHolder {
private static final ThreadLocal<String> tokenHolder = new ThreadLocal<>();
private static Boolean TokenValidationFlag=true;
public static Boolean getTokenValidationFlag() {
return TokenValidationFlag;
}
public static void setTokenValidationFlag(Boolean tokenValidationFlag) {
TokenValidationFlag = tokenValidationFlag;
}
public static void setToken(String token) {
tokenHolder.set(token);
}
public static void removeToken() {
tokenHolder.remove();
}
public static String getToken() {
return tokenHolder.get();
}
}
@Component
public class TokenInterceptor implements RequestInterceptor {
private final HttpServletRequest request;
@Autowired
public TokenInterceptor(HttpServletRequest request) {
this.request = request;
}
@Override
public void apply(RequestTemplate template) {
boolean validateToken = TokenHolder.getTokenValidationFlag();
if (validateToken) {
String token = request.getHeader("X-Access-Token"); // 从原始请求头中获取 Token
template.header("Authorization", "Bearer " + token); // 将 Token 添加到 Feign 请求头中
template.header("X-Access-Token", token); // 将 Token 添加到 Feign 请求头中
}
}
}
タイミングタスク処理
@Scheduled(fixedDelay =30 * 60 * 1000)
// @PostConstruct
public void initGoods(){
TokenHolder.setTokenValidationFlag(false);
Result<List<SysApplicationPermissionDto>> applicationAndPermissions = sysUserCenterApi.getApplicationAndPermissions();
TokenHolder.setTokenValidationFlag(true);