blog/2362105
经常需要发送一个GET/POST请求到其他系统(REST API),通过JDK自带的HttpURLConnection、Apache HttpClient、Netty 4、OkHTTP 2/3都可以实现。
HttpClient的使用:blog/1550436
Spring的RestTemplate封装了这些库的实现,使用起来更简洁。
RestTemplate包含以下几个部分:
-
HttpMessageConverter 对象转换器
-
ClientHttpRequestFactory 默认是JDK的HttpURLConnection
-
ResponseErrorHandler 异常处理
-
ClientHttpRequestInterceptor 请求拦截器
-
@Service
-
public class AccountService {
-
-
@Autowired
-
private RestTemplate restTemplate;
-
-
-
-
}
(1)发送GET请求(getForObject()、getForEntity()、exchange())
-
-
User user1 = this.restTemplate.getForObject(uri, User.class);
-
-
-
ResponseEntity responseEntity1 = this.restTemplate.getForEntity(uri, User.class);
-
HttpStatus statusCode = responseEntity1.getStatusCode();
-
HttpHeaders header = responseEntity1.getHeaders();
-
User user2 = responseEntity1.getBody();
-
-
-
RequestEntity requestEntity = RequestEntity.get(new URI(uri)).build();
-
ResponseEntity responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);
-
User user3 = responseEntity2.getBody();
(2)发送POST请求(postForObject()、postForEntity()、exchange())
-
-
User user1 = this.restTemplate.postForObject(uri, user, User.class);
-
-
-
ResponseEntity responseEntity1 = this.restTemplate.postForEntity(uri, user, User.class);
-
-
-
RequestEntity requestEntity = RequestEntity.post(new URI(uri)).body(user);
-
ResponseEntity responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);
(3)设置HTTP Header信息
-
-
RequestEntity requestEntity = RequestEntity
-
.post(new URI(uri))
-
.contentType(MediaType.APPLICATION_JSON)
-
.body(user);
-
-
-
RequestEntity requestEntity = RequestEntity
-
.post(new URI(uri))
-
.accept(MediaType.APPLICATION_JSON)
-
.body(user);
-
-
-
RequestEntity requestEntity = RequestEntity
-
.post(new URI(uri))
-
.header("Authorization", "Basic " + base64Credentials)
-
.body(user);
(4)异常处理
捕获HttpServerErrorException
-
int retryCount = 0;
-
while (true) {
-
try {
-
responseEntity = restTemplate.exchange(requestEntity, String.class);
-
break;
-
} catch (HttpServerErrorException e) {
-
if (retryCount == 3) {
-
throw e;
-
}
-
retryCount++;
-
}
-
}
自定义异常处理
-
public class CustomErrorHandler extends DefaultResponseErrorHandler {
-
-
@Override
-
public void handleError(ClientHttpResponse response) throws IOException {
-
-
}
-
-
}
-
@Configuration
-
public class RestClientConfig {
-
-
@Bean
-
public RestTemplate restTemplate() {
-
RestTemplate restTemplate = new RestTemplate();
-
restTemplate.setErrorHandler(new CustomErrorHandler());
-
return restTemplate;
-
}
-
-
}
(5)设置超时时间
-
@Configuration
-
public class RestClientConfig {
-
-
@Bean
-
public RestTemplate restTemplate() {
-
return new RestTemplate(clientHttpRequestFactory());
-
}
-
-
private ClientHttpRequestFactory clientHttpRequestFactory() {
-
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
-
factory.setReadTimeout(2000);
-
factory.setConnectTimeout(2000);
-
return factory;
-
}
-
}
(6)设置连接池
-
@Configuration
-
public class RestClientConfig {
-
-
@Bean
-
public ClientHttpRequestFactory httpRequestFactory() {
-
return new HttpComponentsClientHttpRequestFactory(httpClient());
-
}
-
-
@Bean
-
public RestTemplate restTemplate() {
-
return new RestTemplate(httpRequestFactory());
-
}
-
-
@Bean
-
public HttpClient httpClient() {
-
Registry registry = RegistryBuilder. create()
-
.register("http", PlainConnectionSocketFactory.getSocketFactory())
-
.register("https", SSLConnectionSocketFactory.getSocketFactory())
-
.build();
-
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
-
connectionManager.setMaxTotal(5);
-
connectionManager.setDefaultMaxPerRoute(5);
-
-
RequestConfig requestConfig = RequestConfig.custom()
-
.setSocketTimeout(8000)
-
.setConnectTimeout(8000)
-
.setConnectionRequestTimeout(8000)
-
.build();
-
-
return HttpClientBuilder.create()
-
.setDefaultRequestConfig(requestConfig)
-
.setConnectionManager(connectionManager)
-
.build();
-
}
-
-
}
(7)发送文件
-
MultiValueMap multiPartBody = new LinkedMultiValueMap<>();
-
multiPartBody.add("file", new ClassPathResource("/tmp/user.txt"));
-
RequestEntity> requestEntity = RequestEntity
-
.post(uri)
-
.contentType(MediaType.MULTIPART_FORM_DATA)
-
.body(multiPartBody);
(8)下载文件
-
-
RequestEntity requestEntity = RequestEntity.get(uri).build();
-
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(requestEntity, byte[].class);
-
byte[] downloadContent = responseEntity.getBody();
-
-
-
ResponseExtractor> responseExtractor = new ResponseExtractor>() {
-
@Override
-
public ResponseEntity extractData(ClientHttpResponse response) throws IOException {
-
File rcvFile = File.createTempFile("rcvFile", "zip");
-
FileCopyUtils.copy(response.getBody(), new FileOutputStream(rcvFile));
-
return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders()).body(rcvFile);
-
}
-
};
-
File getFile = this.restTemplate.execute(targetUri, HttpMethod.GET, null, responseExtractor);
(9)Spring Boot的RestTemplateBuilder
全局设置
-
@Component
-
public class CustomRestTemplateCustomizer implements RestTemplateCustomizer {
-
@Override
-
public void customize(RestTemplate restTemplate) {
-
new RestTemplateBuilder()
-
.detectRequestFactory(false)
-
.basicAuthorization("username", "password")
-
.uriTemplateHandler(new OkHttp3ClientHttpRequestFactory())
-
.errorHandler(new CustomResponseErrorHandler())
-
.configure(restTemplate);
-
}
-
}
单独设置
-
@Service
-
public class MyRestClientService {
-
-
private RestTemplate restTemplate;
-
-
public MyRestClientService(RestTemplateBuilder restTemplateBuilder) {
-
this.restTemplate = restTemplateBuilder
-
.basicAuthorization("username", "password")
-
.setConnectTimeout(3000)
-
.setReadTimeout(5000)
-
.rootUri("")
-
.errorHandler(new CustomResponseErrorHandler())
-
.additionalMessageConverters(new CustomHttpMessageConverter())
-
.uriTemplateHandler(new OkHttp3ClientHttpRequestFactory())
-
.build();
-
}
-
-
public String site() {
-
return this.restTemplate.getForObject("", String.class);
-
}
-
-
}
参考:
阅读(906) | 评论(0) | 转发(0) |