应使用@controlleradvice+responsebodyadvice全局自动包装json响应。定义result类封装code/msg/data,通过responseadvice对非result返回值自动套用ok(),再配合globalexceptionhandler统一处理各类异常并返回fail()格式。

在 Java 的 REST 接口中实现统一格式的 JSON 响应包装,核心是**避免每个接口手动封装 success/data/code/msg**,而是通过全局拦截或返回值处理器自动包装。主流方案是结合 Spring Boot 的 @ControllerAdvice + ResponseBodyAdvice,兼顾灵活性与一致性。
定义标准响应体类
先创建一个通用的响应结构,例如:
public class Result<t> {
private int code;
private String msg;
private T data;
// 成功构造(含数据)
public static <t> Result<t> ok(T data) {
return new Result(200, "success", data);
}
// 成功构造(无数据)
public static Result<void> ok() {
return new Result(200, "success", null);
}
// 失败构造
public static <t> Result<t> fail(int code, String msg) {
return new Result(code, msg, null);
}
// 私有构造器,强制使用静态工厂方法
private Result(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
// getter/setter 省略
}
</t></t></void></t></t></t>
用 ResponseBodyAdvice 全局包装返回值
实现 ResponseBodyAdvice,对所有 @RestController 的返回值自动套一层 Result(除已包装过的类型):
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
@ControllerAdvice
public class ResultResponseAdvice implements ResponseBodyAdvice<object> {
@Override
public boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType) {
// 跳过已返回 Result 类型的方法,避免重复包装
return !returnType.getParameterType().equals(Result.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class extends HttpMessageConverter>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// 若返回 null,包装为 ok()
if (body == null) {
return Result.ok();
}
// 若已是 Result,直接返回
if (body instanceof Result) {
return body;
}
// 其他情况统一包装为成功响应
return Result.ok(body);
}
}
</object>
配合全局异常处理统一错误响应
用 @ExceptionHandler 捕获业务异常、参数异常等,并返回标准 Result 错误格式:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.OK) // 仍走 200,由 code 区分业务状态
public Result<void> handleBusinessException(BusinessException e) {
return Result.fail(e.getCode(), e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<void> handleValidationException(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
return Result.fail(400, "参数校验失败: " + msg);
}
// 捕获未预期异常(500)
@ExceptionHandler(Exception.class)
public Result<void> handleUnexpected(Exception e) {
log.error("Uncaught error", e);
return Result.fail(500, "服务内部错误");
}
}
</void></void></void>
接口编写更简洁,无需关心包装逻辑
控制器方法只需专注业务逻辑,返回原始对象或 void:
-
返回实体:直接
return user;→ 自动转为{"code":200,"msg":"success","data":{...}} -
返回列表:直接
return userService.findAll();→ data 字段自动是数组 -
无返回值:写
public void deleteUser(...)或return;→ 自动转为{"code":200,"msg":"success","data":null} -
主动抛异常:如
throw new BusinessException(403, "权限不足");→ 触发异常处理器返回对应 Result
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










