作者注:本文将带你快速了解并上手 Spring Boot 下的一站式优雅响应解决方案 —— Graceful Response,让你的接口开发更简洁、更规范、更高效。
Graceful Response 是一个基于 Spring Boot 技术栈的优雅响应处理器,提供以下功能:
使用 Graceful Response 进行 Web 接口开发,不仅能节省大量模板式代码,还能显著提升代码质量与可读性,让逻辑更加清晰。
示例工程地址: https://github.com/feiniaojin/graceful-response-example.git
| Spring Boot 版本 | Graceful Response 版本 | 示例分支 |
|---|---|---|
| 2.x | 3.2.1-boot2 / 3.2.0-boot2 | boot2 分支 |
| 3.x | 3.2.1-boot3 / 3.2.0-boot3 | boot3 分支 |
注意:3.2.1-boot2 版本源码由独立仓库维护 → graceful-response-boot2 除了 Spring Boot 版本不同,其他实现完全一致。
一个常见的 Controller 示例:
java@Controller
public class Controller {
@GetMapping("/query")
@ResponseBody
public Response query(Map<String, Object> paramMap) {
Response res = new Response();
try {
if (illegal(paramMap)) {
res.setCode(1);
res.setMsg("error");
return res;
}
Object data = service.query(paramMap);
res.setData(data);
res.setCode(0);
res.setMsg("ok");
return res;
} catch (Exception e) {
res.setCode(1);
res.setMsg("error");
return res;
}
}
}
返回格式如下:
json{
"code": 0,
"msg": "ok",
"data": {
"id": 1,
"name": "username"
}
}
效率低下 代码中大量重复的异常捕获与结果封装逻辑。
重复劳动 每个接口都要写同样的 try...catch 和封装逻辑。
可读性差 核心业务逻辑被冗余代码淹没,维护困难。
在 pom.xml 中加入:
xml<dependency>
<groupId>com.feiniaojin</groupId>
<artifactId>graceful-response</artifactId>
<version>{latest.version}</version>
</dependency>
在 Spring Boot 启动类上添加注解:
java@EnableGracefulResponse
@SpringBootApplication
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
引入 Graceful Response 后,Controller 无需手动封装返回结果:
java@Controller
public class Controller {
@RequestMapping("/get")
@ResponseBody
public UserInfoView get(Long id) {
log.info("id={}", id);
return UserInfoView.builder().id(id).name("name" + id).build();
}
}
返回结果自动封装为:
json{
"status": {
"code": "0",
"msg": "ok"
},
"payload": {
"id": 1,
"name": "name1"
}
}
对于无返回值(Command)操作:
java@RequestMapping("/command")
@ResponseBody
public void command() {
// 业务操作
}
返回结果自动为:
json{
"status": {
"code": "200",
"msg": "success"
},
"payload": {}
}
有些开发者直接让 Service 层返回 Response 对象:
java@Data
public class Response {
private String code;
private String msg;
private Object data;
}
这种做法污染了业务逻辑,不规范。
Graceful Response 通过 @ExceptionMapper 将异常与错误码绑定。
java@ExceptionMapper(code = "1404", msg = "找不到对象")
public class NotFoundException extends RuntimeException {}
Service 示例:
javapublic interface QueryService {
UserInfoView queryOne(Query query);
}
public class QueryServiceImpl implements QueryService {
@Resource
private UserInfoMapper mapper;
@Override
public UserInfoView queryOne(Query query) {
UserInfo userInfo = mapper.findOne(query.getId());
if (Objects.isNull(userInfo)) {
throw new NotFoundException();
}
return new UserInfoView(...);
}
}
当抛出 NotFoundException 时,接口返回:
json{
"status": {
"code": "1404",
"msg": "找不到对象"
},
"payload": {}
}
Graceful Response 与 JSR-303 / Hibernate Validator 无缝集成,并支持通过 @ValidationStatusCode 指定错误码。
java@Data
public class UserInfoQuery {
@NotNull(message = "userName is null !")
@Length(min = 6, max = 12)
@ValidationStatusCode(code = "520")
private String userName;
}
当校验不通过时,返回:
json{
"status": {
"code": "520",
"msg": "userName is null !"
},
"payload": {}
}
java@RequestMapping("/validateMethodParam")
@ResponseBody
@ValidationStatusCode(code = "1314")
public void validateMethodParam(
@NotNull(message = "userId不能为空") Long userId,
@NotNull(message = "userName不能为空") Long userName) {
// 业务逻辑
}
返回结果:
json{
"status": {
"code": "1314",
"msg": "userId不能为空"
},
"payload": {}
}
Graceful Response 内置两种风格,通过配置项设置:
propertiesgraceful-response.response-style=0
json{
"status": {
"code": 1007,
"msg": "有内鬼,终止交易"
},
"payload": {}
}
propertiesgraceful-response.response-style=1
json{
"code": "1404",
"msg": "not found",
"data": {}
}
如果默认两种格式不满足需求,Graceful Response 也支持 完全自定义响应结构。 具体实现请参考官方文档中的 自定义Response格式 章节。
该组件在 GitHub 上已获得 200+ Star,并被众多开发者在生产环境中使用。 项目主页:https://github.com/feiniaojin/graceful-response
Graceful Response 是一个轻量但强大的 Spring Boot 插件, 它让我们从繁琐的异常处理与统一返回封装中解放出来。
一句话总结:
让你的 Controller 只负责业务逻辑,让 Graceful Response 负责优雅响应。
本文作者:zjx171
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!