Предполагая, что URL-адрес http://localhost:8080/project-name/resource.xhtml,
Я хочу получить следующее http://localhost:8080/project-name в управляемом JSF bean.
Предполагая, что URL-адрес http://localhost:8080/project-name/resource.xhtml,
Я хочу получить следующее http://localhost:8080/project-name в управляемом JSF bean.
Я предполагаю, что вы используете 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-адреса.Вы можете получить его следующим образом:
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 является сигналом запаха кода.
Вы можете избежать зависимостей от контейнера, используя 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-интерфейсам.
Лучший способ - получить доступ к атрибутам 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']}" />