Spring Framework 7.1.0-RC1 把 RestTemplate 标成了 @Deprecated(since = "7.1", forRemoval = true),加 -Xlint:deprecation 编译就会报警。同一次发布里,RequestMethod.QUERY 和 HttpMethod.QUERY 也进来了,控制器上挂 QUERY、请求体带 form 或 JSON,都能拿到 200;同一路径用 GET 或 POST 则是 405,响应头 Allow: QUERY。
版本从哪来
Maven Central 上 spring-core 7.1.0-RC1 的时间戳是 2026-10-22 07:46Z。Spring Framework 7.1 Release Notes 标的是 Oct 22,文首写明这是 7.1.0 的预览页,正式版排在 2026 年 11 月。GitHub 上还没有 v7.1.0-RC1 的 Release 页。
Boot 这边,4.2.0-RC1 的 BOM 已经把 spring-framework.version 写成 7.1.0-RC1。下面的例子用 Spring Boot 4.2.0-RC1,starter-web 会带进 spring-web 7.1.0-RC1 和 Tomcat 11.0.27,JDK 用的是本机的 27。对照用 Spring Boot 4.1.1,它绑的是 Framework 7.0.9。
RestTemplate 正式弃用
源码里类上的注解和说明是这样的:
/**
* ...
* @deprecated as of 7.1, in favor of {@link RestClient}. For removal in 8.0.
*/
@Deprecated(since = "7.1", forRemoval = true)
@SuppressWarnings("removal")
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
RestOperations、RestTemplateAdapter 也是同一组 @Deprecated(since = "7.1", forRemoval = true)。Release Notes 的 Deprecations 一节写的是:按此前 HTTP 客户端现状那篇博文的预告,RestTemplate 及相关类型自 7.1 起正式弃用,实际删除排在 Framework 8.0(尚未排期)。替代方向是 RestClient,这点和更早介绍 RestClient 时的说法一致,见Spring 6.1新特性:RestClient。
项目里放一个故意还在 new RestTemplate() 的组件:
package com.spring4all.sf71;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestTemplateProbe {
private final RestTemplate restTemplate = new RestTemplate();
public RestTemplate get() {
return restTemplate;
}
}
pom.xml 里给 maven-compiler-plugin 加上 -Xlint:deprecation 和 showDeprecation。mvn compile 打出来的警告是:
[WARNING] src/main/java/com/spring4all/sf71/RestTemplateProbe.java:[9,19] org.springframework.web.client.RestTemplate in org.springframework.web.client has been deprecated and marked for removal
[WARNING] src/main/java/com/spring4all/sf71/RestTemplateProbe.java:[11,12] org.springframework.web.client.RestTemplate in org.springframework.web.client has been deprecated and marked for removal
[WARNING] src/main/java/com/spring4all/sf71/RestTemplateProbe.java:[9,51] org.springframework.web.client.RestTemplate in org.springframework.web.client has been deprecated and marked for removal
三处分别对应字段类型、返回类型和 new RestTemplate()。程序还能编过、也能跑,只是编译器已经按“即将删除”处理。
同一段 new RestTemplate() 放到 Boot 4.1.1(Framework 7.0.9)上,同样开 -Xlint:deprecation,mvn compile 干净通过,没有关于 RestTemplate 的弃用警告。用 javap -v 看 7.0.9 的 RestTemplate.class,也没有 java.lang.Deprecated 注解。
HTTP QUERY 能带 body
RFC 10008 定义了 QUERY:幂等,又允许带请求体,位置夹在 GET 和 POST 之间。7.1 Release Notes 给了控制器示例,并写明暂时不加 @QueryMapping,等业界用得多了再加。RequestMethod 和 HttpMethod 都多了 QUERY 常量。
控制器照着 Notes 写:
@RestController
public class QueryController {
@RequestMapping(method = RequestMethod.QUERY, path = "/form",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<String> form(@RequestParam String name) {
return ResponseEntity.ok("hello: " + name);
}
@RequestMapping(method = RequestMethod.QUERY, path = "/body",
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> body(@RequestBody Project project) {
return ResponseEntity.ok("project: " + project.id());
}
public record Project(String name, String id) {
}
}
应用起来后:
01:18:54.633 INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/11.0.27]
01:18:54.921 INFO TomcatWebServer - Tomcat started on port 18091 (http) with context path '/'
对 18091 发几条请求:
$ curl -sS -w '\nHTTP %{http_code}\n' -X QUERY -d 'name=spring' http://127.0.0.1:18091/form
hello: spring
HTTP 200
$ curl -sS -w '\nHTTP %{http_code}\n' -X QUERY -H 'Content-Type: application/json' \
-d '{"name":"Spring Framework","id":"spring-framework"}' http://127.0.0.1:18091/body
project: spring-framework
HTTP 200
$ curl -sS -D - -o - -X GET http://127.0.0.1:18091/body
HTTP/1.1 405
Allow: QUERY
{"timestamp":"2026-10-22T17:18:55.354Z","status":405,"error":"Method Not Allowed","path":"/body"}
$ curl -sS -w '\nHTTP %{http_code}\n' -X POST -H 'Content-Type: application/json' \
-d '{"name":"Spring Framework","id":"spring-framework"}' http://127.0.0.1:18091/body
{"timestamp":"2026-10-22T17:18:55.378Z","status":405,"error":"Method Not Allowed","path":"/body"}
HTTP 405
QUERY 带 form、带 JSON 都是 200。GET 和 POST 打同一路径是 405,Allow 只列了 QUERY,说明映射只认这一种方法。
客户端侧,RestClient 用 HttpMethod.QUERY 也能打通:
RestClient c = RestClient.create();
String form = c.method(HttpMethod.QUERY).uri("http://127.0.0.1:18091/form")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body("name=spring")
.retrieve().body(String.class);
String body = c.method(HttpMethod.QUERY).uri("http://127.0.0.1:18091/body")
.contentType(MediaType.APPLICATION_JSON)
.body("{\"name\":\"Spring Framework\",\"id\":\"spring-framework\"}")
.retrieve().body(String.class);
RestClient form -> hello: spring
RestClient body -> project: spring-framework
对照放在 Framework 7.0.9 上。同一段 RequestMethod.QUERY 会直接编不过:
[ERROR] .../Q.java:[4,27] cannot find symbol
symbol: variable QUERY
location: class org.springframework.web.bind.annotation.RequestMethod
javap 看 7.0.9 的 RequestMethod,枚举里只有 GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE,没有 QUERY。
这次测过的组合:Spring Boot 4.2.0-RC1 + spring-web 7.1.0-RC1 + Tomcat 11.0.27 + JDK 27;对照是 Spring Boot 4.1.1 + spring-web 7.0.9。
一起交流
分享你的思考,让讨论更进一步。