RestTemplate是Spring提供的一个模板类,用于发送Http网络请求。利用它制作一个方向代理,可以使用RestTemplate的exchange方法来实现。具体分为以下几个步骤:
一、创建RestTemplate实例
创建RestTemplate实例直接new就行了,重要的是RestTemplate的配置。考虑到Http请求可能获取多种资源,所以在此使用byte[]来进行传输。使用byte[]进行传输数据,就要配置转换器,让程序可以将二进制数据正确的转为我们需要的数据类型。同时,我们也可以通过SimpleClientHttpRequestFactory来设置请求的超时时间。初始化RestTemplate的代码如下:
SimpleClientHttpRequestFactory srf = new SimpleClientHttpRequestFactory(); srf.setConnectTimeout(5000); List<HttpMessageConverter<?>> converters = new ArrayList<>(); // 二进制数据转换器 converters.add(new ByteArrayHttpMessageConverter()); converters.add(new BufferedImageHttpMessageConverter()); converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); converters.add(new ResourceHttpMessageConverter()); converters.add(new AllEncompassingFormHttpMessageConverter()); this.restTemplate = restTemplateBuilder.build(); this.restTemplate.setRequestFactory(srf); this.restTemplate.setMessageConverters(converters);
二、构造请求头,请求体和参数
构造请求参数可以通过request.getParameterMap来获取,并且通过构造字符串拼接到uri中的方法来实现。
Map<String, String[]> parameterMap = request.getParameterMap();
StringBuilder queryString = new StringBuilder();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
for (String value : entry.getValue()) {
if (!queryString.isEmpty()) {
queryString.append("&");
}
queryString.append(entry.getKey()).append("=").append(value);
}
}
构造请求头可以新建HttpHeaders对象,通过request.getHeaderNames()获取到请求头名称,再使用循环获取到所有请求头内容并且添加。请求头添加时需要跳过host,conten-length,connection,transfer-encoding:
HttpHeaders headers = new HttpHeaders();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
if (!shouldSkipHeader(headerName)) {
Enumeration<String> headerValues = request.getHeaders(headerName);
while (headerValues.hasMoreElements()) {
headers.add(headerName, headerValues.nextElement());
}
}
}
构造请求体时需要新建HttpEntity对象,可以在控制器层面获取到请求体的String,最后传入其中构造请求体。
HttpEntity<Object> requestEntity = null;
if (body != null) {
try {
requestEntity = new HttpEntity<>(body, headers);
} catch (Exception e) {
logger.error("构造请求体异常", e);
}
} else {
requestEntity = new HttpEntity<>(headers);
}
最后通过RestTemplate发送请求即可:
ResponseEntity<byte[]> exchange = restTemplate.exchange(
targetUrl,
HttpMethod.valueOf(request.getMethod()),
requestEntity,
byte[].class
);