Я хочу сделать текущий запрос доступным для дочерних потоков, не передавая исходный запрос в качестве параметров метода через несколько слоев. Приложение работает как сервлет, так и портлет.
Обычно DispatcherServlet и DispatcherPortlet задают текущий запрос в RequestContextHolder для текущего потока. Таким образом, поток вызовов имеет доступ к текущему запросу. Запрос не распространяется на дочерние потоки.
В моем случае запрос порождает subthread, где он вызывает вызов ReST с использованием RestTemplate, и мне нужно получить доступ к исходному запросу в ClientHttpRequestInterceptor, который перехватывает RestTemplate. Запрос, передаваемый на перехват, бесполезен, мне нужен исходный запрос, который попадает на сервер.
И DispatcherServlet, и DispatcherPortlet имеют функцию передать запрос RequestContext дочерним потокам: setThreadContextInheritable (true). Однако, кажется, не так просто установить этот флаг в true. Не существует init-param, который устанавливает его, и обычно вы указываете их в файле web.xml или portlet.xml.
Есть ли способ настроить портлет диспетчера или сервлет через их сеттеры, используя конфигурацию xml? Единственный способ, который я нашел, - написать собственный диспетчерский портлет/портлет, который устанавливает флаг в true и использует его в web.xml и portlet.xml.
Невозможно сделать это напрямую через конфигурацию XML. Вам нужно будет сделать так, как вы сказали, и создать подкласс DispatcherServlet
который внутренне вызывает setThreadContextInheritable(true)
.
Альтернативой является выполнение конфигурации ServletContext
в Java. Spring предоставляет WebApplicationInitializer
и ряд полезных подтипов, где вы можете зарегистрировать настроенный DispatcherServlet
(другие сервлеты и фильтры).
Вы создали бы свой экземпляр.
DispatcherServlet servlet = new DispatcherServlet(context);
servlet.setThreadContextInheritable(true);
и затем зарегистрировать его
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", servlet);