RestTemplate #
一、RestTemplate概述 #
1.1 什么是RestTemplate #
RestTemplate是Spring提供的用于访问REST服务的客户端模板工具类,提供了多种便捷访问远程HTTP服务的方法。
text
┌─────────────────────────────────────────────────────────────┐
│ RestTemplate架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ RestTemplate │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ GET │ │ POST │ │ PUT │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ DELETE │ │ HEAD │ │ OPTIONS │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ ClientHttpRequestFactory │ │ │
│ │ │ SimpleClientHttpRequestFactory (默认) │ │ │
│ │ │ HttpComponentsClientHttpRequestFactory │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 RestTemplate方法分类 #
| 方法组 | 说明 | 方法数量 |
|---|---|---|
| getForObject | GET请求,返回对象 | 2 |
| getForEntity | GET请求,返回ResponseEntity | 2 |
| postForObject | POST请求,返回对象 | 2 |
| postForEntity | POST请求,返回ResponseEntity | 2 |
| postForLocation | POST请求,返回Location | 1 |
| put | PUT请求 | 1 |
| delete | DELETE请求 | 1 |
| exchange | 通用请求方法 | 5 |
| execute | 最底层的请求方法 | 2 |
二、基本配置 #
2.1 创建RestTemplate #
java
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.2 配置超时时间 #
java
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(10000);
return new RestTemplate(factory);
}
2.3 使用HttpClient #
xml
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
java
@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(10000);
return new RestTemplate(factory);
}
2.4 负载均衡配置 #
java
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
三、GET请求 #
3.1 getForObject #
java
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public User getUserById(Long id) {
String url = "http://user-service/users/{id}";
return restTemplate.getForObject(url, User.class, id);
}
public User getUserById2(Long id) {
String url = "http://user-service/users/{id}";
Map<String, Object> params = new HashMap<>();
params.put("id", id);
return restTemplate.getForObject(url, User.class, params);
}
public List<User> getUsers(List<Long> ids) {
String url = "http://user-service/users?ids={ids}";
String idsStr = ids.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
return restTemplate.getForObject(url, List.class, idsStr);
}
}
3.2 getForEntity #
java
public User getUserWithHeaders(Long id) {
String url = "http://user-service/users/{id}";
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, id);
if (response.getStatusCode() == HttpStatus.OK) {
HttpHeaders headers = response.getHeaders();
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
System.out.println("Content-Type: " + contentType);
return response.getBody();
}
return null;
}
public ResponseEntity<User> getUserResponse(Long id) {
String url = "http://user-service/users/{id}";
return restTemplate.getForEntity(url, User.class, id);
}
四、POST请求 #
4.1 postForObject #
java
public User createUser(User user) {
String url = "http://user-service/users";
return restTemplate.postForObject(url, user, User.class);
}
public User createUserWithHeaders(User user) {
String url = "http://user-service/users";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer token");
HttpEntity<User> request = new HttpEntity<>(user, headers);
return restTemplate.postForObject(url, request, User.class);
}
4.2 postForEntity #
java
public ResponseEntity<User> createUserResponse(User user) {
String url = "http://user-service/users";
return restTemplate.postForEntity(url, user, User.class);
}
4.3 postForLocation #
java
public URI createUserAndGetLocation(User user) {
String url = "http://user-service/users";
return restTemplate.postForLocation(url, user);
}
4.4 表单提交 #
java
public User login(String username, String password) {
String url = "http://user-service/login";
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("username", username);
params.add("password", password);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request =
new HttpEntity<>(params, headers);
return restTemplate.postForObject(url, request, User.class);
}
五、PUT请求 #
5.1 put方法 #
java
public void updateUser(Long id, User user) {
String url = "http://user-service/users/{id}";
restTemplate.put(url, user, id);
}
public void updateUser2(Long id, User user) {
String url = "http://user-service/users/{id}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<User> request = new HttpEntity<>(user, headers);
restTemplate.put(url, request, id);
}
5.2 使用exchange #
java
public ResponseEntity<User> updateUserWithResponse(Long id, User user) {
String url = "http://user-service/users/{id}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<User> request = new HttpEntity<>(user, headers);
return restTemplate.exchange(
url,
HttpMethod.PUT,
request,
User.class,
id
);
}
六、DELETE请求 #
6.1 delete方法 #
java
public void deleteUser(Long id) {
String url = "http://user-service/users/{id}";
restTemplate.delete(url, id);
}
6.2 使用exchange #
java
public ResponseEntity<Void> deleteUserWithResponse(Long id) {
String url = "http://user-service/users/{id}";
return restTemplate.exchange(
url,
HttpMethod.DELETE,
null,
Void.class,
id
);
}
七、通用方法exchange #
7.1 基本使用 #
java
public <T> ResponseEntity<T> exchange(
String url,
HttpMethod method,
HttpEntity<?> requestEntity,
Class<T> responseType,
Object... uriVariables) {
return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
}
7.2 带请求头 #
java
public User getUserWithAuth(Long id, String token) {
String url = "http://user-service/users/{id}";
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Void> request = new HttpEntity<>(headers);
ResponseEntity<User> response = restTemplate.exchange(
url,
HttpMethod.GET,
request,
User.class,
id
);
return response.getBody();
}
7.3 泛型返回 #
java
public <T> ResponseEntity<List<T>> exchangeList(
String url,
HttpMethod method,
ParameterizedTypeReference<List<T>> responseType) {
return restTemplate.exchange(url, method, null, responseType);
}
public List<User> getUsers() {
String url = "http://user-service/users";
ResponseEntity<List<User>> response = restTemplate.exchange(
url,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<User>>() {}
);
return response.getBody();
}
八、文件操作 #
8.1 文件上传 #
java
public String uploadFile(MultipartFile file) {
String url = "http://file-service/upload";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", file.getResource());
HttpEntity<MultiValueMap<String, Object>> request =
new HttpEntity<>(body, headers);
return restTemplate.postForObject(url, request, String.class);
}
8.2 文件下载 #
java
public byte[] downloadFile(String fileId) {
String url = "http://file-service/download/{id}";
ResponseEntity<byte[]> response = restTemplate.getForEntity(
url,
byte[].class,
fileId
);
return response.getBody();
}
public void downloadAndSave(String fileId, String localPath) throws IOException {
String url = "http://file-service/download/{id}";
ResponseEntity<Resource> response = restTemplate.getForEntity(
url,
Resource.class,
fileId
);
if (response.getStatusCode() == HttpStatus.OK) {
Files.copy(
response.getBody().getInputStream(),
Paths.get(localPath),
StandardCopyOption.REPLACE_EXISTING
);
}
}
九、拦截器 #
9.1 自定义拦截器 #
java
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
private static final Logger log = LoggerFactory.getLogger(LoggingInterceptor.class);
@Override
public ClientHttpResponse intercept(
HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution) throws IOException {
logRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
logResponse(response);
return response;
}
private void logRequest(HttpRequest request, byte[] body) {
log.info("URI: {}", request.getURI());
log.info("Method: {}", request.getMethod());
log.info("Headers: {}", request.getHeaders());
log.info("Body: {}", new String(body, StandardCharsets.UTF_8));
}
private void logResponse(ClientHttpResponse response) throws IOException {
log.info("Status: {}", response.getStatusCode());
log.info("Headers: {}", response.getHeaders());
}
}
9.2 注册拦截器 #
java
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(new LoggingInterceptor()));
return restTemplate;
}
9.3 认证拦截器 #
java
public class AuthInterceptor implements ClientHttpRequestInterceptor {
private final String token;
public AuthInterceptor(String token) {
this.token = token;
}
@Override
public ClientHttpResponse intercept(
HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().setBearerAuth(token);
return execution.execute(request, body);
}
}
十、异常处理 #
10.1 默认异常处理 #
java
try {
User user = restTemplate.getForObject(url, User.class, id);
} catch (HttpClientErrorException e) {
if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
System.out.println("User not found");
} else if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
System.out.println("Unauthorized");
}
} catch (HttpServerErrorException e) {
System.out.println("Server error: " + e.getStatusCode());
} catch (ResourceAccessException e) {
System.out.println("Connection timeout or refused");
}
10.2 自定义错误处理器 #
java
public class CustomErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return response.getStatusCode().isError();
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
if (response.getStatusCode().is4xxClientError()) {
throw new ClientException("Client error: " + response.getStatusCode());
} else if (response.getStatusCode().is5xxServerError()) {
throw new ServerException("Server error: " + response.getStatusCode());
}
}
}
java
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new CustomErrorHandler());
return restTemplate;
}
十一、最佳实践 #
11.1 封装工具类 #
java
@Component
public class RestTemplateUtil {
@Autowired
@LoadBalanced
private RestTemplate restTemplate;
public <T> T get(String url, Class<T> responseType, Object... uriVariables) {
return restTemplate.getForObject(url, responseType, uriVariables);
}
public <T> T get(String url, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.getForObject(url, responseType, uriVariables);
}
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
public <T> T post(String url, Object request, Class<T> responseType) {
return restTemplate.postForObject(url, request, responseType);
}
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType) {
return restTemplate.postForEntity(url, request, responseType);
}
public void put(String url, Object request, Object... uriVariables) {
restTemplate.put(url, request, uriVariables);
}
public void delete(String url, Object... uriVariables) {
restTemplate.delete(url, uriVariables);
}
public <T> ResponseEntity<T> exchange(
String url,
HttpMethod method,
Object request,
Class<T> responseType,
Object... uriVariables) {
HttpEntity<?> entity = request != null ? new HttpEntity<>(request) : null;
return restTemplate.exchange(url, method, entity, responseType, uriVariables);
}
}
11.2 连接池配置 #
java
@Bean
public RestTemplate restTemplate() {
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(200);
connectionManager.setDefaultMaxPerRoute(50);
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
factory.setConnectTimeout(5000);
factory.setReadTimeout(10000);
return new RestTemplate(factory);
}
十二、总结 #
12.1 核心要点 #
| 要点 | 说明 |
|---|---|
| getForObject | GET请求返回对象 |
| postForObject | POST请求返回对象 |
| exchange | 通用请求方法 |
| 拦截器 | 请求/响应拦截处理 |
| 异常处理 | 自定义错误处理 |
12.2 下一步 #
现在你已经掌握了RestTemplate的使用,接下来让我们学习 OpenFeign,体验声明式服务调用的便捷!
最后更新:2026-03-28