SpringBoot控制器返回值处理的4个技巧

在SpringBoot开发中,控制器(Controller)的返回值处理是API设计的重要部分。以下是4个实用的返回值处理技巧:

图片[1]_SpringBoot控制器返回值处理的4个技巧_知途无界

1. 统一响应格式封装

使用统一的数据结构封装响应,使前端处理更加规范:

@Data
public class Result<T> {
    private int code;    // 状态码
    private String msg;  // 消息
    private T data;      // 数据

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg("success");
        result.setData(data);
        return result;
    }

    public static Result<?> error(int code, String msg) {
        Result<?> result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

// 控制器中使用
@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users/{id}")
    public Result<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return Result.success(user);
    }

    @PostMapping("/users")
    public Result<?> createUser(@RequestBody User user) {
        try {
            userService.save(user);
            return Result.success(null);
        } catch (Exception e) {
            return Result.error(500, e.getMessage());
        }
    }
}

2. 使用ResponseEntity进行精细控制

当需要更精细地控制HTTP状态码和响应头时:

@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = userService.findById(id);
    if (user == null) {
        return ResponseEntity.notFound().build();
    }
    return ResponseEntity.ok()
            .header("Custom-Header", "value")
            .body(user);
}

@PostMapping("/users")
public ResponseEntity<?> createUser(@RequestBody User user) {
    try {
        User savedUser = userService.save(user);
        return ResponseEntity.created(URI.create("/users/" + savedUser.getId()))
                             .body(savedUser);
    } catch (Exception e) {
        return ResponseEntity.badRequest()
                             .body(Map.of("error", e.getMessage()));
    }
}

3. 使用@ResponseBody和@ResponseStatus简化返回

对于简单场景,可以使用注解简化代码:

@ResponseBody
@GetMapping("/greet")
public String greet() {
    return "Hello, SpringBoot!";
}

@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public void createUser(@RequestBody User user) {
    userService.save(user);
}

@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Map<String, String> handleUserNotFound(UserNotFoundException ex) {
    return Map.of("error", ex.getMessage());
}

4. 使用Project Reactor的响应式返回

对于响应式编程(WebFlux)场景:

@RestController
@RequestMapping("/api")
public class ReactiveUserController {

    @GetMapping("/users")
    public Flux<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/users/{id}")
    public Mono<ResponseEntity<User>> getUser(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.notFound().build());
    }

    @PostMapping("/users")
    @ResponseStatus(HttpStatus.CREATED)
    public Mono<User> createUser(@RequestBody User user) {
        return userService.save(user);
    }
}

额外技巧:全局异常处理

结合@ControllerAdvice实现全局异常处理:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Result<?>> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Result.error(500, e.getMessage()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Result<?>> handleValidationException(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(", "));
        return ResponseEntity.badRequest()
                .body(Result.error(400, message));
    }
}

这些技巧可以根据项目需求灵活组合使用,既能保持代码简洁,又能提供强大的API响应控制能力。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞40 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容