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