1

我面临一个问题。我正在使用 Spring Webflux 并行调用一些 API。如果任何子线程遇到任何问题,它需要记录请求。现在的问题是,用于记录普通 POJO 类,其中有一个静态方法,该方法通过 ApplicationContent 获取 bean 并将数据存储在队列中。

现在的问题是,我想访问请求参数,如请求 URL / 控制器等。我试过了

ServletRequestAttributes sra = 
        (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
                    logger.error("====="+sra);
                    HttpServletRequest httpRequest = sra.getRequest();

但在这种情况下,sra为空。我尝试添加以下代码,

@Configuration
public class InheritableRequestContextListener extends RequestContextListener {
    private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
        InheritableRequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";

    @Override
    public void requestInitialized(ServletRequestEvent requestEvent) {
        System.out.println("111111111111111111");
        if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
            throw new IllegalArgumentException(
                    "Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
        }
        HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
        ServletRequestAttributes attributes = new ServletRequestAttributes(request);
        request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
        LocaleContextHolder.setLocale(request.getLocale());
        RequestContextHolder.setRequestAttributes(attributes, true);
    }
}

但这无济于事。任何人都可以帮忙。我正在使用 springboot 版本;2.0.2 .发布。

4

1 回答 1

3

有几个原因导致您的实施不起作用。

Webflux 与线程无关,这意味着任何线程都可以随时处理应用程序中的任何事情。如果应用程序发现切换当前正在执行的线程很有效,它就会这样做。

另一方面,Servlet 应用程序为每个请求分配一个线程,并在整个执行过程中坚持使用该线程。

如您所见,ApplicationContext 使用 ServletRequests,因此它在 Webflux 应用程序中不可用。它又使用 threadlocal 将请求对象存储到指定线程。

在 webflux 中,您不能使用 threadlocal,一旦应用程序切换线程,则 threadlocal 中的所有内容都消失了。这就是你得到空值的原因。

那么如何在线程之间传递数据。

您需要做的是实现一个过滤器来拦截请求,提取您想要的信息并将其放置在反应式上下文对象中。

https://projectreactor.io/docs/core/release/reference/#context

这是解决问题的帖子。

https://developpaper.com/implementation-of-requestcontextholder-in-spring-boot-webflux/

于 2020-04-16T15:38:07.323 回答