Three companion modules verifying and rewriting the Boot 4.1.1 / Framework 7.0.9 story for three older articles: the javax->jakarta.validation namespace fix plus Jakarta Validation 3.1 record-validation clarification, ETag/ conditional-request APIs re-verified unchanged plus the starter rename, and RestTemplate Basic Auth rebuilt on RestClient with the exchange() trap called out. 19 real passing tests generate every transcript quoted from the three companion articles. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EQNA6DJ9VgCtW6zhCE8Xud
67 lines
3.3 KiB
Markdown
67 lines
3.3 KiB
Markdown
# custom-validation
|
|
|
|
Companion module for [**Custom Validation in Spring Boot: Beyond the Basics!**](https://ankurm.com/custom-validation-in-spring-boot-beyond-the-basics/)
|
|
on ankurm.com, rewritten around **Jakarta Validation 3.1** (Spring Boot 4.1.1 / Hibernate Validator
|
|
9.1.3.Final) and the `jakarta.validation` namespace the original article's `javax.validation` code
|
|
never actually ran under on Boot 3+.
|
|
|
|
`mvn test` regenerates every transcript in [`docs/output/`](docs/output) -- the test suite is the
|
|
transcript generator.
|
|
|
|
## Versions
|
|
|
|
| | |
|
|
|---|---|
|
|
| Spring Boot | 4.1.1 |
|
|
| Spring Framework | 7.0.9 |
|
|
| Hibernate Validator | 9.1.3.Final (`jakarta.validation-api` 3.1.1) -- confirmed with `mvn dependency:tree` and by reading the jars' own manifests, see [docs/01](docs/01-jakarta-namespace-and-bean-validation-3-1.md) |
|
|
| JDK | Eclipse Temurin 25.0.4.1 (LTS) |
|
|
|
|
## Quickstart
|
|
|
|
```bash
|
|
export JAVA_HOME=/path/to/jdk-25
|
|
mvn -DskipTests package
|
|
./scripts/run.sh # port 8080
|
|
curl -s -X POST localhost:8080/contact -H 'Content-Type: application/json' \
|
|
-d '{"email":"[email protected]","message":"hello there, this message is long enough"}'
|
|
mvn test # 10 tests, regenerates docs/output/
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
| Endpoint | Shows |
|
|
|---|---|
|
|
| `POST /contact` | field-level custom constraint (`@SpamMessageCheck`), class-based DTO, `BindingResult` |
|
|
| `POST /contact-record` | the same constraint on a record component |
|
|
| `POST /booking` | class-level (cross-field) custom constraint (`@DateRangeValid`), class-based DTO |
|
|
| `POST /booking-record` | the same cross-field constraint on a record's type declaration |
|
|
| `GET /diagnostic/validation-provider` | prints the real Bean Validation provider and spec version at runtime -- delete before shipping |
|
|
|
|
## Documentation
|
|
|
|
1. [The jakarta.validation namespace, and what Bean Validation 3.1 actually changed](docs/01-jakarta-namespace-and-bean-validation-3-1.md)
|
|
2. [Record validation, field-level and class-level](docs/02-record-validation.md)
|
|
3. [What the defaults do not do: record validation failures with no error body](docs/03-what-the-defaults-do-not-do.md)
|
|
|
|
## Findings worth the trip
|
|
|
|
- **The original article's `javax.validation.*` imports never worked on Spring Boot 3+.** Boot 3
|
|
moved entirely to the `jakarta.*` namespace in December 2022; this module is the corrected,
|
|
runnable version.
|
|
- **Spring Boot 4.1.1 pins Hibernate Validator 9.1.3.Final / Jakarta Validation 3.1**, confirmed
|
|
by `mvn dependency:tree` and independently by reading the actual jar manifests at test time.
|
|
- **A record validation failure with no `BindingResult` in the controller signature returns an
|
|
EMPTY 400 body by default** -- not a JSON error, not even with `Accept: application/json`.
|
|
- **`spring.mvc.problemdetails.enabled=true` fixes the empty body but not the missing detail**:
|
|
the resulting `ProblemDetail` is generic (`"Invalid request content."`), with no per-field
|
|
messages, unless you write a custom `@ExceptionHandler` to put them there yourself.
|
|
- **`AutoConfigureMockMvc` moved packages in Boot 4.1**, from
|
|
`org.springframework.boot.test.autoconfigure.web.servlet` to
|
|
`org.springframework.boot.webmvc.test.autoconfigure` -- and `spring-boot-starter-test` alone no
|
|
longer pulls in MockMvc's autoconfiguration; that needs `spring-boot-starter-webmvc-test`.
|
|
|
|
## License
|
|
|
|
MIT -- see [LICENSE](../LICENSE).
|