HttpServletRequest API 提供了若干方法返回地址信息,使得我们可以了解请求信息如何。我们逐一看看哪些是需要的。
方法名:返回值 |
含义 |
getScheme():String |
返回请求协议,如 http or https |
getServerName():String |
返回服务器名称,即主机名,可能是 ip 或域名 |
getServerPort():int |
返回请求服务器的端口 |
由此,我们可以给出一方法,得出请求地址的前缀。
/**
* 网站域名=协议+主机名+端口(如果为 80 端口的话就默认不写 80)
*
* @return 网站名称
*/
public String getServerPath() {
String prefix = getScheme() + "://" + getServerName();
int port = getServerPort();
if (port != 80)
prefix += ":" + port;
return prefix;
}
方法内默认 this 对象为 HttpServletRequest 类型,下面相同。
不过这个方法是不完整的,只是得到完整 url 的前缀。怎么获取完整的前缀呢?我们可以通过 getRequestURI()、getQueryString() 返回网址剩余部分。
/**
* 获取本页 URL,有时可能要对 url redirectUri = java.net.URLEncoder.encode(redirectUri, "utf-8");
*
* @param isFull
* 是否把 QueryString 参数都带进去?
* @return 本页地址
*/
public String getCurrentPageUrl(boolean isFull) {
String url = getServerPath() + getRequestURI();
if (isFull)
url += '?' + getQueryString();
return url;
}
有时候我们只是需要网站名称和项目所在名称,两者一起——这时候 getContextPath() 方法就派上用场了,它的作用是返回当前项目的目录名。
/**
* 网站域名+项目目录
*
* @return 比较完整的 url 但不是最完整的,最完整的见上个方法
*/
public String getBasePath() {
return getServerPath() + getContextPath();
}
不知道大家还记得微软 ASP 时代的 Server.Mappath 方法吗?它可以把指定的路径影射到服务器上相应的物理路径上,非常有用。现在我们在 JSP 上也弄一个。
/**
* 输入一个相对地址,补充成为绝对地址 相对地址转换为绝对地址,并转换斜杠
*
* @param relativePath
* 相对地址
* @return 绝对地址
*/
public String Mappath(String relativePath) {
String absolute = getServletContext().getRealPath(relativePath); // 绝对地址
if (absolute != null)
absolute = absolute.replace('\\', '/');
return absolute;
}
在写 Servlet MVC 的时候(request.getRequestDispatcher(path).forward(request, response)),JSP 模版虽然可以得到 request 等的对象,但是某些属性还是以 JSP 模板路径为准的,并不是 Servlet 请求的路径。为此,我们可以通过获取 JSP 变量 javax.servlet.forward.request_uri 得到真实的请求路径。
/**
* 获取原请求的 uri,而非模版所在的 uri
*/
@Override
public String getRequestURI() {
Object obj = getAttribute("javax.servlet.forward.request_uri");
if (obj != null && !StringUtil.isEmptyString((String) obj)) {
return (String) obj;
} else {
return super.getRequestURI();// 直接 jsp 的
}
}
获取请求者 ip 则是如下。
/**
* 获取请求的 IP 地址
* @return IP 地址
*/
public String getIP() {
String s = getHeader("X-Forwarded-For"), unknown = "unknown";
if (StringUtil.isEmptyString(s) || unknown.equalsIgnoreCase(s))
s = getHeader("Proxy-Client-IP");
if (StringUtil.isEmptyString(s) || unknown.equalsIgnoreCase(s))
s = getHeader("WL-Proxy-Client-IP");
if (StringUtil.isEmptyString(s) || unknown.equalsIgnoreCase(s))
s = getHeader("HTTP_CLIENT_IP");
if (StringUtil.isEmptyString(s) || unknown.equalsIgnoreCase(s))
s = getHeader("HTTP_X_FORWARDED_FOR");
if (StringUtil.isEmptyString(s) || unknown.equalsIgnoreCase(s))
s = getRemoteAddr();
return s;
}
需要注意的是,本文虽然说的在 JSP 环境下,但实际上在 Servlet 里面仍然通用。