本文目录导读:

我来详细介绍Spring Boot编写REST API的几种方式。
基础配置
添加依赖
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
基本REST控制器
简单CRUD示例
@RestController
@RequestMapping("/api/users")
public class UserController {
// GET - 获取所有用户
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
// GET - 获取单个用户
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// POST - 创建用户
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User createUser(@Valid @RequestBody User user) {
return userService.save(user);
}
// PUT - 更新用户
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@Valid @RequestBody User user) {
return userService.update(id, user)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// DELETE - 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
if (userService.deleteById(id)) {
return ResponseEntity.noContent().build();
}
return ResponseEntity.notFound().build();
}
}
请求参数处理
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 路径参数
@GetMapping("/category/{categoryId}")
public List<Product> getByCategory(@PathVariable Long categoryId) {
return productService.findByCategory(categoryId);
}
// 查询参数
@GetMapping("/search")
public List<Product> searchProducts(
@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return productService.search(name, page, size);
}
// 多个参数
@GetMapping("/filter")
public List<Product> filterProducts(
@RequestParam Map<String, String> allParams) {
return productService.filter(allParams);
}
}
返回结果封装
// 统一响应格式
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApiResponse<T> {
private int code;
private String message;
private T data;
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200, "success", data);
}
public static <T> ApiResponse<T> error(int code, String message) {
return new ApiResponse<>(code, message, null);
}
}
// 使用统一响应
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@GetMapping("/{id}")
public ApiResponse<Order> getOrder(@PathVariable Long id) {
return orderService.findById(id)
.map(ApiResponse::success)
.orElse(ApiResponse.error(404, "订单不存在"));
}
@PostMapping
public ApiResponse<Order> createOrder(@RequestBody Order order) {
Order saved = orderService.save(order);
return ApiResponse.success(saved);
}
}
异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理资源不存在
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiResponse<?> handleResourceNotFound(ResourceNotFoundException ex) {
return ApiResponse.error(404, ex.getMessage());
}
// 处理参数验证失败
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<?> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));
return ApiResponse.error(400, "参数验证失败");
}
// 处理其他异常
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiResponse<?> handleGenericException(Exception ex) {
return ApiResponse.error(500, "服务器内部错误");
}
}
数据验证
@Data
public class User {
private Long id;
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 50, message = "用户名长度2-50个字符")
private String username;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@Min(value = 1, message = "年龄必须大于0")
@Max(value = 150, message = "年龄必须小于150")
private Integer age;
@Pattern(regexp = "^\\d{11}$", message = "手机号格式不正确")
private String phone;
}
版本管理
// URL路径版本
@RestController
@RequestMapping("/api/v1/users")
public class UserV1Controller {
// ...
}
@RestController
@RequestMapping("/api/v2/users")
public class UserV2Controller {
// ...
}
// 请求头版本
@RestController
@RequestMapping(value = "/api/users", headers = "API-VERSION=1")
public class UserV1Controller {
// ...
}
高级特性
// 支持HATEOAS
@RestController
@RequestMapping("/api/articles")
public class ArticleController {
@GetMapping("/{id}")
public EntityModel<Article> getArticle(@PathVariable Long id) {
Article article = articleService.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("article", id));
return EntityModel.of(article,
linkTo(methodOn(ArticleController.class).getArticle(id)).withSelfRel(),
linkTo(methodOn(ArticleController.class).getAllArticles()).withRel("articles"));
}
}
// 分页支持
@GetMapping
public Page<Article> getAllArticles(
@PageableDefault(size = 20, sort = "createdAt") Pageable pageable) {
return articleService.findAll(pageable);
}
最佳实践建议
- 使用统一的响应格式 - 方便前端统一处理
- 正确处理HTTP状态码 - 合理使用200、201、204、400、404、500等
- 添加适当的验证 - @Valid、@Validated注解
- 实现异常处理 - 全局异常处理器
- API版本管理 - 便于接口演进
- 添加文档 - 使用Swagger/OpenAPI
- 使用DTO - 避免直接暴露实体类
这样你就有了一个完整的Spring Boot REST API实现。