Spring RestTemplate 使用一则
定义默认的 RestTemplate
/**
* 定义restTemplate的配置
*
* @author wenbronk
* @Date 下午4:33:35
*/
@Configuration
public class RestTemplateConfig {
@Bean
@ConditionalOnMissingBean({ RestOperations.class, RestTemplate.class })
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
// return new RestTemplate(factory);
RestTemplate restTemplate = new RestTemplate(factory);
// 使用 utf-8 编码集的 conver 替换默认的 conver(默认的 string conver 的编码集为"ISO-8859-1")
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> converter = iterator.next();
if (converter instanceof StringHttpMessageConverter) {
iterator.remove();
}
}
messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
return restTemplate;
}
@Bean
@ConditionalOnMissingBean({ClientHttpRequestFactory.class})
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(15000);// ms
factory.setConnectTimeout(15000);// ms
return factory;
}
}
Rest API 方法规范
| HTTP 方法 | 核心语义 | 幂等性 | 安全性 | 场景 |
|---|---|---|---|---|
| GET | 读取 / 查询资源 | 是 | 是 | 获取单个用户:GET /users/123;获取所有订单:GET /orders |
| POST | 创建新资源 | 否 | 否 | 创建订单:POST /orders;注册用户:POST /users |
| PUT | 全量更新资源(替换) | 是 | 否 | 更新用户全部信息:PUT /users/123 |
| PATCH | 部分更新资源 | 否 | 否 | 仅更新用户昵称:PATCH /users/123 |
| DELETE | 删除资源 | 是 | 否 | 删除订单:DELETE /orders/456 |
对象&数组以及请求头参数 (复杂的请求)
HttpEntity
HttpEntity<T>这个对象可以存放复杂的请求参数; 泛型是请求参数体; (GET没有请求体,也是可以的),
构造它需要 参数体, 请求头; 参数体可为null;
HttpEntity<T> request = new HttpEntity<T>(param, headers);
默认情况下, 请求体 会转为json 请求
数组参数问题
Long [] ids
StreamServer streamServer = getCurrentStreamServer();
String server_http_uri = streamServer.getServerHttpUri();
String url = server_http_uri+ MAPP_URI+"/query_by_ids?ids={ids}";
HttpHeaders headers = new HttpHeaders();
//headers.add("token", streamServer.getInsideVerify());
HttpEntity request = new HttpEntity(ids, headers);
return restTemplate.exchange(url, HttpMethod.GET, httpEntity, List.class,httpEntity.getBody());
//return restTemplate.exchange(url, HttpMethod.GET, httpEntity, List.class,ids);最后一个参数必须要,
而且必须通过httpEntity.getBody()获取,否则ids会丢掉后面下标, 什么鬼..?
在form-data 中
RestTemplate restTemplate = new RestTemplate();
String url = "http://ifreezer.zkmeiling.com/sample/source/add/insert.do";
HttpHeaders headers = new HttpHeaders();
headers.add("Cookie", "JSESSIONID=5B7130B20A1E78F2DB60E4D3B8CF8E1D");
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
@SuppressWarnings("rawtypes")
MultiValueMap map = new LinkedMultiValueMap();
map.add("sourceName","广东省畜禽种质地方猪采样-test220");
map.add("sourceTypeId",SOURCE_TYPE_ID);
for (int i = 0; i < sourceFieldValues.length; i++) {
map.add("sourceFieldValues[]", sourceFieldValues[i]);
}
HttpEntity requestBody = new HttpEntity(map, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestBody, String.class);
System.out.println(responseEntity.getBody() );
forEntity 因为泛型导致 LinkMap的问题
/**
封装一个方法 可接受泛型
**/
public static <T, A> T exchange(String url, HttpMethod method, ParameterizedTypeReference<T> responseBodyType, A requestBody, Object... params) {
RestTemplate restTemplate = new RestTemplate();
// 请求头
HttpHeaders headers = new HttpHeaders();
MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
// 请求体
headers.setContentType(mediaType);
// 发送请求
HttpEntity<A> entity = new HttpEntity<>(requestBody, headers);
ResponseEntity<T> resultEntity = restTemplate.exchange(url, method, entity, responseBodyType, params);
return resultEntity.getBody();
}
//使用
ParameterizedTypeReference<OriginalDataBean<Sl_collection_data>> typeRef = new ParameterizedTypeReference<OriginalDataBean<Sl_collection_data>>() {};
OriginalDataBean<Sl_collection_data> bean = exchange(url, HttpMethod.GET, typeRef, null, greaterId);自定义消息转换器
getRestTemplate().getMessageConverters().add(e)
忽略证书 https
import java.net.HttpURLConnection;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@Bean
public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}}, new java.security.SecureRandom());
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
//处理中文乱码
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}