本文目录导读:

在Java后端开发中,统一响应返回流程是提升代码可维护性、规范前后端交互的核心手段,通常有两种主流实现方式,下面分别说明:
通用响应体封装(最常用)
1 定义统一响应类
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class ApiResponse<T> {
private int code;
private String message;
private T data;
private String timestamp;
// 私有构造器
private ApiResponse() {
this.timestamp = LocalDateTime.now().toString();
}
// 成功响应
public static <T> ApiResponse<T> success(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(200);
response.setMessage("success");
response.setData(data);
return response;
}
// 成功响应(带自定义消息)
public static <T> ApiResponse<T> success(String message, T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(200);
response.setMessage(message);
response.setData(data);
return response;
}
// 失败响应
public static <T> ApiResponse<T> error(int code, String message) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(code);
response.setMessage(message);
response.setData(null);
return response;
}
// 失败响应(带自定义数据)
public static <T> ApiResponse<T> error(int code, String message, T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(code);
response.setMessage(message);
response.setData(data);
return response;
}
}
2 使用方式
@RestController
public class UserController {
@GetMapping("/user/{id}")
public ApiResponse<User> getUser(@PathVariable Long id) {
try {
User user = userService.findById(id);
return ApiResponse.success(user);
} catch (Exception e) {
return ApiResponse.error(500, "查询用户失败: " + e.getMessage());
}
}
}
使用全局异常处理器(更优雅)
1 自定义业务异常
import lombok.Getter;
@Getter
public class BusinessException extends RuntimeException {
private int code;
private String message;
public BusinessException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
// 预定义错误码
public static class ErrorCode {
public static final int PARAM_ERROR = 400;
public static final int UNAUTHORIZED = 401;
public static final int FORBIDDEN = 403;
public static final int NOT_FOUND = 404;
public static final int SERVER_ERROR = 500;
}
}
2 全局异常处理器
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理业务异常
@ExceptionHandler(BusinessException.class)
public ApiResponse<Void> handleBusinessException(BusinessException e) {
return ApiResponse.error(e.getCode(), e.getMessage());
}
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public ApiResponse<Void> handleValidationException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(", "));
return ApiResponse.error(400, message);
}
// 处理其他未捕获异常
@ExceptionHandler(Exception.class)
public ApiResponse<Void> handleException(Exception e) {
log.error("系统异常", e);
return ApiResponse.error(500, "服务器内部错误");
}
}
3 控制器直接返回数据
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
User user = userService.findById(id);
if (user == null) {
throw new BusinessException(404, "用户不存在");
}
return user; // 直接返回数据,由全局异常处理器统一包装
}
}
使用 ResponseBodyAdvice 自动包装(最自动化)
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@RestControllerAdvice
public class ResponseWrapperAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 排除已经包装的响应和特定类型
return !returnType.getParameterType().equals(ApiResponse.class)
&& !returnType.getParameterType().equals(ResponseEntity.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// 对 String 类型特殊处理(避免类型转换错误)
if (body instanceof String) {
return ApiResponse.success((String) body);
}
return ApiResponse.success(body);
}
}
最佳实践建议
1 定义枚举响应码
public enum ResponseCode {
SUCCESS(200, "成功"),
BAD_REQUEST(400, "请求参数错误"),
UNAUTHORIZED(401, "未授权"),
FORBIDDEN(403, "禁止访问"),
NOT_FOUND(404, "资源不存在"),
METHOD_NOT_ALLOWED(405, "请求方法不允许"),
INTERNAL_ERROR(500, "服务器内部错误"),
BUSINESS_ERROR(1001, "业务逻辑错误");
private final int code;
private final String message;
ResponseCode(int code, String message) {
this.code = code;
this.message = message;
}
// getter ...
}
2 完整示例
// 使用总结
@RestController
@RequestMapping("/api")
public class DemoController {
@GetMapping("/example")
public ApiResponse<String> example() {
// 方式1:直接返回包装对象
return ApiResponse.success("Hello World");
}
@GetMapping("/auto-wrap")
public String autoWrap() {
// 方式2:配合 ResponseBodyAdvice 自动包装
return "自动包装";
}
@GetMapping("/error")
public void throwError() {
// 方式3:抛出异常由全局异常处理器处理
throw new BusinessException(1001, "自定义业务错误");
}
}
推荐方案
生产中推荐使用:全局异常处理器 + ResponseBodyAdvice 组合
- GlobalExceptionHandler:统一处理异常
- ResponseWrapperAdvice:自动包装成功响应
- BusinessException:自定义业务异常
这样控制器只需关注业务逻辑,返回纯数据对象即可,所有响应(成功/失败)都会统一封装成 ApiResponse 格式。