A controller advice can map object and direct-parameter validation failures to one stable ProblemDetail response.
Spring MVC validation errors: one public ProblemDetail for two failure paths
Keep the public response small
The source-kit advice handles MethodArgumentNotValidException and HandlerMethodValidationException. The test sends an empty JSON note and a count of zero; both produce HTTP 400 with the title Invalid receipt request. The handler leaves out raw submitted values and internal exception text. That makes the response predictable without leaking parser or validation internals.
A production API should define a stable machine-readable type, field error keys, localization policy and correlation ID. Do not make the human title the only programmatic contract. The base ProblemDetail lesson covers the error envelope; the validation-path lesson explains why two exception classes matter.
Test the installed advice
This fixture registers advice explicitly with standalone MockMvc. That is enough for its mapping but does not prove the same advice is component-scanned into the running Boot application. A web-context test should assert registered advice and filters together. Avoid returning every validation message from third-party constraints without an output policy.
Checked source
@RestControllerAdvice
static class ValidationAdvice {
@ExceptionHandler({MethodArgumentNotValidException.class,
HandlerMethodValidationException.class})
ProblemDetail invalidRequest(Exception rejected) {
ProblemDetail problem = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
problem.setTitle("Invalid receipt request");
problem.setDetail("Check the submitted fields and limits.");
return problem;
}
}Verification boundary
MvcProblemAdviceTest.twoValidationPathsReturnOnePublicErrorShape runs in the downloadable Spring source kit. The excerpt omits imports and surrounding setup; the kit contains the complete tests.
Costs and limits
The test checks two local 400 responses, not every invalid input, localization or production filter path. Advice code runs once per rejected request; large field-error lists need a deliberate bound before serialization.
Common Mistakes
- Do not expose rejected secrets or stack traces in an error body.
- Do not assume standalone advice registration proves application component scanning.
- Do not let two validation paths return unrelated API shapes.
Read next
Spring MVC validation paths: object constraints and method parameters, Spring MVC ProblemDetail: stable errors without leaking internals, Spring MockMvc standalone tests: know which HTTP layers were assembled.
