如何从当前请求通过外部拦截器向外部客户机添加动态头值?

t8e9dugd  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(478)

我是新来的Spring云开放外交。我正在尝试建立一个基于微服务的系统。为了使事情看起来更简单,只需使用其中的3个服务,即gateway、service-a和service-b。当我通过网关从前端向service-a发出请求时,网关将验证请求中的jwt令牌,并从令牌中提取用户信息(userid),将请求作为报头放入并转发给service-a。现在service-a将通过外部客户机调用service-b。现在,在通过外部客户机进行服务间调用的过程中,我正在尝试通过外部requestiterceptor将userid从serie-a中的当前请求转发到service-b中的传出请求。但我无法在拦截器中检索当前请求。我试过这个问题的答案,但似乎不起作用。我想我面临的问题和这个gitu问题一样。我可以看到一些博客和文章建议使用requestcontextlistner或requestcontextfilter从DispatcherServlet获取当前请求,但我找不到如何使用或实现它。下面是我目前使用的代码

@Component
public class ProxyInterceptor implements RequestInterceptor {

        private final static Logger LOGGER = LoggerFactory.getLogger(ProxyInterceptor.class);

        @Override
        public void apply(RequestTemplate requestTemplate) {

                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                        .getRequest();

                String userId = request.getHeader("userId");
                LOGGER.info("userId {}", userId);

                if (Optional.ofNullable(userId).isPresent()) {
                        requestTemplate.header(USER_ID_REQUEST_HEADER_VARIABLE, userId);
                }
        }
}

从属关系

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
            <groupId>org.springframework.cloud</groupId>                     
            <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>

hoxton.sr8</spring cloud.version>
此代码引发nullpointer异常,因为requestcontextholder.getrequestattributes()返回null。你知道怎么解决这个问题吗?

kuhbmx9i

kuhbmx9i1#

我有类似的用例,需要在拦截器中获取头。代码如下所示。

circuitBreakerFactory
                    .create("createUserProfile").run(
                            () -> {
                                    String resp = callerClient.callExternalService();
                                    return resp;

                            }, exception -> {
                                    logger.info(exception.getMessage());
                            }
                    );

问题是run方法中的第一个参数是lambda函数,因此会创建一个新线程。这个新线程没有处理请求的前一个线程的请求上下文信息。
将以下bean添加到配置中,然后新线程将继承请求上下文。因此,requestcontextholder.getrequestattributes()不会返回null。

@Bean
   DispatcherServlet dispatcherServlet() {
       DispatcherServlet servlet = new DispatcherServlet();
       servlet.setThreadContextInheritable(true);
       return servlet;
   }

你可以参考这个对我帮助很大的答案。

相关问题