Affects: spring 6.1.0-RC2 with spring boot 3.2.0-RC2 and JDK21

Description I've attached a sample Spring Boot application with a single endpoint that accepts PATCH requests. When the endpoint is invoked with a PATCH request from a WebTestClient it is allowed, but when it is invoked with a PATCH request from a RestClient, it fails with the following exception

org.springframework.web.client.ResourceAccessException: I/O error on PATCH request for "http://localhost:61668/api/endpoint": Invalid HTTP method: PATCH
    at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.createResourceAccessException(DefaultRestClient.java:489)
    at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:414)
    at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:380)

In SecurityConfiguration.java I've added PATCH to the allowed methods, so I guess RestClient is ignoring this configuration.

Steps to Reproduce demo.zip

The application contains 2 integration tests, one of which invokes the endpoint with a RestClient and the other uses WebTestClient. The latter test passes, but the former fails.

Comment From: poutsma

Spring Boot's RestClient support uses the SimpleClientHttpRequestFactory by default, which is based on the dated java.net.HttpURLConnection, and does not have support for PATCH.

Switching to the more modern Java HttpClient fixes it:

@PostConstruct
private void buildRestClient() {
    restClient = restClientBuilder.baseUrl("http://localhost:" + port)
            .requestFactory(new JdkClientHttpRequestFactory())
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .build();
}

Comment From: andrei-ivanov

Wouldn't it make sense to change the default client?

Comment From: donalmurtagh

Spring Boot's RestClient support uses the SimpleClientHttpRequestFactory by default, which is based on the dated java.net.HttpURLConnection, and does not have support for PATCH.

Switching to the more modern Java HttpClient fixes it:

@poutsma Thanks very much for your reply, I've confirmed that switching the request factory resolves the problem.

Given that RestClient is brand new, shouldn't it use JdkClientHttpRequestFactory by default i.e. there doesn't appear to be a backwards compatibility argument for using HttpURLConnection

Comment From: poutsma

Wouldn't it make sense to change the default client?

FWIW, RestClient's default request factory—without Boot—is the JdkClientHttpRequestFactory.

It is because Boot uses the same ClientHttpRequestFactorySettings between RestTemplate and RestClient that the SimpleClientHttpRequestFactory is used, doing otherwise would break backward compatibility for RestTemplate users because the factories have different behavior with regards to redirects.

There are plans to improve the situation, see https://github.com/spring-projects/spring-boot/issues/36266