Spring Boot @RestController 注解详解

Spring Boot @RestController 注解详解

@RestController 是 Spring Boot 中用于构建 RESTful Web 服务的核心注解,它将控制器类标记为 REST API 的入口点,简化了 RESTful 服务的开发。

概述

@RestController 是一个组合注解,它结合了 @Controller@ResponseBody 的功能。使用该注解的类中所有请求处理方法都会自动将返回值序列化为 JSON/XML 格式并写入 HTTP 响应体中。

基本语法结构

java 复制代码
@RestController
@RequestMapping("基础路径")
public class ControllerName {
    
    @GetMapping("/路径")
    public ReturnType methodName(@RequestParam 参数类型 参数名) {
        // 处理逻辑
        return 返回值;
    }
}

核心特性

1. 组合注解特性

@RestController 相当于同时使用了 @Controller@ResponseBody

java 复制代码
// 使用 @RestController(推荐)
@RestController
public class RoomController {
    @GetMapping("/room")
    public RoomEntity getRoom() {
        return new RoomEntity();
    }
}

// 等价于下面的传统写法
@Controller
@ResponseBody
public class RoomController {
    @GetMapping("/room")
    public RoomEntity getRoom() {
        return new RoomEntity();
    }
}

2. 自动序列化返回值

所有方法返回值自动转换为 JSON/XML 格式:

java 复制代码
@RestController
@RequestMapping("/api/rooms")
public class RoomController {
    
    // 返回对象自动序列化为 JSON
    @GetMapping("/{id}")
    public RoomEntity getRoom(@PathVariable Long id) {
        RoomEntity room = new RoomEntity();
        room.setId(id);
        room.setName("会议室");
        return room; // 自动转换为 JSON: {"id": 1, "name": "会议室"}
    }
    
    // 返回集合也自动序列化
    @GetMapping
    public List<RoomEntity> getAllRooms() {
        return Arrays.asList(new RoomEntity(), new RoomEntity());
    }
}

常用详解

1. 基本使用方式

java 复制代码
@RestController
@RequestMapping("/api/rooms")
public class RoomController {
    
    @Autowired
    private RoomService roomService;
    
    // GET /api/rooms - 获取房间列表
    @GetMapping
    public ResponseEntity<List<RoomEntity>> getAllRooms() {
        List<RoomEntity> rooms = roomService.findAll();
        return ResponseEntity.ok(rooms);
    }
    
    // GET /api/rooms/1 - 获取特定房间
    @GetMapping("/{id}")
    public ResponseEntity<RoomEntity> getRoom(@PathVariable Long id) {
        RoomEntity room = roomService.findById(id);
        return ResponseEntity.ok(room);
    }
    
    // POST /api/rooms - 创建新房间
    @PostMapping
    public ResponseEntity<RoomEntity> createRoom(@RequestBody RoomEntity room) {
        RoomEntity savedRoom = roomService.save(room);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedRoom);
    }
}

2. 与 HTTP 方法注解配合

java 复制代码
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // GET 请求 - 查询数据
    @GetMapping
    public List<User> getUsers() {
        return userService.findAll();
    }
    
    // GET 请求 - 根据 ID 查询
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    // POST 请求 - 创建资源
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
    
    // PUT 请求 - 更新整个资源
    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        return userService.update(id, user);
    }
    
    // PATCH 请求 - 部分更新资源
    @PatchMapping("/{id}")
    public User patchUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
        return userService.partialUpdate(id, updates);
    }
    
    // DELETE 请求 - 删除资源
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
    }
}

关键说明

1. 与 @Controller 的区别

java 复制代码
// @Controller - 通常用于返回视图名称
@Controller
public class WebController {
    @GetMapping("/page")
    public String getPage() {
        return "index"; // 返回视图名称
    }
}

// @RestController - 用于返回数据
@RestController
public class ApiController {
    @GetMapping("/api/data")
    public Map<String, Object> getData() {
        return Map.of("message", "Hello World"); // 返回 JSON 数据
    }
}

2. 返回值处理机制

java 复制代码
@RestController
public class DataController {
    
    // 1. 返回简单对象
    @GetMapping("/string")
    public String getString() {
        return "Hello World"; // 返回字符串
    }
    
    // 2. 返回复杂对象(自动转 JSON)
    @GetMapping("/object")
    public User getUser() {
        return new User("张三", 25); // 转换为 {"name": "张三", "age": 25}
    }
    
    // 3. 返回集合
    @GetMapping("/list")
    public List<User> getUsers() {
        return List.of(new User("张三", 25), new User("李四", 30));
    }
    
    // 4. 使用 ResponseEntity 提供更精确的控制
    @GetMapping("/response")
    public ResponseEntity<User> getResponseUser() {
        User user = new User("王五", 28);
        return ResponseEntity.ok()
                .header("Custom-Header", "Value")
                .body(user);
    }
}

注意事项

1. 不要与视图解析混用

java 复制代码
// 错误示例 - 不要在 @RestController 中返回视图名称
@RestController
public class WrongController {
    @GetMapping("/page")
    public String getPage() {
        return "index"; // 这会返回字符串 "index" 而不是视图
    }
}

// 正确示例 - 使用 @Controller 处理视图
@Controller
public class ViewController {
    @GetMapping("/page")
    public String getPage() {
        return "index"; // 返回视图名称
    }
}

2. 异常处理

java 复制代码
@RestController
public class RoomController {
    
    @GetMapping("/{id}")
    public RoomEntity getRoom(@PathVariable Long id) {
        RoomEntity room = roomService.findById(id);
        if (room == null) {
            // 应使用统一异常处理机制
            throw new RoomNotFoundException("Room not found: " + id);
        }
        return room;
    }
}

// 统一异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(RoomNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleRoomNotFound(RoomNotFoundException e) {
        ErrorResponse error = new ErrorResponse("ROOM_NOT_FOUND", e.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }
}

实用技巧

1. 统一响应格式

java 复制代码
@RestController
public class RoomController {
    
    // 定义统一响应结构
    @GetMapping("/{id}")
    public ApiResponse<RoomEntity> getRoom(@PathVariable Long id) {
        RoomEntity room = roomService.findById(id);
        return ApiResponse.success(room);
    }
}

// 统一响应类
public class ApiResponse<T> {
    private int code;
    private String message;
    private T data;
    
    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.code = 0;
        response.message = "success";
        response.data = data;
        return response;
    }
}

2. 版本控制

java 复制代码
@RestController
@RequestMapping("/api/v1/rooms")  // API 版本控制
public class RoomControllerV1 {
    // v1 版本的实现
}

@RestController
@RequestMapping("/api/v2/rooms")  // API 版本控制
public class RoomControllerV2 {
    // v2 版本的实现
}

3. 分组管理

java 复制代码
@RestController
@RequestMapping("/api/admin/rooms")  // 管理员接口
public class AdminRoomController {
    // 管理员专用接口
}

@RestController
@RequestMapping("/api/public/rooms")  // 公共接口
public class PublicRoomController {
    // 公共可访问接口
}

命名规范建议

1. 控制器类命名

java 复制代码
// 推荐命名方式 - 资源名 + Controller
@RestController
public class RoomController { }

@RestController
public class UserController { }

@RestController
public class OrderController { }

2. 路径命名规范

java 复制代码
@RestController
@RequestMapping("/api/v1/rooms")        // 复数形式
public class RoomController { }

@RestController
@RequestMapping("/api/v1/room-types")   // 多个单词使用连字符
public class RoomTypeController { }

总结:核心要点速览

特性 说明
主要用途 标记 RESTful API 控制器类
组合注解 等价于 @Controller + @ResponseBody
自动序列化 方法返回值自动转换为 JSON/XML
适用场景 构建 REST API,不适用于视图渲染
路径映射 通常与 @RequestMapping 配合使用
方法注解 配合 @GetMapping@PostMapping
返回处理 支持对象、集合、ResponseEntity 等类型
最佳实践 遵循 RESTful 设计原则,统一响应格式

通过合理使用 @RestController 注解,可以快速构建功能完善、规范统一的 RESTful API 服务,是现代 Web 应用开发中不可或缺的重要组件。

相关推荐
canonical_entropy5 小时前
可逆计算:一场软件构造的世界观革命
后端·aigc·ai编程
叫我阿柒啊5 小时前
从Java全栈到前端框架:一次真实面试的深度复盘
java·spring boot·typescript·vue·database·testing·microservices
点云SLAM5 小时前
C++ 常见面试题汇总
java·开发语言·c++·算法·面试·内存管理
sniper_fandc5 小时前
IDEA修改系统缓存路径,防止C盘爆满
java·ide·intellij-idea
重庆穿山甲5 小时前
从0到1:用 Akka 持久化 Actor + Outbox + RocketMQ 做到“订单-库存最终一致”
后端
aristo_boyunv5 小时前
拦截器和过滤器(理论+实操)
java·数据仓库·hadoop·servlet
半夏陌离5 小时前
SQL 入门指南:排序与分页查询(ORDER BY 多字段排序、LIMIT 分页实战)
java·前端·数据库
CUIYD_19895 小时前
Eclipse 常用搜索功能汇总
java·ide·eclipse