Simplify Spring Boot APIs with Graceful Response: A Quick Guide
This article introduces the Graceful Response component for Spring Boot, explaining how it provides unified response wrapping, global exception handling, and custom error codes to eliminate boilerplate, improve readability, and streamline API development with practical code examples and configuration tips.
Introduction
Graceful Response is a Spring Boot component that offers a one‑stop solution for unified response wrapping, global exception handling, and custom error codes, helping developers save time, improve code quality, and make controller logic clearer.
Strongly recommended to spend 3 minutes learning it!
Project example repository: https://github.com/feiniaojin/graceful-response-example.git (choose the latest branch).
Supported Spring Boot versions: 2.x with Graceful Response 3.2.1‑boot2, and 3.x with Graceful Response 3.2.1‑boot3.
Current Problems in Spring Boot API Development
In typical Spring Boot projects, controller code often suffers from low efficiency, repetitive boilerplate, and poor readability. The following pseudo‑code illustrates the common pattern:
@Controller
public class Controller {
@GetMapping("/query")
@ResponseBody
public Response query(Map<String, Object> paramMap) {
Response res = new Response();
try {
// 1. Validate params
if (illegal(paramMap)) {
res.setCode(1);
res.setMsg("error");
return res;
}
// 2. Call service
Object data = service.query(params);
// 3. Set result
res.setData(data);
res.setCode(0);
res.setMsg("ok");
return res;
} catch (Exception e) {
// 4. Exception handling
res.setCode(1);
res.setMsg("error");
return res;
}
}
}The issues are:
Low efficiency : Most of the code is dedicated to wrapping results rather than business logic.
Repetitive work : Every endpoint repeats the same validation and wrapping steps.
Poor readability : Core logic is buried under redundant code.
Graceful Response can solve these problems.
Quick Start
Adding Graceful Response
Graceful Response is published to Maven Central. Add the dependency:
<dependency>
<groupId>com.feiniaojin</groupId>
<artifactId>graceful-response</artifactId>
<version>{latest.version}</version>
</dependency>Enable Graceful Response
Annotate the main application class:
@EnableGracefulResponse
@SpringBootApplication
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}Controller Layer
After enabling the component, controller methods can return plain objects; Graceful Response will automatically wrap them.
@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();
}
}The actual HTTP response becomes:
{
"status": {"code": "0", "msg": "ok"},
"payload": {"id": 1, "name": "name1"}
}For command‑type endpoints that return void, Graceful Response still produces a wrapped response:
@RequestMapping("/command")
@ResponseBody
public void command() {
// business logic
} {
"status": {"code": "200", "msg": "success"},
"payload": {}
}Service Layer
Before using Graceful Response, some developers return a custom Response object from service methods, mixing business data with status codes. With Graceful Response, service methods return plain business objects, and exceptions are mapped to status codes via @ExceptionMapper.
@ExceptionMapper(code = "1404", msg = "找不到对象")
public class NotFoundException extends RuntimeException {} public interface QueryService {
UserInfoView queryOne(Query query);
} public class QueryServiceImpl implements QueryService {
@Resource
private UserInfoMapper mapper;
public UserInfoView queryOne(Query query) {
UserInfo userInfo = mapper.findOne(query.getId());
if (Objects.isNull(userInfo)) {
throw new NotFoundException();
}
// further business logic
}
}If NotFoundException is thrown, the response is:
{
"status": {"code": "1404", "msg": "找不到对象"},
"payload": {}
}Parameter Validation
Graceful Response enhances JSR‑303 validation. By adding @ValidationStatusCode to a validation annotation, the specified error code is used when validation fails.
@Data
public class UserInfoQuery {
@NotNull(message = "userName is null !")
@Length(min = 6, max = 12)
@ValidationStatusCode(code = "520")
private String userName;
}When validation fails, the response is:
{
"status": {"code": "520", "msg": "userName is null !"},
"payload": {}
}Method‑level validation works similarly:
public class Controller {
@RequestMapping("/validateMethodParam")
@ResponseBody
@ValidationStatusCode(code = "1314")
public void validateMethodParam(@NotNull(message = "userId不能为空") Long userId,
@NotNull(message = "userName不能为空") Long userName) {
// business logic
}
} {
"status": {"code": "1314", "msg": "userId不能为空"},
"payload": {}
}Custom Response Formats
Graceful Response provides two built‑in response styles, configurable via graceful-response.response-style:
Style 0 (default):
{
"status": {"code": 1007, "msg": "有内鬼,终止交易"},
"payload": {}
}Style 1:
{
"code": "1404",
"msg": "not found",
"data": {}
}If neither format fits, users can define their own response structure.
Advanced Features
Third‑party integrations (Swagger, actuator, etc.)
Custom response bodies
Exception pass‑through
Exception aliasing
Common configuration items
Project Address
GitHub repository: https://github.com/feiniaojin/graceful-response
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
