天天看點

java invoker_Spring的HTTPInvoker

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);

}

}