SpringMVC_02_注解开发实战

【Spring MVC】注解开发实战:核心注解与 RESTful 风格

🔑 关键词:Java、Spring MVC、@Controller、@RequestMapping、@RequestParam、@PathVariable、RESTful


一、常用注解总览

注解 作用 标注位置
@Controller 声明为 Controller 组件 类上
@RestController = @Controller + @ResponseBody 类上
@RequestMapping 映射请求路径 类/方法上
@GetMapping GET 请求快捷注解 方法上
@PostMapping POST 请求快捷注解 方法上
@PutMapping PUT 请求快捷注解 方法上
@DeleteMapping DELETE 请求快捷注解 方法上
@RequestParam 接收查询参数 方法参数上
@PathVariable 接收路径变量 方法参数上
@RequestBody 接收 JSON 请求体 方法参数上
@ResponseBody 返回值写入响应体 方法上
@ModelAttribute 绑定表单数据到模型 方法参数上

二、请求映射注解

2.1 @RequestMapping

java 复制代码
@Controller
@RequestMapping("/user")  // 类级别:统一前缀
public class UserController {

    @RequestMapping("/list")  // 方法级别:完整路径 /user/list
    public String list() {
        return "userList";
    }

    // 指定请求方法
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add() {
        return "redirect:/user/list";
    }
}

2.2 快捷注解(推荐)

java 复制代码
@RestController
@RequestMapping("/api/user")
public class UserRestController {

    @GetMapping("/list")      // GET /api/user/list
    public List<User> list() {
        return userService.findAll();
    }

    @GetMapping("/{id}")      // GET /api/user/1
    public User getById(@PathVariable Long id) {
        return userService.findById(id);
    }

    @PostMapping              // POST /api/user
    public User create(@RequestBody User user) {
        return userService.save(user);
    }

    @PutMapping("/{id}")      // PUT /api/user/1
    public User update(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        return userService.update(user);
    }

    @DeleteMapping("/{id}")   // DELETE /api/user/1
    public void delete(@PathVariable Long id) {
        userService.deleteById(id);
    }
}

三、参数绑定注解

3.1 @RequestParam ------ 接收查询参数

java 复制代码
// GET /api/user?name=张三&age=25

@GetMapping("/search")
public String search(
    @RequestParam("name") String name,      // 必传参数
    @RequestParam(value = "age", required = false) Integer age,  // 可选参数
    @RequestParam(defaultValue = "1") int page  // 带默认值
) {
    return "查询:" + name + ", " + age + ", page=" + page;
}

常用属性:

属性 说明
value / name 参数名(可与方法参数名不同)
required 是否必传,默认 true
defaultValue 默认值(设置后 required 自动为 false)

3.2 @PathVariable ------ 接收路径变量

java 复制代码
// GET /api/user/123
@GetMapping("/{id}")
public User getById(@PathVariable("id") Long id) {
    return userService.findById(id);
}

// GET /api/user/123/order/456
@GetMapping("/{userId}/order/{orderId}")
public Order getOrder(
    @PathVariable Long userId,
    @PathVariable Long orderId
) {
    return orderService.find(userId, orderId);
}

对比:

方式 URL 示例 适用场景
@RequestParam /user?id=1 查询参数、分页、筛选
@PathVariable /user/1 RESTful 资源定位

3.3 @RequestBody ------ 接收 JSON 请求体

java 复制代码
// POST /api/user
// Content-Type: application/json
// Body: {"name": "张三", "age": 25}

@PostMapping
public User create(@RequestBody User user) {
    // Spring 自动将 JSON 反序列化为 User 对象(需要 Jackson 依赖)
    return userService.save(user);
}

注意:

  • 一个方法只能有一个 @RequestBody
  • 需要引入 Jackson 依赖:jackson-databind
  • Content-Type 必须是 application/json

3.4 直接接收 POJO(无需注解)

java 复制代码
// GET /api/user?name=张三&age=25
// 或 POST 表单提交
@GetMapping("/register")
public String register(User user) {
    // Spring 自动将请求参数绑定到 User 的同名属性
    System.out.println(user.getName());  // 张三
    System.out.println(user.getAge());   // 25
    return "success";
}

四、响应处理

4.1 @ResponseBody ------ 返回 JSON

java 复制代码
@Controller
public class ApiController {

    @ResponseBody  // 返回值直接写入响应体(JSON 格式)
    @GetMapping("/api/hello")
    public Map<String, String> hello() {
        Map<String, String> map = new HashMap<>();
        map.put("message", "Hello JSON!");
        return map;
        // 响应:{"message": "Hello JSON!"}
    }
}

4.2 @RestController ------ 类级别 @ResponseBody

java 复制代码
@RestController  // 等价于 @Controller + 所有方法 @ResponseBody
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/users")
    public List<User> list() {
        return userService.findAll();  // 自动序列化为 JSON
    }
}

4.3 ResponseEntity ------ 完全控制响应

java 复制代码
@GetMapping("/api/user/{id}")
public ResponseEntity<User> getById(@PathVariable Long id) {
    User user = userService.findById(id);
    if (user == null) {
        return ResponseEntity.notFound().build();  // 404
    }
    return ResponseEntity.ok(user);  // 200 + JSON
}

@PostMapping("/api/user")
public ResponseEntity<User> create(@RequestBody User user) {
    User saved = userService.save(user);
    URI location = URI.create("/api/user/" + saved.getId());
    return ResponseEntity.created(location).body(saved);  // 201
}

常用状态码:

方法 状态码 场景
.ok(body) 200 成功
.created(uri).body(body) 201 创建成功
.noContent().build() 204 无内容
.badRequest().build() 400 请求错误
.notFound().build() 404 资源不存在

五、RESTful 风格设计

5.1 RESTful 核心原则

HTTP 方法 操作 URL 示例 说明
GET 查询 /api/users 获取列表
GET 查询 /api/users/1 获取单个
POST 新增 /api/users 创建资源
PUT 修改 /api/users/1 全量更新
PATCH 修改 /api/users/1 部分更新
DELETE 删除 /api/users/1 删除资源

5.2 完整 RESTful Controller

java 复制代码
@RestController
@RequestMapping("/api/users")
public class UserRestController {

    @Autowired
    private UserService userService;

    // 查询全部
    @GetMapping
    public ResponseEntity<List<User>> list() {
        return ResponseEntity.ok(userService.findAll());
    }

    // 根据 ID 查询
    @GetMapping("/{id}")
    public ResponseEntity<User> getById(@PathVariable Long id) {
        User user = userService.findById(id);
        return user != null
            ? ResponseEntity.ok(user)
            : ResponseEntity.notFound().build();
    }

    // 新增
    @PostMapping
    public ResponseEntity<User> create(@RequestBody User user) {
        User saved = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(saved);
    }

    // 修改
    @PutMapping("/{id}")
    public ResponseEntity<User> update(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        return ResponseEntity.ok(userService.update(user));
    }

    // 删除
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable Long id) {
        userService.deleteById(id);
        return ResponseEntity.noContent().build();
    }
}

六、总结

注解 用途 记忆要点
@RequestMapping 路径映射 可标注在类和方法上
@RequestParam 查询参数 ?name=xxx
@PathVariable 路径变量 /user/{id}
@RequestBody JSON 请求体 POST/PUT 的 JSON 数据
@ResponseBody JSON 响应 返回值写入响应体
ResponseEntity 完全控制响应 状态码 + 响应头 + 响应体

📝 下一篇预告:《Spring MVC 进阶功能》,详解拦截器、文件上传下载、全局异常处理。

相关推荐
apcipot_rain13 小时前
C++转Java日记(04)
java·开发语言·c++
特立独行的猫A13 小时前
我给女儿写了个打字练习:一边敲键盘,一边把小学英语单词记牢
java·后端·python
cpolar技术支持14 小时前
「我这边连不上你那个服务」—— 用清单驱动的 TCP 连通性只读看板,cpolar 让远端同事自己取证
python·内网穿透·tcp·cpolar·网络诊断
云和数据.ChenGuang14 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
天诰15 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
benchmark_cc16 小时前
用 QuantDash 读取美股行情:AAPL.US 的运行前检查、排错顺序与数据校验清单
python·数据分析·pandas·量化交易·股票数据·quantdash
蜗牛一步步往上爬18 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
艺杯羹18 小时前
Windows原生软件锁设计:从暴力杀进程丢数据到零轮询事件驱动架构
windows·系统架构·开源·开源软件·内存管理·开源协议
羲云网络19 小时前
GPT Image 2.6 接入指南:Flare、Sunburst 怎么选,编辑失败如何排查
人工智能·python·aigc·图像生成·acedatacloud
张张123y20 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent