Skip to content

请求


参数获取方式

@RequestParam:获取查询参数 / 表单字段

java
@GetMapping("/search")
public List<Post> search(
    @RequestParam String keyword,                 // ?keyword=java
    @RequestParam(defaultValue = "1") int page,   // ?page=2,默认1
    @RequestParam(required = false) String sort   // 可选参数
) { ... }

PHP 写 $request->input('keyword') 是运行时查找,Java 写 @RequestParam String keyword 是编译期声明。 原因:Java 是静态类型语言,所有参数的结构必须在编译时就确定。好处是 IDE 自动补全、重构安全;坏处是灵活度不如 PHP。

@PathVariable:获取路径参数

java
@GetMapping("/posts/{year}/{month}/{slug}")
public Post show(
    @PathVariable int year,
    @PathVariable int month,
    @PathVariable String slug
) { ... }

@RequestBody:获取 JSON Body

java
@PostMapping("/posts")
public Post create(@RequestBody @Valid Post post) { ... }

// 也可以接收原始 Map
@PostMapping("/raw")
public Map<String, Object> raw(@RequestBody Map<String, Object> body) {
    String name = (String) body.get("name");  // 手动取值,不推荐
    return body;
}

⚠️ 和 PHP 的关键差异

  • PHP 中 $request->all() 得到一个数组,动态访问
  • Java 中需要提前定义一个类(DTO)来映射 JSON 结构
  • 原因:Java 在编译期就需要知道 JSON 的字段名和类型,无法像 PHP 那样在运行时动态读取

DTO 类的示例:

java
// 需要手动定义这个类
public class CreatePostRequest {
    private String title;
    private String content;
    private Long categoryId;

    // getter / setter 必须写(或 @Data 注解自动生成)
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
    public Long getCategoryId() { return categoryId; }
    public void setCategoryId(Long categoryId) { this.categoryId = categoryId; }
}

使用 Lombok 的 @Data 可以省掉 getter/setter,见附录-常用注解速查。

@RequestHeader:获取请求头

java
@GetMapping("/info")
public String info(
    @RequestHeader("User-Agent") String ua,
    @RequestHeader("Authorization") String token
) { ... }

直接注入原始对象

java
@RestController
public class RawController {

    @GetMapping("/raw")
    public String raw(HttpServletRequest request) {     // 类比 $_SERVER / $_REQUEST
        String method = request.getMethod();             // 类比 $_SERVER['REQUEST_METHOD']
        String uri = request.getRequestURI();            // 类比 $_SERVER['REQUEST_URI']
        String param = request.getParameter("name");     // 类比 $_REQUEST['name']
        String body = request.getReader().lines()
                .collect(Collectors.joining());          // 类比 file_get_contents('php://input')
        return "OK";
    }
}

理论上可以直接用 HttpServletRequest 做一切事(像 PHP 那样),但主流做法是用 @RequestParam / @PathVariable / @RequestBody 等注解精确声明。


⚠️ 常见坑

1. @RequestParam 的 required 默认是 true

java
@GetMapping("/test")
public String test(@RequestParam String name) { }
// 访问 /test(不带 ?name=xxx)→ 400 Bad Request

// 需要可选则:
public String test(@RequestParam(required = false) String name) { }
// 或设置默认值:
public String test(@RequestParam(defaultValue = "") String name) { }

2. JSON 字段名映射

java
// JSON: { "user_name": "foo" }
public class UserRequest {
    private String userName;  // Java 惯例使用驼峰

    // 需要加注解映射
    @JsonProperty("user_name")
    public String getUserName() { return userName; }
}

3. 枚举参数 ⚠️

java
public enum Status { DRAFT, PUBLISHED, ARCHIVED }

@GetMapping("/posts")
public List<Post> list(@RequestParam Status status) { }
// 访问 /posts?status=draft → 400(大小写不匹配)
// 正确:/posts?status=DRAFT
// 或自定义转换器处理大小写

面向 PHP 开发者的 Spring Boot 文档