杰瑞科技汇

Java request 信息如何高效获取与解析?

  1. 核心概念:什么是 Request 对象?
  2. 获取 Request 对象的几种方式 (在不同框架中)
  3. Request 对象包含的核心信息分类与获取方法
  4. 一个完整的代码示例
  5. 进阶:Request Body 的读取与处理

核心概念:什么是 Request 对象?

在 Java Web 开发中,Request 对象是一个服务器端创建的、代表客户端 HTTP 请求的 Java 对象,它封装了请求中的所有信息,包括请求头、请求参数、请求方法、请求路径、Cookie 等,通过这个对象,服务器端的程序可以“读懂”客户端的意图,并做出相应的处理。

Java request 信息如何高效获取与解析?-图1
(图片来源网络,侵删)

最原始和核心的 Request 对象是 HttpServletRequest,它是在 Java Servlet API 中定义的,现代的 Web 框架(如 Spring MVC)对其进行了进一步的封装和简化,但其底层原理都是基于 HttpServletRequest


获取 Request 对象的几种方式

获取 Request 对象的方式取决于你使用的框架。

a. 原生 Servlet 环境

doGetdoPost 方法中,容器(如 Tomcat)会自动将 requestresponse 对象作为参数传入。

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // 在这里直接使用 request 对象
    String method = request.getMethod();
    // ...
}

b. Spring MVC 环境

在 Spring MVC 中,你可以通过多种方式获取 HttpServletRequest

Java request 信息如何高效获取与解析?-图2
(图片来源网络,侵删)

直接作为 Controller 方法的参数

这是最常用、最推荐的方式,Spring 会自动将当前的 request 对象注入到你的方法参数中。

import jakarta.servlet.http.HttpServletRequest; // Spring Boot 3.x 使用 jakarta
// import javax.servlet.http.HttpServletRequest; // Spring 2.x 使用 javax
@Controller
public class MyController {
    @GetMapping("/info")
    public String getInfo(HttpServletRequest request) {
        // 直接使用 request 对象
        String userAgent = request.getHeader("User-Agent");
        System.out.println("User-Agent: " + userAgent);
        return "some-view";
    }
}

使用 @Autowired 注入

如果你需要在 Service 层或其他非 Controller 组件中使用 request,可以通过 @Autowired 注入一个代理对象。

Java request 信息如何高效获取与解析?-图3
(图片来源网络,侵删)
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;
@Service
public class MyService {
    public void doSomething() {
        // 从当前线程的上下文中获取 request
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 使用 request...
        String sessionId = request.getSession().getId();
    }
}

通过 WebRequest 接口

WebRequest 是 Spring 提供的一个更通用的接口,它不直接绑定到 Servlet API,使得代码更容易测试。

import org.springframework.web.context.request.WebRequest;
@Controller
public class MyController {
    @GetMapping("/data")
    public String getData(WebRequest webRequest) {
        // WebRequest 提供了类似的方法,但更通用
        String paramValue = webRequest.getParameter("param");
        return "some-view";
    }
}

Request 对象包含的核心信息分类与获取方法

下面我们详细拆解 HttpServletRequest 对象中包含的信息,并提供获取它们的代码示例。

a. 请求行信息

这是请求的第一行,包含了请求方法、URI 和协议版本。

信息项 获取方法 示例
请求方法 request.getMethod() GET, POST, PUT
请求URI request.getRequestURI() /user/profile
请求URL request.getRequestURL() http://localhost:8080/user/profile
协议版本 request.getProtocol() HTTP/1.1
查询字符串 request.getQueryString() name=John&age=30

b. 请求头信息

客户端发送的元数据,如 User-Agent, Accept, Content-Type 等。

获取方法 说明
String getHeader(String name) 获取指定名称的请求头值。
Enumeration<String> getHeaderNames() 获取所有请求头的名称。
Enumeration<String> getHeaders(String name) 获取指定名称请求头的所有值(一个头可以有多个值)。

示例代码:

// 获取单个请求头
String userAgent = request.getHeader("User-Agent");
System.out.println("User-Agent: " + userAgent);
// 获取所有请求头
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
    String headerName = headerNames.nextElement();
    System.out.println(headerName + ": " + request.getHeader(headerName));
}

c. 请求参数

这部分信息通常来自 URL 的查询字符串 (?key=value) 或 POST 请求的表单数据。

获取方法 说明
String getParameter(String name) 获取指定名称的参数值,如果参数不存在,返回 null
Map<String, String[]> getParameterMap() 获取一个包含所有参数的 Map,键是参数名,值是字符串数组(支持同名多值)。
Enumeration<String> getParameterNames() 获取所有参数的名称。
String[] getParameterValues(String name) 获取指定名称参数的所有值(数组形式)。

示例代码: 假设请求 URL 是 http://localhost:8080/search?q=java&page=1

// 获取单个参数
String query = request.getParameter("q"); // 值为 "java"
String page = request.getParameter("page"); // 值为 "1"
// 获取所有参数
Map<String, String[]> paramsMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) {
    System.out.println("Param: " + entry.getKey() + ", Values: " + Arrays.toString(entry.getValue()));
}
// 输出:
// Param: q, Values: [java]
// Param: page, Values: [1]

d. 请求体信息

对于 POSTPUT 请求,数据通常放在请求体中,JSON、XML 或表单数据。

  • 获取 Content-Type: request.getContentType()
  • 获取 Content-Length: request.getContentLength()
  • 获取请求体流: request.getInputStream()request.getReader()

⚠️ 重要提示: 请求体流只能被读取一次,读取后,流中的数据就被消耗掉了,后续代码再读取将得到空数据,对于需要多次或深入解析请求体的框架(如 Spring),它们通常会先读取并缓存请求体,然后提供一个更高级的 API(如 @RequestBody 注解)来方便开发者使用。

e. Cookie 信息

获取方法 说明
Cookie[] getCookies() 获取一个包含所有 Cookie 对象的数组。

示例代码:

Cookie[] cookies = request.getCookies();
if (cookies != null) {
    for (Cookie cookie : cookies) {
        System.out.println("Cookie Name: " + cookie.getName());
        System.out.println("Cookie Value: " + cookie.getValue());
    }
}

f. 其他重要信息

信息项 获取方法 说明
客户端 IP 地址 request.getRemoteAddr() 获取发起请求的客户端的 IP 地址。
服务器名称 request.getServerName() 获取服务器的主机名,如 localhost
服务器端口 request.getServerPort() 获取服务器接收请求的端口号,如 8080
请求的上下文路径 request.getContextPath() 获取 Web 应用的根路径,如 /myapp

一个完整的代码示例

这是一个 Spring Boot Controller,它展示了如何获取上述大部分信息。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
@Controller
public class RequestInfoController {
    @GetMapping("/show-request")
    public String showRequestInfo(HttpServletRequest request) {
        System.out.println("======================================");
        System.out.println("         Request Information          ");
        System.out.println("======================================");
        // 1. 请求行信息
        System.out.println("Method: " + request.getMethod());
        System.out.println("Request URI: " + request.getRequestURI());
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Protocol: " + request.getProtocol());
        System.out.println("Query String: " + request.getQueryString());
        System.out.println("---");
        // 2. 请求头信息
        System.out.println("Headers:");
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            System.out.println("  " + headerName + ": " + request.getHeader(headerName));
        }
        System.out.println("---");
        // 3. 请求参数信息
        System.out.println("Parameters:");
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            System.out.println("  " + entry.getKey() + ": " + String.join(", ", entry.getValue()));
        }
        System.out.println("---");
        // 4. 其他信息
        System.out.println("Remote Address: " + request.getRemoteAddr());
        System.out.println("Server Name: " + request.getServerName());
        System.out.println("Server Port: " + request.getServerPort());
        System.out.println("Context Path: " + request.getContextPath());
        // 5. Cookie 信息
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            System.out.println("---");
            System.out.println("Cookies:");
            for (Cookie cookie : cookies) {
                System.out.println("  " + cookie.getName() + ": " + cookie.getValue());
            }
        }
        System.out.println("======================================");
        // 返回一个视图名称,Spring Boot 会尝试渲染 templates/show-request.html
        return "show-request"; 
    }
}

进阶:Request Body 的读取与处理

在现代 RESTful API 开发中,请求体通常是 JSON 或 XML 格式,直接使用 request.getInputStream() 来读取原始流比较繁琐,Spring MVC 提供了更优雅的解决方案。

使用 @RequestBody 注解

你可以在 Controller 方法的参数上使用 @RequestBody,Spring 会自动将请求体中的内容(如 JSON)转换成你指定的 Java 对象。

前提: 需要引入 Jackson 或 Gson 等 JSON 处理库,Spring Boot 默认会包含 Jackson。

示例:

  1. 创建一个 DTO (Data Transfer Object) 类

    public class UserLoginRequest {
        private String username;
        private String password;
        // Getters and Setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
  2. 在 Controller 中使用 @RequestBody

    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    @RestController // @RestController 会自动将返回值转为 JSON
    public class LoginController {
        @PostMapping("/login")
        public String login(@RequestBody UserLoginRequest loginRequest) {
            // Spring 已经将请求体 JSON 自动映射到了 loginRequest 对象中
            System.out.println("Username from body: " + loginRequest.getUsername());
            System.out.println("Password from body: " + loginRequest.getPassword());
            // 这里进行业务逻辑处理...
            return "Login successful for user: " + loginRequest.getUsername();
        }
    }

    当你发送一个 POST 请求到 /login,请求体为 {"username":"admin", "password":"123456"} 时,loginRequest 对象的 usernamepassword 字段就会被自动填充。

信息类别 主要获取方法 关键点
请求行 getMethod(), getRequestURI() 定义了请求的基本动作和目标。
请求头 getHeader(name) 包含客户端信息、内容类型、认证信息等元数据。
请求参数 getParameter(name) 来自 URL 查询字符串或表单,是 GET 和 POST 的常见数据来源。
请求体 getInputStream() / @RequestBody 主要用于 POST/PUT,承载复杂结构的数据(如 JSON、XML)。
Cookie getCookies() 用于在客户端存储状态信息。
其他信息 getRemoteAddr(), getContextPath() 提供网络和部署环境的上下文信息。

理解如何获取和使用 Request 信息是 Java Web 开发的基础,对于初学者,建议从原生 HttpServletRequest 开始,熟悉其 API;对于实际项目,则应深入学习 Spring 等框架提供的更高级、更便捷的封装。

分享:
扫描分享到社交APP
上一篇
下一篇