Получение объекта запроса в Spring Webflux elasti c thread - PullRequest
0 голосов
/ 16 апреля 2020

Я столкнулся с одной проблемой. Я вызываю некоторые API параллельно, используя Spring Webflux. Если какой-либо дочерний поток сталкивается с какой-либо проблемой, он должен зарегистрировать запрос. Теперь проблема заключается в регистрации нормального класса POJO, в котором есть метод stati c, который получает компонент через ApplicationContent и сохраняет данные в очереди.

Теперь проблема в том, что я хочу получить доступ параметры запроса, такие как Request URL / Controller et c. Я пробовал

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.RELEASE .

1 Ответ

0 голосов
/ 16 апреля 2020

Существует несколько причин, по которым ваша реализация не работает.

Webflux является независимой от потоков c, что означает, что любой поток может иметь дело с чем угодно в любое время в приложении. Если приложение посчитает эффективным переключение текущего исполняющего потока, оно сделает это.

Приложения сервлетов, с другой стороны, назначают один поток каждому запросу и придерживаются этого потока во время выполнения.

ApplicationContext использует, как вы видите, ServletRequests, поэтому его нельзя использовать в приложении Webflux. В свою очередь, он использует threadlocal для хранения объекта запроса в указанном потоке.

В webflux вы не можете использовать threadlocal, bucase, как только приложение переключает потоки, все в threadlocal исчезает. Вот почему вы получаете ноль.

Итак, как вы передаете данные из потока в поток.

Что вам нужно сделать, это реализовать фильтр, который перехватывает запрос, извлекает необходимую информацию и помещает его в объект реактивного контекста.

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

Это сообщение, посвященное проблеме.

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

...