天天看点

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

}

}