Spring 框架中 RestTemplate 的使用方法

当然可以!下面我将为你详细讲解 Spring 框架中 ​​RestTemplate 的使用方法​​,包括它的基本概念、核心功能、常见用法、配置方式、以及在实际项目中的最佳实践,并附带代码示例,帮助你全面掌握。


一、什么是 RestTemplate?

​RestTemplate​​ 是 Spring Framework 提供的一个用于访问 RESTful 服务的同步客户端工具类,它是对 HTTP 客户端的一层封装,简化了与 REST 服务交互的过程,比如:

  • 发送 GET、POST、PUT、DELETE 请求

  • 设置请求头、请求参数、请求体

  • 处理响应数据(JSON / XML 等)

  • 错误处理

它适用于 ​​服务与服务之间(如微服务架构)的 HTTP 通信​ ​,在 Spring Boot 2.x 之前非常常用。但从 ​​Spring 5 开始,官方推荐使用 WebClient(响应式非阻塞)作为 RestTemplate 的替代方案​ ​,不过 ​​RestTemplate 仍然被广泛使用,特别是在传统 Spring MVC 项目中​​。


二、RestTemplate 的核心特点

特性 说明
同步阻塞 RestTemplate 是 ​​同步、阻塞式​​ 的 HTTP 客户端,调用线程会等待响应返回
支持多种 HTTP 方法 GET、POST、PUT、DELETE、PATCH 等
支持请求/响应的序列化与反序列化 比如自动将 Java 对象转为 JSON 发送,或者将返回的 JSON 转为 Java 对象
灵活的请求构造 可以设置 URL、请求头、请求参数、请求体等
支持多种响应处理方式 比如直接获取字符串、字节数组、对象等
易于使用 相比原生 HttpURLConnection 或 HttpClient,使用更简单

三、RestTemplate 的基本使用步骤

步骤 1:引入依赖(Spring Boot 项目中通常已包含)

如果你使用的是 Spring Boot,一般无需额外引入,因为 spring-web已经包含 RestTemplate(在 spring-boot-starter-web 中)。

但如果你想自定义或明确引入,可以检查你的 pom.xml是否有以下依赖:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

⚠️ 注意:从 Spring Boot 2.7 开始,RestTemplate 不再自动配置,你需要手动创建 Bean;Spring Boot 3.x 推荐使用 WebClient。

步骤 2:创建 RestTemplate 实例

方式一:直接 new(不推荐,无连接池等优化)

java 复制代码
RestTemplate restTemplate = new RestTemplate();

方式二:通过 Spring Bean 方式注入(推荐)

你可以在配置类中定义一个 RestTemplate Bean:

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

然后就可以通过 ​​@Autowired​​ 注入使用:

java 复制代码
@Autowired
private RestTemplate restTemplate;

步骤 3:使用 RestTemplate 发送请求

下面介绍最常用的几种 HTTP 方法的使用。


1. GET 请求

① 获取字符串响应
java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/1";
String result = restTemplate.getForObject(url, String.class);
System.out.println(result);
② 获取对象(自动反序列化 JSON 到 Java 对象)

假设有一个类:

java 复制代码
public class Post {
    private Integer userId;
    private Integer id;
    private String title;
    private String body;

    // getters / setters ...
}

调用:

java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/1";
Post post = restTemplate.getForObject(url, Post.class);
System.out.println(post.getTitle());
③ 带路径参数的 GET 请求
java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
Map<String, Object> params = new HashMap<>();
params.put("id", 1);

Post post = restTemplate.getForObject(url, Post.class, params);
// 或者
Post post = restTemplate.getForObject(url, Post.class, 1); // 直接传参
④ 带请求头的 GET 请求

需要使用 HttpHeadersHttpEntityRestTemplate.exchange()

java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/1";

HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer your_token_here");
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

HttpEntity<String> entity = new HttpEntity<>(headers);

ResponseEntity<Post> response = restTemplate.exchange(
    url,
    HttpMethod.GET,
    entity,
    Post.class
);

Post post = response.getBody();
System.out.println(post.getTitle());

2. POST 请求

① 发送对象并接收对象(常用)
java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts";

Post newPost = new Post();
newPost.setTitle("Hello");
newPost.setBody("This is a test post");
// userId 可以根据 API 要求设置

Post createdPost = restTemplate.postForObject(url, newPost, Post.class);
System.out.println(createdPost.getId());
② 带请求头的 POST 请求
java 复制代码
String url = "https://example.com/api/posts";

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer xxxx");

Post newPost = new Post();
newPost.setTitle("Hello");
newPost.setBody("Content");

HttpEntity<Post> requestEntity = new HttpEntity<>(newPost, headers);

ResponseEntity<Post> response = restTemplate.exchange(
    url,
    HttpMethod.POST,
    requestEntity,
    Post.class
);

Post result = response.getBody();

3. PUT 请求(更新资源)

java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/1";

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

Post updatedPost = new Post();
updatedPost.setId(1);
updatedPost.setTitle("Updated Title");
updatedPost.setBody("Updated Body");

HttpEntity<Post> requestEntity = new HttpEntity<>(updatedPost, headers);

restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Void.class);
// 如果你不需要返回值,可以用 Void.class

4. DELETE 请求

java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/1";

restTemplate.delete(url);

如果带路径参数:

java 复制代码
String url = "https://jsonplaceholder.typicode.com/posts/{id}";
Map<String, Object> params = Collections.singletonMap("id", 1);
restTemplate.delete(url, params);

四、RestTemplate 的高级用法

1. 使用 exchange() 方法(最灵活)

exchange()是 RestTemplate 最强大的方法,支持所有 HTTP 方法,可以自定义请求头、请求体,且能获取完整的响应信息(状态码、响应头、响应体)。

java 复制代码
ResponseEntity<Post> response = restTemplate.exchange(
    url,                    // 请求URL
    HttpMethod.GET,         // 请求方法
    entity,                 // 请求实体(可含headers、body)
    Post.class              // 响应体类型
);

HttpStatus statusCode = response.getStatusCode();      // 如 HttpStatus.OK
HttpHeaders responseHeaders = response.getHeaders();   // 响应头
Post responseBody = response.getBody();                // 响应体

2. 使用 ResponseEntity 接收更丰富的响应信息

java 复制代码
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
System.out.println(response.getStatusCode()); // 如 200 OK
System.out.println(response.getBody());

3. 错误处理

默认情况下,如果服务端返回 4xx 或 5xx,RestTemplate 会抛出异常,比如:

  • HttpClientErrorException(4xx)

  • HttpServerErrorException(5xx)

你可以捕获这些异常做处理:

java 复制代码
try {
    Post post = restTemplate.getForObject(url, Post.class);
} catch (HttpClientErrorException e) {
    System.err.println("客户端错误: " + e.getStatusCode() + ", " + e.getResponseBodyAsString());
} catch (HttpServerErrorException e) {
    System.err.println("服务端错误: " + e.getStatusCode());
} catch (RestClientException e) {
    System.err.println("Rest请求异常: " + e.getMessage());
}

五、RestTemplate 的配置(可选)

你可以通过自定义 RestTemplate的构建过程,配置例如:

  • 消息转换器(如支持 JSON、XML)

  • 拦截器(添加统一 Header、日志等)

  • 超时设置(需要使用 HttpComponentsClientHttpRequestFactory 或 SimpleClientHttpRequestFactory)

示例:配置超时和拦截器

java 复制代码
@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();

    // 设置请求工厂(可配置超时)
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setConnectTimeout(5000); // 连接超时时间 ms
    factory.setReadTimeout(5000);    // 读取超时时间 ms
    restTemplate.setRequestFactory(factory);

    // 添加拦截器(比如统一加 Token)
    restTemplate.getInterceptors().add((request, body, execution) -> {
        request.getHeaders().add("Authorization", "Bearer xxx");
        return execution.execute(request, body);
    });

    return restTemplate;
}

⚠️ 如果你要更高级的 HTTP 客户端功能(如连接池、更灵活的超时控制),可以考虑使用 ​​Apache HttpClient​ ​ 或 ​​OkHttp​ ​ 作为底层实现,然后传入对应的 ClientHttpRequestFactory

六、RestTemplate vs WebClient

对比项 RestTemplate WebClient
类型 同步阻塞 异步非阻塞(响应式)
适用场景 传统 MVC、简单调用 高并发、响应式编程、WebFlux
是否推荐新项目使用 ❌ 不推荐(尤其 Spring 6 / Boot 3) ✅ 推荐
学习曲线 简单 较复杂(需了解 Reactor)
Spring Boot 3 支持 已移除自动配置 ✅ 官方主推

如果你使用的是 ​​Spring Boot 3+ 或 Spring 6+,官方已移除 RestTemplate 自动配置,推荐使用 WebClient​​。


七、总结:RestTemplate 使用要点

项目 说明
作用 用于同步调用 RESTful API,简化 HTTP 客户端操作
推荐使用场景 传统 Spring MVC 项目,简单 HTTP 调用
创建方式 推荐通过 @Bean 方式注入
常用方法 getForObject、postForObject、exchange、delete 等
请求构造 支持 URL、参数、Header、Body
响应处理 支持 String、JSON 对象、ResponseEntity 等
错误处理 捕获 HttpClientErrorException / HttpServerErrorException
配置优化 可配置超时、拦截器、消息转换器等
替代方案 WebClient(响应式,Spring 5+ 推荐)

八、附:完整示例代码(GET + POST)

java 复制代码
@Service
public class ApiService {

    @Autowired
    private RestTemplate restTemplate;

    // GET 示例
    public Post getPostById(int id) {
        String url = "https://jsonplaceholder.typicode.com/posts/{id}";
        return restTemplate.getForObject(url, Post.class, id);
    }

    // POST 示例
    public Post createPost(Post newPost) {
        String url = "https://jsonplaceholder.typicode.com/posts";
        return restTemplate.postForObject(url, newPost, Post.class);
    }
}
相关推荐
小趴菜82272 小时前
安卓人机验证View
android·java·前端
信安成长日记2 小时前
golang 写路由的时候要注意
开发语言·后端·golang
Lojarro2 小时前
GO学习2:基本数据类型 与 转换
后端·学习·golang
观望过往3 小时前
【Java SE 运算符】全面解析与实践指南
java
没有bug.的程序员3 小时前
分布式架构初识:为什么需要分布式
java·分布式·架构·php
闲人编程3 小时前
2025年,如何选择Python Web框架:Django, Flask还是FastAPI?
前端·后端·python·django·flask·fastapi·web
郑州光合科技余经理3 小时前
微服务架构:基于Spring Cloud ,构建同城生活服务平台
java·spring cloud·微服务·小程序·架构·uni-app
ajassi20003 小时前
开源 java android app 开发(十七)封库--混淆源码
android·java·开源
海梨花3 小时前
关于Java的几个小问题
java·面试