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
3.5 KiB
2. RestClient with Basic Auth, two ways
Prev: {noop} passwords | README | Next: The starter split, and the exchange() trap
Source: RestClientConfig.java,
ApiClient.java.
Test: RestClientBasicAuthTest.java.
Transcripts: docs/output/01-restclient-basic-auth-default-headers.txt,
docs/output/02-restclient-basic-auth-interceptor.txt.
The original article's two RestTemplate patterns -- RestTemplateBuilder.basicAuthentication(...)
and a hand-added BasicAuthenticationInterceptor -- both have a direct RestClient equivalent.
Both are built on the auto-configured RestClient.Builder injected as a constructor parameter,
never RestClient.create(), which carries none of Boot's message converters, observability, or
customizer beans -- the same rule the
RestTemplate to RestClient migration guide
covers in more general depth.
Idiomatic on RestClient: defaultHeaders + setBasicAuth
@Bean
public RestClient restClientWithDefaultHeaders(RestClient.Builder builder) {
return builder
.defaultHeaders(headers -> headers.setBasicAuth("admin", "password123"))
.build();
}
Response: Hello, you have accessed a secured endpoint!
(docs/output/01-restclient-basic-auth-default-headers.txt)
-- a real HTTP call against a real embedded Tomcat with a real Spring Security filter chain, not a
mock.
Ported unchanged: BasicAuthenticationInterceptor
@Bean
public RestClient restClientWithInterceptor(RestClient.Builder builder) {
return builder
.requestInterceptor(new BasicAuthenticationInterceptor("admin", "password123"))
.build();
}
BasicAuthenticationInterceptor implements ClientHttpRequestInterceptor -- the exact same
interface both RestTemplate.getInterceptors() and RestClient.Builder.requestInterceptor(...)
accept, so this class needs no changes at all to move from one client to the other. Same result:
docs/output/02-restclient-basic-auth-interceptor.txt.
Prefer defaultHeaders when the credentials are fixed at bean-creation time; keep the interceptor
form when credentials must be resolved per request (a token fetched from a vault, say) --
an interceptor runs on every call, a defaultHeaders value is captured once.
The negative cases, checked too
docs/output/03-restclient-no-credentials-401.txt and 04-restclient-wrong-password-401.txt
confirm what actually happens on the failure path: retrieve() throws
HttpClientErrorException.Unauthorized on a 401, exactly like RestTemplate did -- this is the
default retrieve() behaviour, not the exchange() behaviour covered in the next chapter.
Going deeper
RestClientJavadoc (rel="nofollow")- Prev: {noop} passwords
- Next: The starter split, and the exchange() trap