How to Turn Bloated Spring Controllers into Clean, Maintainable Code
The article compares messy Spring MVC controllers packed with try‑catch, field checks, and business logic to concise, well‑structured versions that use @Valid, service delegation, and global exception handling, and provides a step‑by‑step refactoring guide.
Problem: Overly Complex Controllers
Controllers that contain thousands of lines, repetitive if checks, extensive try‑catch blocks, and inline business logic are hard to read, test and maintain.
Refactored (Graceful) Controller
By delegating validation to Spring and moving business logic to services, the controller size can be reduced by roughly 50%.
@RestController
@RequestMapping("/user/test")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService userService;
@Autowired
private AuthService authService;
@PostMapping("/userRegistration")
public CommonResult userRegistration(@RequestBody @Valid UserVo userVo) {
userService.registerUser(userVo.getUsername());
return CommonResult.ok();
}
@PostMapping("/login")
@PermitAll
@ApiOperation("使用账号密码登录")
public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
return success(authService.login(reqVO));
}
}All validation and error handling are now centralized, making the controller concise and testable.
Validation with @Valid
Apply @Valid on request‑body parameters and annotate the fields of the VO (Value Object) with Bean Validation constraints.
@ApiModel(value = "管理后台 - 账号密码登录 Request VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AuthLoginReqVO {
@ApiModelProperty(value = "账号", required = true, example = "user")
@NotEmpty(message = "登录账号不能为空")
@Length(min = 4, max = 16, message = "账号长度为 4-16 位")
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母")
private String username;
@ApiModelProperty(value = "密码", required = true, example = "password")
@NotEmpty(message = "密码不能为空")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
}When a POST request arrives, Spring automatically validates the object. If validation succeeds, the method proceeds; otherwise a MethodArgumentNotValidException is thrown.
Why use @Valid ?
Eliminates verbose if checks.
Improves readability and keeps controller responsibilities focused on routing.
Related annotations
@NotEmpty, @Length, @Pattern – define constraints on individual fields.
Difference between @Valid and @Validated
@Validatedsupports validation groups, allowing selective validation of fields, while @Valid validates all constraints on the object.
Global Exception Handling
A centralized @RestControllerAdvice captures validation errors and any uncaught exceptions, returning a uniform CommonResult response.
@ResponseBody
@RestControllerAdvice
public class ExceptionHandlerAdvice {
private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlerAdvice.class);
@ExceptionHandler(MethodArgumentNotValidException.class)
public CommonResult<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
logger.error("[handleValidationExceptions]", ex);
StringBuilder sb = new StringBuilder();
ex.getBindingResult().getAllErrors().forEach(error -> {
String field = ((org.springframework.validation.FieldError) error).getField();
sb.append(field).append(":").append(error.getDefaultMessage()).append(";");
});
return CommonResult.error(sb.toString());
}
@ExceptionHandler(Exception.class)
public CommonResult<?> defaultExceptionHandler(Throwable ex) {
logger.error("[defaultExceptionHandler]", ex);
return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
}
}This approach ensures that validation failures and unexpected errors are reported consistently.
Benefits of the Refactor
Business logic is isolated in service layers, improving reuse.
Controller methods stay under 80–100 lines, aligning with common style guides.
Code is easier to read, test, and maintain.
Centralized validation and exception handling reduce duplication.
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.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
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.
