insight spring 提供的rest操作,以及jdk自带URL http访问的实现。
spring RestTemplate 执行流程
/**
* http请求,根据指定的方法访问URI
* @param requestCallback write请求对象至 request。借助HttpMessageConverter 组件,转换对象,如json的序列化
* 类比前端ajax请求,JSON.stringify(request)
* @param responseExtractor 从response 解析返回值。responseExtractor 封装HttpMessageConverter 组件,用以转换response,比如json的反序列化。
* new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);
*/
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor) {
try {
// 1.构造request (open a connection, set timeout...)
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
// 2.序列化request,write bytes to request body
requestCallback.doWithRequest(request);
}
// 3.check、connect,构造response
response = request.execute();
// 4.handle error
handleResponse(url, method, response);
if (responseExtractor != null) {
// 5.解析、反序列化response
return responseExtractor.extractData(response);
}
} catch (IOException ex) {
// ......
} finally {
// 6.切记close InputStream
if (response != null) {
response.close();
}
}
}
JDK 自带URL实现的http访问
对应上述的执行流程,JDK URL的具体操作
/*
* createRequest 实现
*/
// 根据url协议创建对应的URLConnection,不会真正的建立网络连接.
URLConnection connection = (HttpURLConnection) url.openConnection();
// A timeout of zero is interpreted as an infinite timeout.
connection.setConnectTimeout(this.connectTimeout);
connection.setReadTimeout(this.readTimeout);
connection.setDoInput(true);
// 如果是POST、PUT、PATCH、DELETE方法,需要enable output
connection.setDoOutput(true);
// 默认方法是GET.
connection.setRequestMethod(httpMethod);
/**
* request.execute 实现
*/
connection.setRequestProperty("Cookie", headerValue);
connection.addRequestProperty(headerName, actualHeaderValue);
// 构造Response,responseBody = connection.getInputStream()
new SimpleClientHttpResponse(connection)