RestTemplate应用实践总结
【1】RestTemplate配置
RestTemplate
是 Spring 框架中用于发送 HTTP 请求的一个工具类。虽然 RestTemplate
本身已经提供了很多功能,但在某些情况下,你可能需要对其进行更详细的配置。你可以通过创建一个 RestTemplateConfig
配置类来实现这一点。以下是一些常见的配置选项:
1. 设置连接超时和读取超时
你可以设置连接超时和读取超时时间,以防止请求长时间没有响应。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000); // 连接超时时间,单位为毫秒
factory.setReadTimeout(5000); // 读取超时时间,单位为毫秒
return factory;
}
}
2. 添加拦截器
你可以添加拦截器来修改请求或响应,例如添加日志记录或修改请求头。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
// 修改请求头
request.getHeaders().add("X-Custom-Header", "CustomValue");
// 打印请求信息
System.out.println("Request URL: " + request.getURI());
System.out.println("Request Method: " + request.getMethod());
return execution.execute(request, body);
}
}));
return restTemplate;
}
}
3. 设置消息转换器
你可以添加或修改消息转换器,以便更好地处理请求和响应的序列化和反序列化。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new MappingJackson2HttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
restTemplate.setMessageConverters(messageConverters);
return restTemplate;
}
}
4. 设置错误处理器
你可以自定义错误处理器来处理请求过程中可能出现的异常。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
// 自定义错误处理逻辑
System.out.println("Error handling for status code: " + response.getStatusCode());
}
});
return restTemplate;
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(5000);
return factory;
}
}
5. 设置代理
如果你需要通过代理服务器发送请求,可以在配置中设置代理信息。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.net.InetSocketAddress;
import java.net.Proxy;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(5000);
factory.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080)));
return factory;
}
}
通过 RestTemplateConfig
配置类,你可以对 RestTemplate
进行多种配置,包括设置超时时间、添加拦截器、设置消息转换器、自定义错误处理器和设置代理等。这些配置可以帮助你更好地控制 HTTP 请求的行为,满足不同的应用场景需求。
【2】postForEntity发送JSON
发送一个 JSONObject
作为请求体使用 RestTemplate
是一个常见的需求。以下是一个完整的示例,展示了如何在客户端发送一个 JSONObject
并在服务器端接收和处理它。
客户端代码
- 添加依赖:确保你的项目中已经添加了Spring Web的依赖和JSON处理库(如Jackson)。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
- 使用
RestTemplate
发送 POST 请求:
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.json.JSONObject;
public class RestClient {
public static void main(String[] args) {
// 创建RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
// 创建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 创建请求体
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "John Doe");
jsonObject.put("age", 30);
jsonObject.put("email", "john.doe@example.com");
HttpEntity<String> requestEntity = new HttpEntity<>(jsonObject.toString(), headers);
// 目标URL
String url = "http://localhost:8080/api/receiveJson";
// 发送POST请求
ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
// 处理响应
if (response.getStatusCode().is2xxSuccessful()) {
System.out.println("Response Body: " + response.getBody());
} else {
System.out.println("Request failed with status code: " + response.getStatusCode());
}
}
}
服务器端代码
- 创建 Spring Boot 项目:确保你已经创建了一个 Spring Boot 项目,并添加了必要的依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
- 创建控制器:编写一个控制器来处理 POST 请求。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.json.JSONObject;
@RestController
public class JsonController {
@PostMapping("/api/receiveJson")
public ResponseEntity<String> receiveJson(@RequestBody String jsonBody) {
// 将接收到的字符串转换为JSONObject
JSONObject jsonObject = new JSONObject(jsonBody);
// 处理接收到的JSON对象
String name = jsonObject.getString("name");
int age = jsonObject.getInt("age");
String email = jsonObject.getString("email");
System.out.println("Received JSON:");
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Email: " + email);
// 返回响应
return ResponseEntity.ok("JSON received successfully");
}
}
解释
-
客户端代码:
- 创建
RestTemplate
实例。 - 设置请求头,指定内容类型为
application/json
。 - 创建一个
JSONObject
对象并添加一些键值对。 - 将
JSONObject
转换为字符串,并将其封装到HttpEntity
中。 - 使用
restTemplate.postForEntity
方法发送 POST 请求。 - 处理响应,检查状态码并打印响应体。
- 创建
-
服务器端代码:
- 创建一个控制器类
JsonController
。 - 使用
@PostMapping
注解标记一个方法来处理/api/receiveJson
路径上的 POST 请求。 - 使用
@RequestBody
注解将请求体中的字符串自动绑定到方法参数jsonBody
。 - 将接收到的字符串转换为
JSONObject
。 - 在方法体内,可以访问
JSONObject
中的属性并进行相应的业务逻辑处理。 - 返回一个
ResponseEntity
对象,包含响应状态码和响应体。
- 创建一个控制器类