SmartMVC
All docs
Guide
Features
Authentication
Example
Reference
  • 简体中文
  • English
  • 日本語
  • Русский
GitHub
All docs
Guide
Features
Authentication
Example
Reference
  • 简体中文
  • English
  • 日本語
  • Русский
GitHub
  • Core features

    • Consistent responses
    • Exceptions and request validation
    • Date and time
    • Request logging

Consistent responses

A consistent response contract lets every client use the same rules to determine whether a request succeeded, read its data, and present an appropriate message.

Response structure

ApiResponse<T> contains five fields:

FieldTypeMeaning
successbooleanWhether the request completed as expected
codeStringA machine-readable result code
messageStringA human-readable explanation
dataTBusiness data or error details
timestamplongThe response creation time in milliseconds

Automatic wrapping

When response.wrap-enabled is enabled, an ordinary controller return value automatically becomes a successful response:

@GetMapping("/{id}")
public UserView get(@PathVariable Long id) {
    return userService.get(id);
}

You do not need to call ApiResponse.success(...) in every controller method.

String return values are wrapped correctly as well. Even when Spring selects StringHttpMessageConverter, SmartMVC writes JSON rather than treating the response object as plain text.

Response types that remain unchanged

SmartMVC does not wrap these return types:

  • an object that is already an ApiResponse;
  • byte[];
  • a Spring Resource;
  • StreamingResponseBody;
  • ProblemDetail.

These types commonly represent files, binary data, streaming output, or a standard problem response. Adding another JSON envelope would interfere with their intended behavior.

Creating a response explicitly

When an endpoint needs a specific message or error code, return an ApiResponse directly:

return ApiResponse.success("User created", userView);
return ApiResponse.failure(
        "ORDER_CLOSED",
        "The order is already closed",
        Map.of("orderId", orderId)
);

A direct ApiResponse is recognized and will not be wrapped a second time.

void return values

By default, void and Void become successful responses with data: null.

spring:
  smart:
    mvc:
      response:
        wrap-void: false

With this setting disabled, a void return value no longer produces the response envelope.

Paginated results

PageResult<T> is a general-purpose pagination model. It does not depend on a database or a particular pagination library:

PageResult<UserView> result = new PageResult<>(
        users,
        total,
        page,
        pageSize
);

It provides:

  • items — the records on the current page;
  • total — the total number of records;
  • page — the current page number;
  • pageSize — the number of records per page;
  • totalPages — the page count calculated from total and pageSize.

Why are Long values strings by default?

JavaScript cannot represent every 64-bit integer exactly. SmartMVC therefore serializes long and Long values as strings by default:

spring.smart.mvc.response.long-as-string: true

You can disable this option when every client can safely process 64-bit integer values.

Configuration

spring:
  smart:
    mvc:
      response:
        wrap-enabled: true
        wrap-void: true
        success-message: success
        long-as-string: true

When wrap-enabled is false, the automatic response-enhancement bean is not registered, and Spring MVC handles controller return values without SmartMVC wrapping.

Edit this page on GitHub
Last updated: 8/7/26, 8:33 AM
Previous
How a request moves through SmartMVC
Next
Exceptions and validation