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 里面仍然通用。