Backend Development 18 min read

Best Practices for Spring MVC Controller Design: Unified Response, Validation, and Exception Handling

This article explains how to design Spring MVC controllers with a unified response structure, implement request validation using JSR‑303 and custom annotations, handle exceptions uniformly, and resolve issues with ResponseBodyAdvice and HttpMessageConverters to improve code clarity and maintainability.

Top Architect
Top Architect
Top Architect
Best Practices for Spring MVC Controller Design: Unified Response, Validation, and Exception Handling

The article discusses the role of the Controller in Spring MVC, emphasizing its responsibilities such as receiving requests, delegating to Service, handling exceptions, and returning responses.

It lists the typical tasks performed by a Controller and provides sample DTO, Service, and Controller code illustrating basic request handling and error throwing.

To achieve a consistent API contract, the author introduces a unified response structure (IResult, ResultEnum, Result ) and shows how to wrap all controller responses using a custom ResponseAdvice that implements ResponseBodyAdvice . The advice checks if the body is already wrapped, handles String return types by converting the Result to JSON, and otherwise returns Result.success(body) .

The article also addresses a common issue where ResponseBodyAdvice combined with StringHttpMessageConverter causes a class‑cast exception. Two solutions are presented: manually converting the Result to a JSON string for String responses, or reordering the MappingJackson2HttpMessageConverter ahead of the StringHttpMessageConverter in the converter list.

For request validation, it explains the use of JSR‑303 (Hibernate Validator) and Spring's @Validated annotation on controller methods and DTO fields, showing how validation errors trigger MethodArgumentNotValidException . The validation flow inside RequestResponseBodyMethodProcessor and AbstractMessageConverterMethodArgumentResolver is described.

Custom validation rules are demonstrated with a @Mobile annotation and a corresponding MobileValidator implementing ConstraintValidator , illustrating how to define custom constraints and integrate them into the validation process.

Finally, the article defines custom runtime exceptions ( ForbiddenException , BusinessException ) and a global @RestControllerAdvice ( ExceptionAdvice ) that catches these exceptions, as well as validation exceptions, and returns a unified Result object with appropriate error codes and messages, ensuring that all API responses share the same structure and HTTP status 200.

JavaException HandlingValidationControllerSpring MVCResponseBodyAdvice
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.