本文目录导读:

我来为您提供一个完整的Spring Boot统一返回格式的实现案例。
项目结构
src/main/java/com/example/demo/
├── DemoApplication.java
├── common/
│ ├── Result.java // 统一返回结果类
│ ├── ResultCode.java // 返回状态码枚举
│ └── GlobalExceptionHandler.java // 全局异常处理器
├── controller/
│ └── UserController.java
├── service/
│ ├── UserService.java
│ └── impl/
│ └── UserServiceImpl.java
├── entity/
│ └── User.java
└── config/
└── WebMvcConfig.java // Web配置(可选)
统一返回结果类实现
1 状态码枚举类
package com.example.demo.common;
import lombok.Getter;
/**
* 返回状态码枚举
*/
@Getter
public enum ResultCode {
SUCCESS(200, "操作成功"),
ERROR(500, "操作失败"),
PARAM_ERROR(400, "参数错误"),
UNAUTHORIZED(401, "未认证"),
FORBIDDEN(403, "无权限"),
NOT_FOUND(404, "资源不存在"),
// 业务相关错误码
USER_NOT_EXIST(1001, "用户不存在"),
USER_ALREADY_EXIST(1002, "用户已存在"),
PASSWORD_ERROR(1003, "密码错误"),
USERNAME_ERROR(1004, "用户名错误"),
// 系统错误码
SYSTEM_ERROR(5000, "系统异常"),
DATABASE_ERROR(5001, "数据库异常");
// 状态码
private final Integer code;
// 返回消息
private final String message;
ResultCode(Integer code, String message) {
this.code = code;
this.message = message;
}
}
2 统一返回结果类
package com.example.demo.common;
import lombok.Data;
import java.io.Serializable;
/**
* 统一返回结果类
*/
@Data
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 状态码
*/
private Integer code;
/**
* 返回消息
*/
private String message;
/**
* 返回数据
*/
private T data;
/**
* 时间戳
*/
private Long timestamp;
public Result() {
this.timestamp = System.currentTimeMillis();
}
/**
* 成功返回结果
*/
public static <T> Result<T> success() {
return success(null);
}
/**
* 成功返回结果
*/
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(ResultCode.SUCCESS.getMessage());
result.setData(data);
return result;
}
/**
* 成功返回结果(自定义消息)
*/
public static <T> Result<T> success(String message, T data) {
Result<T> result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(message);
result.setData(data);
return result;
}
/**
* 失败返回结果
*/
public static <T> Result<T> error() {
return error(ResultCode.ERROR);
}
/**
* 失败返回结果(自定义信息)
*/
public static <T> Result<T> error(String message) {
return error(ResultCode.ERROR.getCode(), message);
}
/**
* 失败返回结果(使用枚举)
*/
public static <T> Result<T> error(ResultCode resultCode) {
return error(resultCode.getCode(), resultCode.getMessage());
}
/**
* 失败返回结果(自定义状态码和消息)
*/
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
return result;
}
}
3 业务异常类
package com.example.demo.common;
import lombok.Getter;
/**
* 业务异常类
*/
@Getter
public class BusinessException extends RuntimeException {
private final Integer code;
private final String message;
public BusinessException(String message) {
super(message);
this.code = ResultCode.ERROR.getCode();
this.message = message;
}
public BusinessException(ResultCode resultCode) {
super(resultCode.getMessage());
this.code = resultCode.getCode();
this.message = resultCode.getMessage();
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
this.message = message;
}
}
4 全局异常处理器
package com.example.demo.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;
/**
* 全局异常处理器
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理业务异常
*/
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
log.error("业务异常:{}", e.getMessage());
return Result.error(e.getCode(), e.getMessage());
}
/**
* 处理参数校验异常(@RequestBody)
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
log.error("参数校验异常:{}", message);
return Result.error(ResultCode.PARAM_ERROR.getCode(), message);
}
/**
* 处理参数绑定异常
*/
@ExceptionHandler(BindException.class)
public Result<?> handleBindException(BindException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
log.error("参数绑定异常:{}", message);
return Result.error(ResultCode.PARAM_ERROR.getCode(), message);
}
/**
* 处理参数校验异常(@RequestParam)
*/
@ExceptionHandler(ConstraintViolationException.class)
public Result<?> handleConstraintViolationException(ConstraintViolationException e) {
String message = e.getConstraintViolations().stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
log.error("参数约束异常:{}", message);
return Result.error(ResultCode.PARAM_ERROR.getCode(), message);
}
/**
* 处理其他未知异常
*/
@ExceptionHandler(Exception.class)
public Result<?> handleException(Exception e) {
log.error("系统异常:", e);
return Result.error(ResultCode.SYSTEM_ERROR.getCode(), ResultCode.SYSTEM_ERROR.getMessage());
}
}
实体类
package com.example.demo.entity;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
public class User {
private Long id;
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度必须在6-20之间")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
@NotNull(message = "年龄不能为空")
private Integer age;
}
Controller层示例
package com.example.demo.controller;
import com.example.demo.common.Result;
import com.example.demo.entity.User;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/users")
public class UserController {
/**
* 模拟用户数据
*/
private static final Map<Long, User> USER_MAP = new HashMap<>();
static {
User user1 = new User();
user1.setId(1L);
user1.setUsername("zhangsan");
user1.setPassword("123456");
user1.setEmail("zhangsan@example.com");
user1.setAge(25);
USER_MAP.put(1L, user1);
User user2 = new User();
user2.setId(2L);
user2.setUsername("lisi");
user2.setPassword("123456");
user2.setEmail("lisi@example.com");
user2.setAge(30);
USER_MAP.put(2L, user2);
}
/**
* 查询所有用户
* GET /api/users
*/
@GetMapping
public Result<List<User>> list() {
List<User> users = new ArrayList<>(USER_MAP.values());
return Result.success(users);
}
/**
* 根据ID查询用户
* GET /api/users/{id}
*/
@GetMapping("/{id}")
public Result<User> getUserById(@PathVariable Long id) {
User user = USER_MAP.get(id);
if (user == null) {
return Result.error("用户不存在");
}
return Result.success(user);
}
/**
* 创建用户
* POST /api/users
*/
@PostMapping
public Result<User> create(@Valid @RequestBody User user) {
// 模拟创建用户
Long id = (long) (USER_MAP.size() + 1);
user.setId(id);
USER_MAP.put(id, user);
return Result.success("创建用户成功", user);
}
/**
* 更新用户
* PUT /api/users/{id}
*/
@PutMapping("/{id}")
public Result<User> update(@PathVariable Long id, @Valid @RequestBody User user) {
if (!USER_MAP.containsKey(id)) {
return Result.error("用户不存在");
}
user.setId(id);
USER_MAP.put(id, user);
return Result.success("更新用户成功", user);
}
/**
* 删除用户
* DELETE /api/users/{id}
*/
@DeleteMapping("/{id}")
public Result<?> delete(@PathVariable Long id) {
if (!USER_MAP.containsKey(id)) {
return Result.error("用户不存在");
}
USER_MAP.remove(id);
return Result.success("删除用户成功");
}
}
Service层示例(带异常处理)
package com.example.demo.service;
import com.example.demo.common.BusinessException;
import com.example.demo.common.ResultCode;
import com.example.demo.entity.User;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserService {
private static final Map<Long, User> USER_MAP = new HashMap<>();
static {
User user1 = new User();
user1.setId(1L);
user1.setUsername("zhangsan");
user1.setPassword("123456");
user1.setEmail("zhangsan@example.com");
user1.setAge(25);
USER_MAP.put(1L, user1);
}
/**
* 查询所有用户
*/
public List<User> findAll() {
return new ArrayList<>(USER_MAP.values());
}
/**
* 根据ID查询用户
*/
public User findById(Long id) {
User user = USER_MAP.get(id);
if (user == null) {
throw new BusinessException(ResultCode.USER_NOT_EXIST);
}
return user;
}
/**
* 创建用户
*/
public User create(User user) {
// 检查用户名是否已存在
boolean exists = USER_MAP.values().stream()
.anyMatch(u -> u.getUsername().equals(user.getUsername()));
if (exists) {
throw new BusinessException(ResultCode.USER_ALREADY_EXIST);
}
Long id = (long) (USER_MAP.size() + 1);
user.setId(id);
USER_MAP.put(id, user);
return user;
}
/**
* 更新用户
*/
public User update(Long id, User user) {
if (!USER_MAP.containsKey(id)) {
throw new BusinessException(ResultCode.USER_NOT_EXIST);
}
user.setId(id);
USER_MAP.put(id, user);
return user;
}
/**
* 删除用户
*/
public void delete(Long id) {
if (!USER_MAP.containsKey(id)) {
throw new BusinessException(ResultCode.USER_NOT_EXIST);
}
USER_MAP.remove(id);
}
}
配置类(可选)
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 配置跨域(如有需要)
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.maxAge(3600);
}
}
主启动类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
测试用例
package com.example.demo;
import com.example.demo.common.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureMockMvc
class DemoApplicationTests {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
void testGetUserById() throws Exception {
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.message").value("操作成功"))
.andExpect(jsonPath("$.data.username").value("zhangsan"));
}
@Test
void testGetUserNotExist() throws Exception {
mockMvc.perform(get("/api/users/999"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(500))
.andExpect(jsonPath("$.message").value("用户不存在"));
}
@Test
void testCreateUser() throws Exception {
String userJson = "{\"username\":\"wangwu\",\"password\":\"123456\",\"email\":\"wangwu@example.com\",\"age\":28}";
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(userJson))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data.username").value("wangwu"));
}
@Test
void testCreateUserValidation() throws Exception {
// 测试参数校验
String invalidUserJson = "{\"username\":\"w\",\"password\":\"123\",\"email\":\"invalid-email\",\"age\":-1}";
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(invalidUserJson))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(400));
}
}
在Controller中使用Service
package com.example.demo.controller;
import com.example.demo.common.Result;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
/**
* 查询所有用户
*/
@GetMapping
public Result<List<User>> list() {
return Result.success(userService.findAll());
}
/**
* 根据ID查询用户
*/
@GetMapping("/{id}")
public Result<User> getUserById(@PathVariable Long id) {
return Result.success(userService.findById(id));
}
/**
* 创建用户
*/
@PostMapping
public Result<User> create(@Valid @RequestBody User user) {
return Result.success("创建用户成功", userService.create(user));
}
/**
* 更新用户
*/
@PutMapping("/{id}")
public Result<User> update(@PathVariable Long id, @Valid @RequestBody User user) {
return Result.success("更新用户成功", userService.update(id, user));
}
/**
* 删除用户
*/
@DeleteMapping("/{id}")
public Result<?> delete(@PathVariable Long id) {
userService.delete(id);
return Result.success("删除用户成功");
}
}
响应示例
成功响应:
{
"code": 200,
"message": "操作成功",
"data": {
"id": 1,
"username": "zhangsan",
"password": "123456",
"email": "zhangsan@example.com",
"age": 25
},
"timestamp": 1700000000000
}
失败响应:
{
"code": 1001,
"message": "用户不存在",
"data": null,
"timestamp": 1700000000000
}
Maven依赖
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
使用说明
应用场景:
- 前后端分离:统一接口返回格式,方便前端处理
- API设计:统一错误码和消息格式
- 异常处理:统一异常捕获和转换
优势:
- 统一规范:所有接口返回格式一致
- 错误处理:全局异常处理,避免重复代码
- 可维护性:状态码和消息集中管理
- 扩展性:易于添加新的返回类型和状态码
注意事项:
- 状态码规划:合理规划业务状态码,避免冲突
- 异常处理:根据业务需求选择合适的异常处理方式
- 参数校验:结合
@Valid实现参数验证 - 日志记录:在异常处理器中添加日志,便于问题排查
这个实现方案涵盖了统一返回格式的完整实现,包括正常返回、异常处理、参数校验等场景,您可以根据实际需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播