publicclass SimpleHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor {
//HTTP調用請求執行器真正進行遠端調用的方法,該方法有其父類//AbstractHttpInvokerRequestExecutor的executeRequest方法調用
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
throws IOException, ClassNotFoundException {
//打開一個标準的J2SE HttpURLConnection
HttpURLConnection con = openConnection(config);
//準備連接配接
prepareConnection(con, baos.size());
//遠端調用被封裝成了RemoteInvocation對象,它通過序列化被寫到對應的//HttpURLConnection中
writeRequestBody(config, con, baos);
//擷取遠端調用的結果,校驗傳回的結果
validateResponse(config, con);
InputStream responseBody = readResponseBody(config, con);
//将遠端調用結果轉換成RemoteInvocationResult傳回
return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
}
//打開一個HttpURLConnection
protected HttpURLConnection openConnection(HttpInvokerClientConfiguration config) throws IOException {
//getServiceUrl()方法擷取配置的遠端調用URL,打開一個URL連接配接
URLConnection con = new URL(config.getServiceUrl()).openConnection();
if (!(con instanceof HttpURLConnection)) {
thrownew IOException("Service URL [" + config.getServiceUrl() + "] is not an HTTP URL");
}
return (HttpURLConnection) con;
}
//準備HTTP請求連接配接
protectedvoid prepareConnection(HttpURLConnection con, int contentLength) throws IOException {
con.setDoOutput(true);
//HTTP調用器隻支援POST請求方法
con.setRequestMethod(HTTP_METHOD_POST);
//設定HTTP請求頭内容類型,設定為:application/x-java-serialized-object
con.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, getContentType());
//設定HTTP請求頭内容長度
con.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, Integer.toString(contentLength));
LocaleContext locale = LocaleContextHolder.getLocaleContext();
//設定HTTP請求的Locale
if (locale != null) {
con.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale.getLocale()));
}
//設定HTTP請求壓縮方式
if (isAcceptGzipEncoding()) {
con.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
}
//把序列化對象輸出到HTTP請求體中
protectedvoid writeRequestBody(
HttpInvokerClientConfiguration config, HttpURLConnection con, ByteArrayOutputStream baos)
throws IOException {
baos.writeTo(con.getOutputStream());
}
//校驗遠端調用的HTTP響應
protectedvoid validateResponse(HttpInvokerClientConfiguration config, HttpURLConnection con)
throws IOException {
//如果HTTP響應狀态碼大于等于300,則證明調用發生錯誤
if (con.getResponseCode() >= 300) {
thrownew IOException(
"Did not receive successful HTTP response: status code = " + con.getResponseCode() +
", status message = [" + con.getResponseMessage() + "]");
}
}
//提取遠端調用結果的HTTP響應資訊
protected InputStream readResponseBody(HttpInvokerClientConfiguration config, HttpURLConnection con)
throws IOException {
//如果響應資訊是Gzip壓縮的,則需要先解壓
if (isGzipResponse(con)) {
returnnew GZIPInputStream(con.getInputStream());
}
//正常的HTTP響應
else {
return con.getInputStream();
}
}
//是否是Gzip格式壓縮
protectedboolean isGzipResponse(HttpURLConnection con) {
//擷取HTTP響應頭資訊中的壓縮方式
String encodingHeader = con.getHeaderField(HTTP_HEADER_CONTENT_ENCODING);
return (encodingHeader != null && encodingHeader.toLowerCase().indexOf(ENCODING_GZIP) != -1);
}
}