The RestTemplate is the core class for client-side access to RESTful services. It is conceptually similar to other template classes in Spring, such as JdbcTemplate andJmsTemplate and other template classes found in other Spring portfolio projects.RestTemplate’s behavior is customized by providing callback methods and configuring the HttpMessageConverter used to marshal objects into the HTTP request body and to unmarshal any response back into an object. As it is common to use XML as a message format, Spring provides a MarshallingHttpMessageConverter that uses the Object-to-XML framework that is part of the org.springframework.oxm package. This gives you a wide range of choices of XML to Object mapping technologies to choose from.
This section describes how to use the RestTemplate and its associated HttpMessageConverters.
Invoking RESTful services in Java is typically done using a helper class such as Apache HttpComponents HttpClient. For common REST operations this approach is too low level as shown below.
RestTemplate provides higher level methods that correspond to each of the six main HTTP methods that make invoking many RESTful services a one-liner and enforce REST best practices.
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
RestTemplate构造方法
RestTemplate有3个构造方法,一个无参构造,两个有参构造
RestTemplate无参构造
/**
* Create a new instance of the {@link RestTemplate} using default settings.
* Default {@link HttpMessageConverter}s are initialized.
* 使用默认配置创建一个RestTemplate实例
* 默认的HttpMessageConverter集合被初始化
*/
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter());
this.messageConverters.add(new SourceHttpMessageConverter());
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (jackson2XmlPresent) {
this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
}
else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
/**
* 如果类路径下包含com.fasterxml.jackson.databind.ObjectMapper 和 com.fasterxml.jackson.core.JsonGenerator
* 使用jackson做http请求、响应的json转换
*/
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
}
}
参数为ClientHttpRequestFactory的构造
/**
* Create a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.
* @param requestFactory HTTP request factory to use
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
* @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory
* 使用指定的ClientHttpRequestFactory创建一个RestTemplate实例
* requestFactory是用于创建HTTP请求的工厂,默认的实现有
* SimpleClientHttpRequestFactory、HttpComponentsClientHttpRequestFactory
* 如果没有设置默认是SimpleClientHttpRequestFactory
*/
public RestTemplate(ClientHttpRequestFactory requestFactory) {
this(); //也会调用无参构造初始化默认的messageConverters
setRequestFactory(requestFactory);
}
参数为messageConverters的构造
/**
* Create a new instance of the {@link RestTemplate} using the given list of
* {@link HttpMessageConverter} to use
* @param messageConverters the list of {@link HttpMessageConverter} to use
* @since 3.2.7
* 传入自定义的HttpMessageConverter集合,并赋值给messageConverters,之后使用自定义的HttpMessageConverter
*/
public RestTemplate(List> messageConverters) {
Assert.notEmpty(messageConverters, "At least one HttpMessageConverter required");
this.messageConverters.addAll(messageConverters);
}
T getForObject(String url, Class responseType, Object... uriVariables) T getForObject(String url, Class responseType, Map uriVariables) T getForObject(URI url, Class responseType)
ResponseEntity getForEntity(String url, Class responseType, Object... uriVariables) ResponseEntity getForEntity(String url, Class responseType, Map uriVariables) ResponseEntity getForEntity(URI url, Class responseType)
Set optionsForAllow(String url, Object... uriVariables) Set optionsForAllow(String url, Map uriVariables) Set optionsForAllow(URI url)
POST
T postForObject(String url, Object request, Class responseType, Object... uriVariables) T postForObject(String url, Object request, Class responseType, Map uriVariables) T postForObject(URI url, Object request, Class responseType)
ResponseEntity postForEntity(String url, Object request, Class responseType, Object... uriVariables) ResponseEntity postForEntity(String url, Object request, Class responseType, Map uriVariables) ResponseEntity postForEntity(URI url, Object request, Class responseType)
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("MyRequestHeader", "MyValue");
HttpEntity requestEntity = new HttpEntity(requestHeaders);
Book book = restTemplate.postForObject("http://127.0.0.1:8080/getbook", requestEntity, Book.class);
/**
* Create a new, empty {@code HttpEntity}.
*/
protected HttpEntity() {
this(null, null);
}
/**
* Create a new {@code HttpEntity} with the given body and no headers.
* @param body the entity body
*/
public HttpEntity(T body) {
this(body, null);
}
/**
* Create a new {@code HttpEntity} with the given headers and no body.
* @param headers the entity headers
*/
public HttpEntity(MultiValueMap headers) {
this(null, headers);
}
/**
* Create a new {@code HttpEntity} with the given body and headers.
* @param body the entity body
* @param headers the entity headers
*/
public HttpEntity(T body, MultiValueMap headers) {
this.body = body;
HttpHeaders tempHeaders = new HttpHeaders();
if (headers != null) {
tempHeaders.putAll(headers);
}
this.headers = HttpHeaders.readOnlyHttpHeaders(tempHeaders);
}
/**
* Factory for {@link ClientHttpRequest} objects.
* Requests are created by the {@link #createRequest(URI, HttpMethod)} method.
* ClientHttpRequest对象的工厂
*
* @author Arjen Poutsma
* @since 3.0
*/
public interface ClientHttpRequestFactory {
/**
* Create a new {@link ClientHttpRequest} for the specified URI and HTTP method.
*
The returned request can be written to, and then executed by calling
* {@link ClientHttpRequest#execute()}.
* 使用指定的URI和HTTP方法新建一个ClientHttpRequest对象
* 可以修改返回的request,并通过ClientHttpRequest的execute()方法执行调用
* 即调用的逻辑也被Spring封装到ClientHttpRequest中
*
* @param uri the URI to create a request for
* @param httpMethod the HTTP method to execute
* @return the created request
* @throws IOException in case of I/O errors
*/
ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException;
}
构造方法设置:
/**
* Create a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.
* @param requestFactory HTTP request factory to use
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
* @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory
*/
public RestTemplate(ClientHttpRequestFactory requestFactory) {
this();
setRequestFactory(requestFactory);
}
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory {
。。。。。。
private int connectTimeout = -1;
private int readTimeout = -1;
//创建Request
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
HttpURLConnection connection = openConnection(uri.toURL(), this.proxy);
prepareConnection(connection, httpMethod.name());
//bufferRequestBody默认为true
if (this.bufferRequestBody) {
return new SimpleBufferingClientHttpRequest(connection, this.outputStreaming);
}
else {
return new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming);
}
}
/**
* Opens and returns a connection to the given URL.
* 打开并返回一个指定URL的连接
*
The default implementation uses the given {@linkplain #setProxy(java.net.Proxy) proxy} -
* if any - to open a connection.
* @param url the URL to open a connection to
* @param proxy the proxy to use, may be {@code null}
* @return the opened connection 返回类型为 java.net.HttpURLConnection
* @throws IOException in case of I/O errors
*/
protected HttpURLConnection openConnection(URL url, 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;
}
/**
* Template method for preparing the given {@link HttpURLConnection}.
*
The default implementation prepares the connection for input and output, and sets the HTTP method.
* @param connection the connection to prepare
* @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.)
* @throws IOException in case of I/O errors
*/
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
//如果connectTimeout大于等于0,设置连接超时时间
if (this.connectTimeout >= 0) {
connection.setConnectTimeout(this.connectTimeout);
}
//如果readTimeout大于等于0,设置读超时时间
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);
}
。。。。。。
}
HttpComponentsClientHttpRequestFactory:
/**
* Merge the given {@link HttpClient}-level {@link RequestConfig} with
* the factory-level {@link RequestConfig}, if necessary.
* @param clientConfig the config held by the current httpClient级别的requestConfig配置
* @return the merged request config
* (may be {@code null} if the given client config is {@code null})
* @since 4.2
*/
protected RequestConfig mergeRequestConfig(RequestConfig clientConfig) {
if (this.requestConfig == null) { // nothing to merge
return clientConfig;
}
RequestConfig.Builder builder = RequestConfig.copy(clientConfig);
int connectTimeout = this.requestConfig.getConnectTimeout(); //HttpComponentsClientHttpRequestFactory级别的配置
if (connectTimeout >= 0) {
builder.setConnectTimeout(connectTimeout);
}
int connectionRequestTimeout = this.requestConfig.getConnectionRequestTimeout();
if (connectionRequestTimeout >= 0) {
builder.setConnectionRequestTimeout(connectionRequestTimeout);
}
int socketTimeout = this.requestConfig.getSocketTimeout();
if (socketTimeout >= 0) {
builder.setSocketTimeout(socketTimeout);
}
return builder.build();
}
用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支 持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。
实用命令实例
默认启动
tcpdump
普通情况下,直
MO= Mobile originate,上行,即用户上发给SP的信息。MT= Mobile Terminate,下行,即SP端下发给用户的信息;
上行:mo提交短信到短信中心下行:mt短信中心向特定的用户转发短信,你的短信是这样的,你所提交的短信,投递的地址是短信中心。短信中心收到你的短信后,存储转发,转发的时候就会根据你填写的接收方号码寻找路由,下发。在彩信领域是一样的道理。下行业务:由SP
import java.util.Arrays;
import java.util.Random;
public class MinKElement {
/**
* 5.最小的K个元素
* I would like to use MaxHeap.
* using QuickSort is also OK
*/
public static void
添加没有默认值:alter table Test add BazaarType char(1)
有默认值的添加列:alter table Test add BazaarType char(1) default(0)
删除没有默认值的列:alter table Test drop COLUMN BazaarType
删除有默认值的列:先删除约束(默认值)alter table Test DRO
Spring Boot 1.2.4已于6.4日发布,repo.spring.io and Maven Central可以下载(推荐使用maven或者gradle构建下载)。
这是一个维护版本,包含了一些修复small number of fixes,建议所有的用户升级。
Spring Boot 1.3的第一个里程碑版本将在几天后发布,包含许多