fix bugs
This commit is contained in:
31
blade-core-context/pom.xml
Normal file
31
blade-core-context/pom.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>BladeX-Tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>blade-core-context</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<version>${project.parent.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-tool</artifactId>
|
||||
</dependency>
|
||||
<!-- Auto -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-auto</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springblade.core.tool.utils.ThreadLocalUtil;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* 多线程中传递 context 和 mdc
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class BladeCallableWrapper<V> implements Callable<V> {
|
||||
private final Callable<V> delegate;
|
||||
private final Map<String, Object> tlMap;
|
||||
/**
|
||||
* logback 下有可能为 null
|
||||
*/
|
||||
@Nullable
|
||||
private final Map<String, String> mdcMap;
|
||||
|
||||
public BladeCallableWrapper(Callable<V> callable) {
|
||||
this.delegate = callable;
|
||||
this.tlMap = ThreadLocalUtil.getAll();
|
||||
this.mdcMap = MDC.getCopyOfContextMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V call() throws Exception {
|
||||
if (!tlMap.isEmpty()) {
|
||||
ThreadLocalUtil.put(tlMap);
|
||||
}
|
||||
if (mdcMap != null && !mdcMap.isEmpty()) {
|
||||
MDC.setContextMap(mdcMap);
|
||||
}
|
||||
try {
|
||||
return delegate.call();
|
||||
} finally {
|
||||
tlMap.clear();
|
||||
if (mdcMap != null) {
|
||||
mdcMap.clear();
|
||||
}
|
||||
ThreadLocalUtil.clear();
|
||||
MDC.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Blade微服务上下文
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public interface BladeContext {
|
||||
|
||||
/**
|
||||
* 获取 请求 id
|
||||
*
|
||||
* @return 请求id
|
||||
*/
|
||||
@Nullable
|
||||
String getRequestId();
|
||||
|
||||
/**
|
||||
* 账号id
|
||||
*
|
||||
* @return 账号id
|
||||
*/
|
||||
@Nullable
|
||||
String getAccountId();
|
||||
|
||||
/**
|
||||
* 获取租户id
|
||||
*
|
||||
* @return 租户id
|
||||
*/
|
||||
@Nullable
|
||||
String getTenantId();
|
||||
|
||||
/**
|
||||
* 获取上下文中的数据
|
||||
*
|
||||
* @param ctxKey 上下文中的key
|
||||
* @return 返回对象
|
||||
*/
|
||||
@Nullable
|
||||
String get(String ctxKey);
|
||||
|
||||
/**
|
||||
* 获取上下文中的数据
|
||||
*
|
||||
* @param ctxKey 上下文中的key
|
||||
* @param function 函数式
|
||||
* @param <T> 泛型对象
|
||||
* @return 返回对象
|
||||
*/
|
||||
@Nullable
|
||||
<T> T get(String ctxKey, Function<String, T> function);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* HttpHeaders 获取器,用于跨服务和线程的传递,
|
||||
* <p>
|
||||
* 暂时不支持 webflux。
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public interface BladeHttpHeadersGetter {
|
||||
|
||||
/**
|
||||
* 获取 HttpHeaders
|
||||
*
|
||||
* @return HttpHeaders
|
||||
*/
|
||||
@Nullable
|
||||
HttpHeaders get();
|
||||
|
||||
/**
|
||||
* 获取 HttpHeaders
|
||||
*
|
||||
* @param request 请求
|
||||
* @return HttpHeaders
|
||||
*/
|
||||
@Nullable
|
||||
HttpHeaders get(HttpServletRequest request);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springblade.core.tool.utils.ThreadLocalUtil;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 多线程中传递 context 和 mdc
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class BladeRunnableWrapper implements Runnable {
|
||||
private final Runnable delegate;
|
||||
private final Map<String, Object> tlMap;
|
||||
/**
|
||||
* logback 下有可能为 null
|
||||
*/
|
||||
@Nullable
|
||||
private final Map<String, String> mdcMap;
|
||||
|
||||
public BladeRunnableWrapper(Runnable runnable) {
|
||||
this.delegate = runnable;
|
||||
this.tlMap = ThreadLocalUtil.getAll();
|
||||
this.mdcMap = MDC.getCopyOfContextMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!tlMap.isEmpty()) {
|
||||
ThreadLocalUtil.put(tlMap);
|
||||
}
|
||||
if (mdcMap != null && !mdcMap.isEmpty()) {
|
||||
MDC.setContextMap(mdcMap);
|
||||
}
|
||||
try {
|
||||
delegate.run();
|
||||
} finally {
|
||||
tlMap.clear();
|
||||
if (mdcMap != null) {
|
||||
mdcMap.clear();
|
||||
}
|
||||
ThreadLocalUtil.clear();
|
||||
MDC.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.core.context.props.BladeContextProperties;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.ThreadLocalUtil;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.springblade.core.tool.constant.BladeConstant.CONTEXT_KEY;
|
||||
|
||||
/**
|
||||
* blade servlet 上下文,跨线程失效
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
public class BladeServletContext implements BladeContext {
|
||||
private final BladeContextProperties contextProperties;
|
||||
private final BladeHttpHeadersGetter httpHeadersGetter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getRequestId() {
|
||||
return get(contextProperties.getHeaders().getRequestId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getAccountId() {
|
||||
return get(contextProperties.getHeaders().getAccountId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTenantId() {
|
||||
return get(contextProperties.getHeaders().getTenantId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String get(String ctxKey) {
|
||||
HttpHeaders headers = ThreadLocalUtil.getIfAbsent(CONTEXT_KEY, httpHeadersGetter::get);
|
||||
if (headers == null || headers.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return headers.getFirst(ctxKey);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T get(String ctxKey, Function<String, T> function) {
|
||||
String ctxValue = get(ctxKey);
|
||||
if (StringUtil.isBlank(ctxValue)) {
|
||||
return null;
|
||||
}
|
||||
return function.apply(ctxKey);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.core.context.props.BladeContextProperties;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* HttpHeaders 获取器
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
public class ServletHttpHeadersGetter implements BladeHttpHeadersGetter {
|
||||
private final BladeContextProperties properties;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HttpHeaders get() {
|
||||
HttpServletRequest request = WebUtil.getRequest();
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
return get(request);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HttpHeaders get(HttpServletRequest request) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
List<String> crossHeaders = properties.getCrossHeaders();
|
||||
// 传递请求头
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
if (headerNames != null) {
|
||||
List<String> allowed = properties.getHeaders().getAllowed();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String key = headerNames.nextElement();
|
||||
// 只支持配置的 header
|
||||
if (crossHeaders.contains(key) || allowed.contains(key)) {
|
||||
String values = request.getHeader(key);
|
||||
// header value 不为空的 传递
|
||||
if (StringUtil.isNotBlank(values)) {
|
||||
headers.add(key, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context.config;
|
||||
|
||||
import org.springblade.core.context.BladeContext;
|
||||
import org.springblade.core.context.BladeHttpHeadersGetter;
|
||||
import org.springblade.core.context.BladeServletContext;
|
||||
import org.springblade.core.context.ServletHttpHeadersGetter;
|
||||
import org.springblade.core.context.props.BladeContextProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* blade 服务上下文配置
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@EnableConfigurationProperties(BladeContextProperties.class)
|
||||
public class BladeContextAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public BladeHttpHeadersGetter bladeHttpHeadersGetter(BladeContextProperties contextProperties) {
|
||||
return new ServletHttpHeadersGetter(contextProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public BladeContext bladeContext(BladeContextProperties contextProperties, BladeHttpHeadersGetter httpHeadersGetter) {
|
||||
return new BladeServletContext(contextProperties, httpHeadersGetter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context.config;
|
||||
|
||||
import org.springblade.core.context.BladeHttpHeadersGetter;
|
||||
import org.springblade.core.context.listener.BladeServletRequestListener;
|
||||
import org.springblade.core.context.props.BladeContextProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* Servlet 监听器自动配置
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
public class BladeServletListenerConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletListenerRegistrationBean<?> registerCustomListener(BladeContextProperties properties,
|
||||
BladeHttpHeadersGetter httpHeadersGetter) {
|
||||
return new ServletListenerRegistrationBean<>(new BladeServletRequestListener(properties, httpHeadersGetter));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context.listener;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.slf4j.MDC;
|
||||
import org.springblade.core.context.BladeHttpHeadersGetter;
|
||||
import org.springblade.core.context.props.BladeContextProperties;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.ThreadLocalUtil;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import jakarta.servlet.ServletRequestEvent;
|
||||
import jakarta.servlet.ServletRequestListener;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Servlet 请求监听器
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class BladeServletRequestListener implements ServletRequestListener {
|
||||
private final BladeContextProperties contextProperties;
|
||||
private final BladeHttpHeadersGetter httpHeadersGetter;
|
||||
|
||||
@Override
|
||||
public void requestInitialized(ServletRequestEvent event) {
|
||||
HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
|
||||
// MDC 获取透传的 变量
|
||||
BladeContextProperties.Headers headers = contextProperties.getHeaders();
|
||||
String requestId = request.getHeader(headers.getRequestId());
|
||||
if (StringUtil.isNotBlank(requestId)) {
|
||||
MDC.put(BladeConstant.MDC_REQUEST_ID_KEY, requestId);
|
||||
}
|
||||
String accountId = request.getHeader(headers.getAccountId());
|
||||
if (StringUtil.isNotBlank(accountId)) {
|
||||
MDC.put(BladeConstant.MDC_ACCOUNT_ID_KEY, accountId);
|
||||
}
|
||||
String tenantId = request.getHeader(headers.getTenantId());
|
||||
if (StringUtil.isNotBlank(tenantId)) {
|
||||
MDC.put(BladeConstant.MDC_TENANT_ID_KEY, tenantId);
|
||||
}
|
||||
// 处理 context,直接传递 request,因为 spring 中的尚未初始化完成
|
||||
HttpHeaders httpHeaders = httpHeadersGetter.get(request);
|
||||
ThreadLocalUtil.put(BladeConstant.CONTEXT_KEY, httpHeaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDestroyed(ServletRequestEvent event) {
|
||||
// 会话销毁时,清除上下文
|
||||
ThreadLocalUtil.clear();
|
||||
// 会话销毁时,清除 mdc
|
||||
MDC.remove(BladeConstant.MDC_REQUEST_ID_KEY);
|
||||
MDC.remove(BladeConstant.MDC_ACCOUNT_ID_KEY);
|
||||
MDC.remove(BladeConstant.MDC_TENANT_ID_KEY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: DreamLu (596392912@qq.com)
|
||||
*/
|
||||
package org.springblade.core.context.props;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springblade.core.launch.constant.TokenConstant;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Headers 配置
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(BladeContextProperties.PREFIX)
|
||||
public class BladeContextProperties {
|
||||
/**
|
||||
* 配置前缀
|
||||
*/
|
||||
public static final String PREFIX = "blade.context";
|
||||
/**
|
||||
* 上下文传递的 headers 信息
|
||||
*/
|
||||
private Headers headers = new Headers();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Headers {
|
||||
/**
|
||||
* 请求id,默认:Blade-RequestId
|
||||
*/
|
||||
private String requestId = "Blade-RequestId";
|
||||
/**
|
||||
* 用于 聚合层 向调用层传递用户信息 的请求头,默认:Blade-AccountId
|
||||
*/
|
||||
private String accountId = "Blade-AccountId";
|
||||
/**
|
||||
* 用于 聚合层 向调用层传递租户id 的请求头,默认:Blade-TenantId
|
||||
*/
|
||||
private String tenantId = "Blade-TenantId";
|
||||
/**
|
||||
* 自定义 RestTemplate 和 Feign 透传到下层的 Headers 名称列表
|
||||
*/
|
||||
private List<String> allowed = Arrays.asList("X-Real-IP", "x-forwarded-for", "version", "VERSION", "authorization", "Authorization", TokenConstant.HEADER.toLowerCase(), TokenConstant.HEADER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取跨服务的请求头
|
||||
*
|
||||
* @return 请求头列表
|
||||
*/
|
||||
public List<String> getCrossHeaders() {
|
||||
List<String> headerList = new ArrayList<>();
|
||||
headerList.add(headers.getRequestId());
|
||||
headerList.add(headers.getAccountId());
|
||||
headerList.add(headers.getTenantId());
|
||||
headerList.addAll(headers.getAllowed());
|
||||
return headerList;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user