Подтвердить что ты не робот

Как получить URL-адрес запроса в управляемом jsf bean без запрошенного сервлета?

Предполагая, что URL-адрес http://localhost:8080/project-name/resource.xhtml,

Я хочу получить следующее http://localhost:8080/project-name в управляемом JSF bean.

4b9b3361

Ответ 1

Я предполагаю, что вы используете JSF 2 и Java EE 6 для этого ответа.

Реализация фактического механизма будет зависеть от того, в какой степени вам понадобится исходный URL.

Сначала вам нужно получить доступ к базовому контейнеру сервлета (предположительно одному, а не контейнеру портлета), созданному объектом HttpServletRequest. Используйте объект FacesContext для доступа к объекту HttpServletRequest следующим образом:

HttpServletRequest origRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();

Класс HttpServletRequest предоставляет несколько методов утилиты для получения близкого представления исходного запроса:

  • getRequestURL(), который предоставляет исходный запрос без строки запроса
  • getScheme, getServerName, getServerPort, getContextPath, getServletPath, getPathInfo и getQueryString все выходы могут быть объединены последовательно для получения исходного запроса. Возможно, вам придется опустить последние вызовы, если вам нужен меньший фрагмент URL-адреса.

Ответ 2

Вы можете получить его следующим образом:

HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String url = req.getRequestURL().toString();
return url.substring(0, url.length() - req.getRequestURI().length()) + req.getContextPath() + "/";
// ...

Обратите внимание, что, возможно, существуют лучшие способы достижения этого требования. Получение необработанного API сервлета внутри управляемого JSF bean является сигналом запаха кода.

Ответ 3

Вы можете избежать зависимостей от контейнера, используя ExternalContext в виде такой формы:

public String getApplicationUri() {
  try {
    FacesContext ctxt = FacesContext.getCurrentInstance();
    ExternalContext ext = ctxt.getExternalContext();
    URI uri = new URI(ext.getRequestScheme(),
          null, ext.getRequestServerName(), ext.getRequestServerPort(),
          ext.getRequestContextPath(), null, null);
    return uri.toASCIIString();
  } catch (URISyntaxException e) {
    throw new FacesException(e);
  }
}

Однако обратите внимание, что этот код может быть не полностью агрегирован для контейнера - некоторые из этих методов бросают UnsupportedOperationException в их реализацию по умолчанию. Этот код основан на методах JSF 2.0.

Следует также отметить, что использование URI, подобного этому в качестве базы, не является правильным способом ссылаться на ресурс в вашем приложении в общем случае; ViewHandler и ExternalContext должны использоваться совместно для создания URL ресурсов для обращения к ресурсам приложений для извлечения ресурсов или URL-адресов действий для вызова жизненного цикла JSF, например.

К сожалению, я не думаю, что существует общий, контейнерно-агностический способ сделать все, что вы, возможно, захотите сделать в приложении JSF, поэтому иногда вы зависите от реализации, и у вас мало выбора, кроме как сбрасывать к другим API-интерфейсам.

Ответ 4

Лучший способ - получить доступ к атрибутам ExternalContext RequestHeaderMap.

    ExternalContext ext = FacesContext.getCurrentInstance().getExternalContext();
    Map<String,String> requestHeader = ext.getRequestHeaderMap();
    urlRefered = requestHeader.get("referer");

Вы можете сохранить атрибут urlRefered в своем bean и обработать на своей странице xhtml следующим образом:

<h:outputText value="#{notFoundBean.urlRefered}

Не забывайте также отображать свою страницу ошибок в файле web.xml.

<error-page>
    <error-code>404</error-code>
    <location>/xhtml/pg/error/404.xhtml</location>
</error-page>

С другой стороны вы также можете получить его из этой строки непосредственно на страницу xhtml:

<h:outputText value="#{requestScope['javax.servlet.forward.request_uri']}" />