Как сделать HttpServletRequest доступным из другого потока?

Необходим доступ к текущему адресу, на котором расположен стоит веб-приложение.
Для этого используется HttpServletRequest, но в связи с тем, что необходим доступ из другого потока, возникают трудности.

Нашел информацию, что нужно добавить RequestContextListener
В конфигах приложения добавил бин
@Bean
	@ConditionalOnMissingBean(RequestContextListener.class)
	public RequestContextListener requestContextListener() {
		return new RequestContextListener();
	}

но ничего не изменилось, все та же ошибка о недоступности из другого потока.

также пробовал добавить данный Listner с помощью методов ниже, но тоже не было получено результата.
@Override
	protected void registerContextLoaderListener(ServletContext servletContext) {
		super.registerContextLoaderListener(servletContext);
		servletContext.addListener(new RequestContextListener());//To change body of generated methods, choose Tools | Templates.
	}

@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		servletContext.addListener(new RequestContextListener());
		super.onStartup(servletContext);
	}


Чем можно исправить или есть ли какие-нибудь альтернативные решения получения адреса, на котором стоит проект?
  • Вопрос задан
  • 582 просмотра
Пригласить эксперта
Ответы на вопрос 3
timych
@timych
Не очень понял - вам нужен context path вашего приложения или полный URL?
Если первое, то можно например сделать такой листенер :
@WebListener
public class MyApplicationLifeCicleListener implements ServletContextListener {
	@Override
	public void contextInitialized(ServletContextEvent event) {
              // cохраняем куда-нибудь путь
		System.out.println(event.getServletContext().getContextPath());
	}

	@Override
	public void contextDestroyed(ServletContextEvent event) {
	}
}


Если второе то как вариант такой костыль - делаем реквест-листенер

@WebListener
public class MyRequestListener extends RequestContextListener {

	@Override
	public void requestInitialized(ServletRequestEvent requestEvent) {
		super.requestInitialized(requestEvent);
		if (requestEvent.getServletRequest() instanceof HttpServletRequest) {
                        // cохраняем путь
			String url = ((HttpServletRequest) requestEvent.getServletRequest()).getRequestURL().toString();
			System.out.println(url);
		}
	}
}

И в первом и втором случае вам придется либо завести статическую переменную (можно прямо в листенере) для записи url. Либо класс-синглтон, который вам вернет нужное значение.
Но это конечно же костыль, так как для того чтобы к примеру получить URL во втором случае, нужно дождаться хотябы одного реквеста. Да и урл в зависимости от ресурса будет меняться.

А что вам мешает пользоваться HttpServletRequest в родном потоке?
И почему вы не знаете свой URL? (Можно его в какой-нибудь конфиг прописать)
У вас REST сервис или сервлеты?
Ответ написан
Комментировать
@gurinderu
java developer
Почитал я тут и понял, что вы делаете просто херню какую-то.
Хотите делать асинхронную посылку?
Делайте сервис и помечайте метод аннотацией async. Spring все сам разрулит.

Есть же миллион примеров https://spring.io/guides/gs/async-method/
Ответ написан
Комментировать
@Timrus161 Автор вопроса
А что вам мешает пользоваться HttpServletRequest в родном потоке?

вешаем аннотацию для отправки писем. она отправляет в другом потоке.
И почему вы не знаете свой URL? (Можно его в какой-нибудь конфиг прописать)

это не очень удобно при переездах и при дев/релиз сборках
У вас REST сервис или сервлеты?

рест

@WebListener
public class MyRequestListener extends RequestContextListener {

  @Override
  public void requestInitialized(ServletRequestEvent requestEvent) {
    super.requestInitialized(requestEvent);
    if (requestEvent.getServletRequest() instanceof HttpServletRequest) {
                        // cохраняем путь
      String url = ((HttpServletRequest) requestEvent.getServletRequest()).getRequestURL().toString();
      System.out.println(url);
    }
  }
}

больше нигде ничего указывать не надо?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы