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。

— 感谢阅读 —
广告

一起交流

分享你的思考,让讨论更进一步。