Spring-Web RestTemplate

Spring RestTemplate

简介

web服务端开发,如果涉及与第三方通过HTTP交互的需求,就可以使用Spring框架提供了RestTemplate进行阻塞式IO;封装各种请求方式进行远程HTTP访问。完全能满足目前的各种请求方式了。

RestTemplate

UML类图展示
在这里插入图片描述
以上展示有一个接口RestOperations,两个抽象类,HttpAccessor,InterceptingHttpAccessor;

RestOperations

RestOperations是一个接口,定义了一些基本的Restful操作,定义方法详情如下:
在这里插入图片描述
基本上RESTful的多种HTTP方法都定义了执行操作;

HttpAccessor

HttpAccessor 是一个HTTP请求的辅助器,结构如下图所示:
在这里插入图片描述
有一个属性ClientHttpRequestFactory,默认值为SimpleClientHttpRequestFactory。提供了Getter/Setter方法,同时提供了一个protect createRequest方法,表明该方法可以提供给子类使用;
在这里插入图片描述
从上述得知,该辅助器其实是ClientHttpRequestFactory外面的一层皮,从createRequest方法中其实也看到了内部调用也是ClientHttpRequestFactory里的实现。所以HTTP辅助器的真正主角是ClientHttpRequestFactory。
ClientHttpRequestFactory是用来创建ClientHttpRequest的一个工厂类,这两个类都是接口类,ClientHttpRequestFactory专门用来生产ClientHttpRequest,ClientHttpRequest表示的是一个HTTP请求的信息。
ClientHttpRequest的UML类图信息
在这里插入图片描述
ClientHttpRequest想说明的信息有:可以获取Url,Http方法,请求执行,请求返回信息;
简单地用默认SimpleClientHttpRequestFactory来进行说明:

public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
		HttpURLConnection connection = openConnection(uri.toURL(), this.proxy);
		prepareConnection(connection, httpMethod.name());

		if (this.bufferRequestBody) {
			return new SimpleBufferingClientHttpRequest(connection, this.outputStreaming);
		}
		else {
			return new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming);
		}
	}
	
	protected HttpURLConnection openConnection(URL url, @Nullable Proxy proxy) throws IOException {
		URLConnection urlConnection = (proxy != null ? url.openConnection(proxy) : url.openConnection());
		if (!HttpURLConnection.class.isInstance(urlConnection)) {
			throw new IllegalStateException("HttpURLConnection required for [" + url + "] but got: " + urlConnection);
		}
		return (HttpURLConnection) urlConnection;
	}
	
	protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
		if (this.connectTimeout >= 0) {
			connection.setConnectTimeout(this.connectTimeout);
		}
		if (this.readTimeout >= 0) {
			connection.setReadTimeout(this.readTimeout);
		}

		connection.setDoInput(true);

		if ("GET".equals(httpMethod)) {
			connection.setInstanceFollowRedirects(true);
		}
		else {
			connection.setInstanceFollowRedirects(false);
		}

		if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) ||
				"PATCH".equals(httpMethod) || "DELETE".equals(httpMethod)) {
			connection.setDoOutput(true);
		}
		else {
			connection.setDoOutput(false);
		}

		connection.setRequestMethod(httpMethod);
	}

创建Request流程描述如下:
1、打开一个HttpURLConnection
2、准备connection的配置参数,例如链接超时时间,读取超时时间,HTTP方法等配置信息;
3、通过返回结果类型标识符来控制是返回SimpleBufferingClientHttpRequest还是SimpleStreamingClientHttpRequest;
最终执行请求的代码,如下:

protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
		addHeaders(this.connection, headers);
		// JDK <1.8 doesn't support getOutputStream with HTTP DELETE
		if (getMethod() == HttpMethod.DELETE && bufferedOutput.length == 0) {
			this.connection.setDoOutput(false);
		}
		if (this.connection.getDoOutput() && this.outputStreaming) {
			this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
		}
		this.connection.connect();
		if (this.connection.getDoOutput()) {
			FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
		}
		else {
			// Immediately trigger the request in a no-output scenario as well
			this.connection.getResponseCode();
		}
		return new SimpleClientHttpResponse(this.connection);
	}

最终还是通过Connection.connect()进行实现链接,然后进行数据交互;

InterceptingHttpAccessor

这个主要是控制自定义的拦截器的,如果添加了拦截器,getRequestFactory方法就会获取到InterceptingClientHttpRequestFactory,就用该工厂类创建Request

猜你喜欢

转载自blog.csdn.net/jianghuafeng0/article/details/106926814