下面我将分场景、分环境(Servlet 原生 API vs. Spring Boot)为你详细讲解如何获取这些信息。

核心概念:HttpServletRequest 对象
获取 URL 的所有信息都依赖于 javax.servlet.http.HttpServletRequest 这个对象,在标准的 Servlet 应用中,你通常通过控制器方法的参数来接收它。
import javax.servlet.http.HttpServletRequest;
public class MyController {
public void handleRequest(HttpServletRequest request) {
// 在这里使用 request 对象获取 URL 信息
}
}
在 Spring Boot 中,这个过程被简化了,你只需要在方法参数中声明 HttpServletRequest,Spring 会自动为你注入。
获取 URL 的各个组成部分
HttpServletRequest 提供了一系列方法来获取 URL 的不同部分,我们用一个示例 URL 来演示:
https://www.example.com:8080/path/to/resource?name=John&age=30#section1

注意: 及其后面的部分(section1)是片段标识符(Fragment Identifier),它不会发送到服务器,因此无法通过 HttpServletRequest 获取。
| 目标信息 | Servlet API 方法 | 示例 URL 中的值 | 说明 |
|---|---|---|---|
| 完整的请求 URI (包含协议、主机、端口、路径、查询参数) | request.getRequestURL() |
https://www.example.com:8080/path/to/resource?name=John&age=30 |
返回一个 StringBuffer,包含从协议到查询字符串的所有内容。这是最常用的获取完整 URL 的方式。 |
| 请求路径 (不包含查询参数) | request.getRequestURI() |
/path/to/resource |
返回请求的 URI 部分,不包含查询参数。 |
| 查询字符串 | request.getQueryString() |
name=John&age=30 |
返回 后面的字符串,不包含 本身,如果没有查询参数,返回 null。 |
| 协议 | request.getScheme() |
https |
返回请求的协议,如 http 或 https。 |
| 服务器名称 | request.getServerName() |
www.example.com |
返回请求头 Host 中的主机名。 |
| 服务器端口 | request.getServerPort() |
8080 |
返回请求的端口号。 |
| 上下文路径 | request.getContextPath() |
(可能为空字符串 ) | 返回当前应用的上下文路径,如果应用部署在 myapp 下,则此处为 /myapp,在 Spring Boot 的嵌入式容器中,默认通常是空字符串。 |
| Servlet 路径 | request.getServletPath() |
(可能为空字符串 ) | 返回匹配到 Servlet 的路径部分,在 Spring MVC 中,这通常与 @RequestMapping 的路径相关,但直接使用较少。 |
代码示例
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Enumeration;
public class UrlInfoExtractor {
public void printUrlInfo(HttpServletRequest request) {
// 1. 获取完整的请求 URL (最常用)
StringBuffer requestUrl = request.getRequestURL();
System.out.println("1. Request URL: " + requestUrl.toString());
// 2. 获取请求 URI (路径部分)
String requestUri = request.getRequestURI();
System.out.println("2. Request URI: " + requestUri);
// 3. 获取查询字符串
String queryString = request.getQueryString();
System.out.println("3. Query String: " + (queryString == null ? "N/A" : queryString));
// 4. 获取协议
String scheme = request.getScheme();
System.out.println("4. Scheme: " + scheme);
// 5. 获取服务器名称
String serverName = request.getServerName();
System.out.println("5. Server Name: " + serverName);
// 6. 获取服务器端口
int serverPort = request.getServerPort();
System.out.println("6. Server Port: " + serverPort);
// 7. 获取上下文路径
String contextPath = request.getContextPath();
System.out.println("7. Context Path: " + (contextPath.isEmpty() ? "\"\"" : contextPath));
// 8. 获取Servlet路径
String servletPath = request.getServletPath();
System.out.println("8. Servlet Path: " + (servletPath.isEmpty() ? "\"\"" : servletPath));
// 9. 获取所有请求头 (可以看到 Host 头)
System.out.println("\n--- Request Headers ---");
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ": " + request.getHeader(headerName));
}
}
}
不同环境下的使用方法
标准 Servlet 环境
如果你在使用原生的 Servlet API,比如在一个 HttpServlet 的 doGet 或 doPost 方法中。
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 直接使用 req 对象
String fullUrl = req.getRequestURL().toString();
String query = req.getQueryString();
System.out.println("Full URL: " + fullUrl);
System.out.println("Query: " + query);
resp.getWriter().write("URL information printed to console.");
}
}
Spring Boot / Spring MVC 环境
在 Spring Boot 中,这变得非常简单,你只需要在 Controller 的方法参数中声明 HttpServletRequest。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class MySpringController {
@GetMapping("/api/info")
public String getUrlInfo(HttpServletRequest request) {
// 创建一个 StringBuilder 来构建响应
StringBuilder response = new StringBuilder();
response.append("Full Request URL: ").append(request.getRequestURL()).append("<br>");
response.append("Request URI: ").append(request.getRequestURI()).append("<br>");
response.append("Query String: ").append(request.getQueryString() == null ? "N/A" : request.getQueryString()).append("<br>");
response.append("Scheme: ").append(request.getScheme()).append("<br>");
response.append("Server Name: ").append(request.getServerName()).append("<br>");
response.append("Server Port: ").append(request.getServerPort()).append("<br>");
response.append("Context Path: ").append(request.getContextPath()).append("<br>");
return response.toString();
}
}
当你访问 http://localhost:8080/api/info?name=test 时,浏览器会显示类似下面的内容:

Full Request URL: http://localhost:8080/api/info
Request URI: /api/info
Query String: name=test
Scheme: http
Server Name: localhost
Server Port: 8080
Context Path:
常见问题与注意事项
如何获取不含查询参数的完整 URL?
这是一个非常常见的需求。getRequestURL() 返回包含查询参数的 URL,而 getRequestURI() 不包含,我们可以将两者结合起来。
// HttpServletRequest request
StringBuffer urlBuffer = request.getRequestURL(); // 不包含查询参数
String queryString = request.getQueryString(); // 只包含查询参数
String fullUrlWithoutQuery = urlBuffer.toString();
if (queryString != null) {
fullUrlWithoutQuery += "?" + queryString;
}
// 如果只想获取不含查询参数的 URL,直接使用 getRequestURL() 即可
String urlWithoutQuery = request.getRequestURL().toString();
getContextPath() 在 Spring Boot 中为什么是空的?
在 Spring Boot 的嵌入式 Tomcat (Jetty, Undertow) 中,应用通常部署在根路径 下。getContextPath() 返回一个空字符串 ,如果你的应用被部署在传统的 Servlet 容器(如 Tomcat)的某个子路径下(myapp),getContextPath() 就会返回 /myapp。
如何处理中文或特殊字符?
URL 中的路径和查询参数可能会包含非 ASCII 字符(如中文),这些字符在传输时通常会被URL编码(空格 -> %20,中 -> %E4%B8%AD)。
request.getRequestURI()和request.getRequestURL()返回的是已经解码的字符串,如果你需要原始的、编码后的字符串,你需要从请求头或路径中手动处理,但这通常不必要。- 如果你想获取原始的、未经解码的查询字符串,
request.getQueryString()返回的就是编码后的字符串。 - 如果你想手动解码一个字符串,可以使用
java.net.URLDecoder:
import java.net.URLDecoder; import java.nio.charset.StandardCharsets; String encodedValue = "E4%B8%AD%E6%96%87"; String decodedValue = URLDecoder.decode(encodedValue, StandardCharsets.UTF_8.name()); // decodedValue 现在是 "中文"
| 你的目标 | 推荐方法 |
|---|---|
| 获取完整的请求 URL (包含查询参数) | request.getRequestURL().toString() |
| 获取请求路径 (不包含查询参数) | request.getRequestURI() |
| 获取查询字符串 (不包含 ) | request.getQueryString() |
| 获取协议、主机、端口等 | 分别使用 getScheme(), getServerName(), getServerPort() |
| 在 Spring Boot 中获取 | 直接在 Controller 方法参数中注入 HttpServletRequest |
