Controller参数类型如何正确使用?

99ANYc3cd6
预计阅读时长 33 分钟
位置: 首页 参数 正文

控制器方法的参数非常灵活,Spring MVC 通过强大的 HandlerMethodArgumentResolver(参数解析器)机制来自动将 HTTP 请求中的数据绑定到方法参数上。

下面我将参数类型分为几大类,并附上示例和说明。


核心基础类型

这是最常用、最基础的参数类型,直接接收请求中的简单数据。

HttpServletRequest / HttpServletResponse

直接获取原生 Servlet API 的请求和响应对象。

@GetMapping("/api/request-info")
public String getRequestInfo(HttpServletRequest request, HttpServletResponse response) {
    String userAgent = request.getHeader("User-Agent");
    response.setHeader("Custom-Header", "MyValue");
    return "User Agent: " + userAgent;
}

HttpSession

用于获取和操作会话(Session)。

@GetMapping("/api/session")
public String getSessionInfo(HttpSession session) {
    // 从 session 中获取用户ID,如果不存在则设置一个
    Object userId = session.getAttribute("userId");
    if (userId == null) {
        session.setAttribute("userId", "12345");
        return "Session created for user 12345.";
    }
    return "Current user ID in session: " + userId;
}

java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap

用于向视图(View)传递数据,主要用于返回页面(@Controller)。

  • Model: Spring 提供的接口,推荐使用。
  • ModelMap: Model 的实现类。
  • Map: 也可以,但功能不如 Model 丰富。
@GetMapping("/hello")
public String helloPage(Model model) {
    model.addAttribute("name", "World");
    model.addAttribute("currentTime", new Date());
    // 返回视图名,Spring 会解析为 "hello.html" 或类似模板
    return "hello"; 
}

在 Thymeleaf 模板 hello.html 中就可以使用 ${name}${currentTime}

@PathVariable (路径变量)

用于获取 URL 路径中的变量。

// 请求 URL: /api/users/123
@GetMapping("/api/users/{userId}")
public String getUserById(@PathVariable("userId") String id) {
    return "User ID: " + id; // 输出: User ID: 123
}
  • 如果变量名和方法参数名一致,可以省略 value@PathVariable String userId
  • 可以指定类型,Spring 会自动转换:@PathVariable Long userId

@RequestParam (请求参数)

用于获取 URL 查询参数(?key=value)或表单数据。

// 请求 URL: /api/search?name=John&age=30
@GetMapping("/api/search")
public String search(@RequestParam("name") String userName, 
                     @RequestParam(required = false, defaultValue = "18") int age) {
    return "Searching for: " + userName + ", Age: " + age;
}
  • name: 参数名,与 URL 中的 key 对应。
  • required: 是否为必需参数,默认为 true,如果为 true 且参数不存在,会抛出 MissingServletRequestParameterException
  • defaultValue: 如果参数不存在或为空,则使用默认值。

接收多个值(如复选框)

// 请求 URL: /api/hobbies?hobbies=reading&hobbies=sports
@GetMapping("/api/hobbies")
public String getHobbies(@RequestParam("hobbies") List<String> hobbies) {
    return "Your hobbies are: " + hobbies; // 输出: [reading, sports]
}

@RequestBody (请求体)

用于接收 HTTP 请求体中的 JSON/XML 数据,通常用于 POST/PUT 请求。必须配合 @RestController@ResponseBody 使用

使用前,需要确保有 JSON 解析库(如 Jackson)的依赖,Spring Boot 默认已包含。

// 前端发送 POST 请求,Content-Type: application/json
// 请求体: {"username": "jack", "password": "123456"}
@PostMapping("/api/users")
public String createUser(@RequestBody User user) { // User 是一个自定义的 Java 类
    // Spring 会自动将 JSON 字符串解析成 User 对象
    System.out.println("Creating user: " + user.getUsername());
    return "User created successfully: " + user.getUsername();
}

User.java 示例:

public class User {
    private String username;
    private String password;
    // Getters and Setters...
}

@RequestHeader (请求头)

用于获取 HTTP 请求头中的信息。

@GetMapping("/api/headers")
public String getHeaders(@RequestHeader("User-Agent") String userAgent,
                         @RequestHeader(value = "Accept", defaultValue = "*/*") String accept) {
    return "User-Agent: " + userAgent + ", Accept: " + accept;
}

@CookieValue (Cookie)

用于获取指定的 Cookie 值。

@GetMapping("/api/cookie")
public String getCookie(@CookieValue("JSESSIONID") String sessionId) {
    return "Session ID from Cookie: " + sessionId;
}

复杂对象类型

接收整个表单(@ModelAttribute

当表单字段和 Java 对象的属性名一致时,Spring 会自动进行数据绑定(类型转换、封装),它也可以像 Model 一样向视图添加数据。

  • @Controller 中,常用于表单提交的 GET 请求(展示表单)和 POST 请求(处理表单)。
  • @RestController 中,作用与 @RequestParam 类似,用于接收 x-www-form-urlencoded 格式的数据。
// 请求 URL: /api/register?username=John&email=john@example.com
@GetMapping("/api/register")
public String showRegistrationForm(@ModelAttribute("user") User user) {
    // user 对象已经被填充了 username 和 email 属性
    // 这个对象也可以在视图中使用
    return "registration-form"; 
}
@PostMapping("/api/register")
public String processRegistration(@ModelAttribute User user) {
    // 处理 user 对象...
    return "redirect:/success";
}

User.java 示例:

public class User {
    private String username;
    private String email;
    // Getters and Setters...
}

Spring Web 特殊类型

org.springframework.web.servlet.ModelAndView

这是一个非常传统的对象,它既可以包含要渲染的数据(Model 部分),也可以指定要跳转的视图(View 部分)。

@GetMapping("/api/mav")
public ModelAndView modelAndView() {
    ModelAndView mav = new ModelAndView();
    mav.addObject("message", "Hello from ModelAndView");
    mav.setViewName("hello"); // 设置视图名
    return mav;
}

java.io.InputStream / java.io.Reader

直接获取请求体的输入流,用于处理文件上传或原始数据流。

@PostMapping("/api/upload")
public String uploadFile(InputStream inputStream) throws IOException {
    // 可以直接读取 inputStream 中的内容
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        // 处理数据...
    }
    return "File uploaded successfully.";
}

org.springframework.http.ResponseEntity

这是 @RestController 中最常用的返回类型之一,它允许你完全控制 HTTP 响应,包括状态码、响应头和响应体。

@GetMapping("/api/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    // 模拟从数据库查找用户
    if (id == 1L) {
        User user = new User("Alice", "alice@example.com");
        return ResponseEntity.ok(user); // 返回 200 OK 和用户对象
    } else {
        return ResponseEntity.notFound().build(); // 返回 404 Not Found
    }
}
@PostMapping("/api/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
    // 模拟创建用户
    user.setId(1L);
    return ResponseEntity.status(HttpStatus.CREATED).body(user); // 返回 201 Created
}

org.springframework.http.HttpEntity

ResponseEntity 类似,但它主要用于接收请求,可以同时获取请求体和请求头。

@PostMapping("/api/echo")
public String echo(@RequestBody HttpEntity<String> httpEntity) {
    String body = httpEntity.getBody();
    HttpHeaders headers = httpEntity.getHeaders();
    return "Body: " + body + "\nHeaders: " + headers;
}

MultipartFile (文件上传)

这是处理文件上传的专用类型。

添加依赖pom.xml 中添加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

(Spring Boot Web starter 已经包含了所需的一切)

配置文件上传application.propertiesapplication.yml 中设置:

# 单个文件最大大小
spring.servlet.multipart.max-file-size=10MB
# 总请求最大大小
spring.servlet.multipart.max-request-size=10MB

编写控制器

import org.springframework.web.multipart.MultipartFile;
@PostMapping("/api/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
    if (file.isEmpty()) {
        return "Please select a file to upload.";
    }
    try {
        // 获取文件名
        String fileName = file.getOriginalFilename();
        // 保存文件到服务器...
        // Files.write(Paths.get("/uploads/" + fileName), file.getBytes());
        return "You successfully uploaded '" + fileName + "'";
    } catch (IOException e) {
        return "Failed to upload file: " + e.getMessage();
    }
}

前端表单必须设置 enctype="multipart/form-data"


总结表格

参数类型/注解 作用 适用场景 示例
HttpServletRequest 获取原生请求对象 获取请求头、Session、输入流等 public void method(HttpServletRequest req)
HttpSession 获取会话对象 管理用户登录状态等 public void method(HttpSession session)
Model 向视图传递数据 @Controller 返回页面时 public String method(Model model)
@PathVariable 获取 URL 路径变量 RESTful API 设计 @GetMapping("/users/{id}")
@RequestParam 获取 URL 查询参数或表单数据 搜索、分页、筛选 @GetMapping("/search?name={name}")
@RequestBody 获取请求体中的 JSON/XML 数据 接收复杂对象,POST/PUT 请求 @PostMapping("/users")
@RequestHeader 获取请求头信息 获取 User-Agent, Authorization 等 @GetMapping("/api")
@CookieValue 获取 Cookie 值 处理客户端状态 @GetMapping("/home")
@ModelAttribute 绑定表单数据到对象 表单提交(GET/POST) @PostMapping("/register")
ResponseEntity 构建完整的 HTTP 响应 @RestController 中精确控制响应 return ResponseEntity.ok(user);
MultipartFile 处理文件上传 上传图片、文档等 @PostMapping("/upload")

掌握这些参数类型,你就可以灵活地处理几乎所有的 Web 请求了,在实际开发中,@PathVariable@RequestParam@RequestBodyResponseEntity 是使用频率最高的。

-- 展开阅读全文 --
头像
thinkpad t41 拆机
« 上一篇 今天
thinkpadp52拆机评测
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]