目录

1.什么是RestTemplate?

2.RestTemplate的使用

2.1spring环境下

注意1:RestTemplate中发送请求execute()和exchange()方法的区别

execute()方式

exchange()方式

二者的区别

注意2:进阶配置——底层HTTP客户端

2.2非spring环境下


1.什么是RestTemplate?

RestTemplate是一款Spring框架中的HTTP客户端工具类库,它封装了大量的HTTP请求处理代码,使得我们可以方便地进行HTTP请求的发送与处理。RestTemplate支持多种HTTP请求方式,例如GET、POST、PUT、DELETE等,同时也支持参数的传递与响应结果的解析等功能,使得我们在进行RESTful风格的API开发时更加方便。

2.RestTemplate的使用

RestTemplate的使用分为俩种方式,一种是spring环境,一种是非spring环境

2.1spring环境下

添加pom依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

添加RestTemplate配置类:

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

使用示例:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * RestTemplate Use Example Demo
 *
 * @author JiuLi
 */
@Controller
public class RestTemplateCtrl {
    @Autowired
    private RestTemplate restTemplate;

    /**
     * exchange()形式
     *
     * @param data
     * @return
     */
    @RequestMapping(value = "/resttemplate/getNative", method = RequestMethod.GET)
    public String restTemplateNativeTest(Map data) {
        // 请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        HttpEntity<Object> httpEntity = new HttpEntity<>(data, httpHeaders);
        String url = "";
        // 发送请求
        ResponseEntity entity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        // 获取请求回调
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSON(entity.getBody()).toString());
        // 打印请求返回信息
        return jsonObject.toJSONString();
    }

    /**
     * execute()形式
     *
     * @param data
     * @return
     */
    @RequestMapping(value = "/resttemplate/getreqAndrep", method = RequestMethod.GET)
    public String restTemplateTest(Map data) {
        // 请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        HttpEntity<Object> httpEntity = new HttpEntity<>(httpHeaders);
        // 请求提取器
        RequestCallback requestCallback = restTemplate.httpEntityCallback(httpEntity, Map.class);
        // 响应提取器
        ResponseExtractor<ResponseEntity<Map>> responseExtractor = restTemplate.responseEntityExtractor(Map.class);
        String url = "";
        // 发送请求
        ResponseEntity entity = restTemplate.execute(url, HttpMethod.GET, requestCallback, responseExtractor, data);
        // 获取请求回调
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSON(entity.getBody()).toString());
        // 打印请求返回信息
        return jsonObject.toJSONString();
    }

}

注意1:RestTemplate中发送请求execute()和exchange()方法的区别

在使用RestTemplate发送HTTP请求时,我们通常会使用execute()或exchange()方法来发送请求。这两个方法的作用类似,但是有一些区别,在本篇博客中我们将介绍execute()和exchange()方法的区别。

execute()方式

execute()方法是RestTemplate中最基本的请求方法,它的定义如下:

public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
        ResponseExtractor<T> responseExtractor) throws RestClientException {
    // ...
}

传入四个参数:请求URL、HTTP请求方法、RequestCallback对象和ResponseExtractor对象。其中,RequestCallback代表着请求体,可以通过实现该接口来设置请求体的内容;ResponseExtractor代表着响应结果的处理器,可以通过实现该接口来对响应结果进行解析。

execute()方法可以返回任意类型的响应结果,包括自定义类型、String类型等由ResponseExtractor对象决定。

exchange()方式

exchange()方法的定义如下:

public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
        Class<T> responseType, Object... uriVariables) throws RestClientException {
    // ...
}

与execute()方法不同,exchange()方法返回的是ResponseEntity<T>类型的响应结果对象。ResponseEntity包含了响应状态码,响应头以及响应体等信息。

exchange()方法的请求体为HttpEntity对象,而非RequestCallback对象。HttpEntity用于封装请求体和请求头信息。

除此之外,在exchange()方法中还可以传入uriVariables参数。这个参数用于替换URL中的变量,例如:

String url = "http://localhost:8080/{id}";
ResponseEntity<User> response = restTemplate.exchange(url, HttpMethod.GET, null, User.class, 1);

在上述代码中,我们通过exchange()方法使用占位符{id}替换URL中的变量,并将变量的值设置为1。

二者的区别

execute()方法更加灵活,可以处理任意类型的响应结果,同时请求体也更加自由。而exchange()方法则更加直观,能够提供完整的响应对象,方便进行状态码和响应头的解析。

当我们只需要简单地获取响应结果时,可以使用execute()方法;而在需要对响应状态码、响应头等信息进行处理时,建议使用exchange()方法。

注意2:进阶配置——底层HTTP客户端

如上方式添加的RestTemplate配置类默认使用的是JDK自带的HttpURLConnection客户端作为底层的HTTP客户端实现的,实际上使用默认的HttpURLConnection客户端已经足够我们进行一系列的Http请求操作了,但是具体受限于某些需求或项目要求,HttpURLConnection客户端不满足一些我们的需求,那么我们可以通过配置替换的方式,指定使用HttpClient客户端替换默认的客户端;HttpClient是一个功能强大、高度可定制、性能优越的HTTP客户端工具类库,它可以满足更多复杂的HTTP请求需求。

使用HttpClient客户端好处:

1.支持连接池:使用HttpClient作为底层客户端可以支持连接池机制,减少每次请求建立连接和关闭连接的开销,提高请求效率。而默认的HttpURLConnection会在每次请求时重新建立连接,效率较低。

2.支持自定义拦截器:使用HttpClient可以通过自定义拦截器来实现一些特殊的功能,例如HTTP认证、请求重试等。而HttpURLConnection则很难通过自定义拦截器来实现这些功能。

3.支持更多协议:HttpClient支持HTTP协议以外的协议,例如HTTPS、FTP等。

缺点:

1.需要额外配置:如果使用HttpClient作为底层客户端,需要引入相应的依赖,并进行相应的配置,增加了使用成本。

2.可能会有线程安全的问题:默认情况下,HttpClient是不线程安全的,如果在多线程环境下并发使用同一个HttpClient实例,可能会出现线程安全问题。为了避免这个问题,我们可以采用各种线程安全的HttpClient实现方式,例如使用PoolingHttpClientConnectionManager来管理连接池。

使用Httpclient,在RestTemplateConfig配置即可:

首先需要添加pom依赖:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>${httpclient.version}</version>
</dependency>

方式一:

import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;


@Configuration
public class RestTemplateConfig {
    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }

    /**
     * 使用HttpClient作为底层客户端
     * @return
     */
    private ClientHttpRequestFactory getClientHttpRequestFactory() {
        int timeout = 5000;
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(timeout)
                .setConnectionRequestTimeout(timeout)
                .setSocketTimeout(timeout)
                .build();
        CloseableHttpClient client = HttpClientBuilder
                .create()
                .setDefaultRequestConfig(config)
                .build();
        return new HttpComponentsClientHttpRequestFactory(client);
    }

}

方式二:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;


@Configuration
public class RestTemplateConfig {
    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(new PoolingHttpClientConnectionManager())
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }


}

当然还有其他的Http客户端,例如OKHttpClient,OKHttpClient优于Httpclient优于默认的HttpURLConnection;具体如何选择看开发需求,以下是使用OKHttpClient的配置:

import okhttp3.OkHttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfig {
    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
    

    /**
     * 使用OkHttpClient作为底层客户端
     * @return
     */
    private ClientHttpRequestFactory getClientHttpRequestFactory(){
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .writeTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .build();
        return new OkHttp3ClientHttpRequestFactory(okHttpClient);
    }

}

2.2非spring环境下

导入依赖:

如果当前项目不是Spring项目,加入spring-web包,即可引入RestTemplate

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.2.6.RELEASE</version>
</dependency>
 

使用new的形式获取到RestTemplate的实例,以发送get请求为例进行测试:

public void simpleTest() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "";
    String str = restTemplate.getForObject(url, String.class);
    System.out.println(str);
}

所以,当在非spring环境下需要使用resttemplate时,只需要使用New获取到restTmeplate的实例,然后再进行之后所需要的收发Http请求的操作即可

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐