杰瑞科技汇

java request 获取参数

核心概念:请求参数 vs. 请求体

在开始之前,必须区分两个概念:

java request 获取参数-图1
(图片来源网络,侵删)
  1. 请求参数

    • 来源:通常来自 URL 的查询字符串(?key1=value1&key2=value2)或 POST 请求的 application/x-www-form-urlencoded 格式的请求体。
    • 特点:数据量通常较小,键值对形式,用于筛选、分页、排序等。
    • 获取方式:通过 HttpServletRequest 对象的 getParameter() 系列方法获取。
  2. 请求体

    • 来源POSTPUTPATCH 等请求方法中,承载实际数据的地方。
    • 特点:数据量可以很大,格式可以是 JSON、XML、纯文本、文件等。
    • 获取方式:通过 HttpServletRequest 对象的 getInputStream()getReader() 获取原始流,然后手动解析,在框架中,通常通过 @RequestBody 注解自动解析。

使用原生 Servlet API

这是最基础的方式,适用于所有遵循 Java Servlet 规范的容器(如 Tomcat, Jetty)。

获取单个参数

request.getParameter(String name) 方法用于获取指定名称的第一个参数值。

java request 获取参数-图2
(图片来源网络,侵删)

示例: 假设请求 URL 是 http://localhost:8080/user?id=123&name=张三

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends javax.servlet.http.HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. �名为 "id" 的参数
        String id = request.getParameter("id");
        if (id != null) {
            System.out.println("ID: " + id); // 输出: ID: 123
        }
        // 2. 获取名为 "name" 的参数
        String name = request.getParameter("name");
        if (name != null) {
            System.out.println("Name: " + name); // 输出: Name: 张三
        }
        // 3. 如果参数不存在,getParameter() 返回 null
        String email = request.getParameter("email");
        System.out.println("Email: " + email); // 输出: Email: null
    }
}

获取多个同名参数

当表单中有多个同名输入框(例如复选框)时,request.getParameter(String name) 只会返回第一个值,此时需要使用 getParameterValues(String name),它返回一个字符串数组。

示例: 假设请求 URL 是 http://localhost:8080/hobby?hobby=reading&hobby=music

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // 获取名为 "hobby" 的所有参数值
    String[] hobbies = request.getParameterValues("hobby");
    if (hobbies != null) {
        System.out.println("Hobbies:");
        for (String hobby : hobbies) {
            System.out.println("- " + hobby); // 输出: - reading, - music
        }
    }
}

获取所有参数名

如果你不知道请求中会有哪些参数,可以先获取所有参数的名称,然后再遍历获取值。

java request 获取参数-图3
(图片来源网络,侵删)
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // 获取所有参数名的 Enumeration
    java.util.Enumeration<String> parameterNames = request.getParameterNames();
    System.out.println("All Parameters:");
    while (parameterNames.hasMoreElements()) {
        String name = parameterNames.nextElement();
        String value = request.getParameter(name);
        System.out.println(name + " = " + value);
    }
}

获取所有参数到一个 Map

request.getParameterMap() 方法将所有参数名和值(第一个值)存储在一个 Map<String, String[]> 中,键是参数名,值是字符串数组。

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // 获取所有参数的 Map
    java.util.Map<String, String[]> parameterMap = request.getParameterMap();
    System.out.println("All Parameters in Map:");
    for (java.util.Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
        String name = entry.getKey();
        String[] values = entry.getValue();
        System.out.println(name + " = " + java.util.Arrays.toString(values));
    }
}

使用 Spring MVC / Spring Boot

在现代 Java Web 开发中,我们几乎都使用 Spring 框架,它极大地简化了参数获取的过程,并且提供了更强大的功能,如数据绑定、类型转换和验证。

获取单个参数(最常用)

直接在 Controller 方法的参数列表中声明一个与请求参数名相同的参数,并加上 @RequestParam 注解,Spring 会自动从请求中获取值并绑定到该参数。

示例: 请求 URL: http://localhost:8080/user?id=123

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
    @GetMapping("/user")
    public String getUser(@RequestParam("id") String userId) {
        // Spring 会自动将 "id" 参数的值 "123" 赋给 userId 变量
        System.out.println("User ID: " + userId); // 输出: User ID: 123
        return "Hello, User " + userId;
    }
}

@RequestParam 的常用属性:

  • value (或 name): 指定请求参数的名称,如果方法参数名和请求参数名一致,可以省略。
    public String getUser(@RequestParam String id) { // 省略 value
        // ...
    }
  • required: 指定该参数是否必须,默认为 true,如果设置为 false,当参数不存在时,Java 变量会被赋值为 null (对于对象类型) 或 0 (对于基本类型,但会抛出 HttpMessageNotReadableException,所以推荐使用包装类型)。
    @GetMapping("/greet")
    public String greet(@RequestParam(value = "name", required = false) String userName) {
        return "Hello, " + (userName != null ? userName : "Guest");
    }
    // 访问 /greet 或 /greet?name=Alice 都可以
  • defaultValue: 如果参数不存在或为空,则使用指定的默认值。
    @GetMapping("/page")
    public String getPage(@RequestParam(defaultValue = "1") int pageNum) {
        return "Showing page " + pageNum;
    }
    // 访问 /page 或 /page?pageNum=5 都可以

获取多个同名参数

同样使用 @RequestParam,但参数类型需要是数组或 List

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class HobbyController {
    @GetMapping("/hobby")
    public String getHobbies(@RequestParam("hobby") List<String> hobbies) {
        // Spring 会将所有 "hobby" 参数的值收集到 List 中
        System.out.println("Hobbies: " + hobbies); // 输出: Hobbies: [reading, music]
        return "Your hobbies are: " + String.join(", ", hobbies);
    }
}

获取整个请求体中的 JSON 数据

对于 POST/PUT 请求,尤其是发送 JSON 数据时,我们使用 @RequestBody 注解。

示例: 前端发送一个 POST 请求,Content-Type 为 application/json,请求体为: {"username": "john", "age": 30}

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
// 定义一个与 JSON 结构匹配的 POJO (Plain Old Java Object)
class User {
    private String username;
    private int age;
    // 必须要有无参构造器、getter 和 setter
    public User() {}
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}
@RestController
public class UserController {
    @PostMapping("/user/create")
    public String createUser(@RequestBody User user) {
        // Spring 会自动将 JSON 请求体解析成 User 对象
        System.out.println("Creating user: " + user.getUsername() + ", age: " + user.getAge());
        return "User created successfully: " + user.getUsername();
    }
}

获取路径变量

参数也可以是 URL 路径的一部分,这被称为“路径变量”或“URI 模板”,使用 @PathVariable 注解。

示例: 请求 URL: http://localhost:8080/users/123

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
    @GetMapping("/users/{userId}")
    public String getUserById(@PathVariable("userId") String id) {
        // Spring 会将路径中的 "123" 赋给 id 变量
        System.out.println("Fetching user with ID: " + id); // 输出: Fetching user with ID: 123
        return "Details for User " + id;
    }
}

总结与最佳实践

场景 推荐方式 原生 Servlet API Spring MVC / Spring Boot
简单参数获取 @RequestParam request.getParameter(name) public void method(@RequestParam String name)
必选/可选参数 @RequestParam(required = false) 手动判断 request.getParameter(name) != null @RequestParam(required = false)
默认值 @RequestParam(defaultValue = "val") 手动判断和赋值 @RequestParam(defaultValue = "val")
多选框/多值 @RequestParam List<String> request.getParameterValues(name) public void method(@RequestParam List<String> items)
JSON 数据体 @RequestBody 手动读取 request.getInputStream() 并解析(如用 Jackson/Gson) public void method(@RequestBody MyObject obj)
URL 路径参数 @PathVariable 手动解析 URL 路径(不推荐) public void method(@PathVariable String id)

核心建议:

  1. 优先使用框架:除非你在编写一个非常底层的库或学习 Servlet 原理,否则请直接使用 Spring Boot,它能让你从繁琐的 HttpServletRequest 操作中解放出来,专注于业务逻辑。
  2. 明确参数来源:始终清楚你要获取的是请求参数还是请求体,这决定了你使用 @RequestParam 还是 @RequestBody
  3. 处理必需参数:对于关键参数,使用 @RequestParam(required = true)(默认)或提供 defaultValue,这样可以尽早失败,避免后续代码因 NullPointerException 而出错。
  4. 使用 POJO:当处理复杂的 JSON 或表单数据时,创建一个对应的 Java 对象(POJO)并使用 @RequestBody 或表单自动绑定,代码会非常清晰和易于维护。
分享:
扫描分享到社交APP
上一篇
下一篇