简体   繁体   English

如何在没有请求的servlet的情况下在jsf托管bean中获取请求URL?

[英]How do I get request url in jsf managed bean without the requested servlet?

Assuming the URL is http://localhost:8080/project-name/resource.xhtml , 假设URL是http:// localhost:8080 / project-name / resource.xhtml

I want to obtain the following http://localhost:8080/project-name in a JSF managed bean. 我想在JSF托管bean中获取以下http:// localhost:8080 / project-name

I'll assume that you are using JSF 2 and Java EE 6 for this answer. 我假设您正在使用JSF 2和Java EE 6来获得此答案。

The implementation of the actual mechanism will vary depending on the extent to which you'll need the original URL. 实际机制的实现将根据您需要原始URL的程度而有所不同。

You'll first need to get access to the underlying servlet container (assumed to one, instead of a portlet container) produced HttpServletRequest object. 您首先需要访问底层的servlet容器(假设为一个,而不是一个portlet容器)生成HttpServletRequest对象。 Use the FacesContext object to access the HttpServletRequest object in the following manner: 使用FacesContext对象以下列方式访问HttpServletRequest对象:

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

The HttpServletRequest class provides several utility methods to obtain a near representation of the original request: HttpServletRequest类提供了几种实用程序方法来获取原始请求的近似表示:

  • getRequestURL() , which provides the original request sans the query string getRequestURL() ,它提供原始请求sans查询字符串
  • getScheme , getServerName , getServerPort , getContextPath , getServletPath , getPathInfo and getQueryString all of whose outputs can be combined in sequence to obtain the original request. getSchemegetServerNamegetServerPortgetContextPathgetServletPathgetPathInfogetQueryString所有输出都可以按顺序组合以获得原始请求。 You may have to omit the latter invocations if you want a lesser fragment of the URL. 如果您想要URL的较小片段,则可能必须省略后面的调用。

You can get it as follows: 您可以按如下方式获得:

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

Note that there are possibly better ways to achieve the requirement. 请注意,可能有更好的方法来实现这一要求。 Getting the raw Servlet API inside a JSF managed bean is a code smell alarm. 在JSF托管bean中获取原始Servlet API是一种代码异味警报。

You can avoid container-specific dependencies by using the ExternalContext in something like this form: 您可以通过使用类似以下形式的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);
  }
}

However, note that this code may not be entirely container-agnostic - some of those methods throw an UnsupportedOperationException in their default implementation. 但请注意,此代码可能不完全与容器无关 - 其​​中一些方法在其默认实现中抛出UnsupportedOperationException This code relies on JSF 2.0 methods. 此代码依赖于JSF 2.0方法。

You should also note that using a URI like this as a base is not the correct way to refer to a resource in your application in the general case; 您还应该注意,在一般情况下,使用这样的URI作为基础并不是在应用程序中引用资源的正确方法; the ViewHandler and ExternalContext should be used in concert to create resource URLs for referring to application resources to fetch resources or action URLs for invoking the JSF lifecycle, for example. 例如, ViewHandlerExternalContext应该协同使用,以创建用于引用应用程序资源的资源URL,以获取用于调用JSF生命周期的资源或操作URL。

Unfortunately, I don't think there is a general, container-agnostic way to do everything you might want to do in a JSF app, so sometimes you're dependent on the implementation and you have little choice but to cast down to other APIs. 不幸的是,我认为在JSF应用程序中执行您可能想做的所有操作并不存在与容器无关的一般方法,所以有时您依赖于实现,除了转向其他API之外别无选择。

The best way is to access to the ExternalContext RequestHeaderMap attributes. 最好的方法是访问ExternalContext RequestHeaderMap属性。

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

You could save the urlRefered attribute in your bean and process in your xhtml page as following: 您可以在您的bean中保存urlRefered属性并在xhtml页面中处理如下:

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

Don't forget mapping your error page in your web.xml file too. 不要忘记在web.xml文件中映射错误页面。

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

By other side you also could get it from this line directly to the xhtml page: 另一方面,您也可以从此行直接获取它到xhtml页面:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM