springboot中RestTemplate的用法

RestTemplate是spring提供的用于发送HTTP请求的的模板方法,其中spring提供了很多类似的模板方法,例如RedisTemplate、JdbcTemplate等等…这类模板方法其实是对一些原生API的抽象和封装,有助与我们方便的使用这些API,并且它的可定制性很强,很多功能我们可以按需进行定制和扩展。
下面为RestTemplate的官网介绍:

The RestTemplate provides a higher level API over HTTP client libraries. It makes it easy to invoke REST endpoints in a single line. It exposes the following groups of overloaded methods。

大致意思:RestTemplate在HTTP客户端库上提供了更高级别的API。使用它很容易调用其他的restful API

阅读本片博客你将掌握:

  1. 如何配置RestTemplate(超时时间、连接池)
  2. 使用RestTemplate发送REST请求
  3. 使用RestTemplate进行文件上传
  4. 配置RestTemplate用于get请求携带multipart/form-data数据

让我们开始把~
老规矩贴一下pom文件


```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.syx</groupId>
    <artifactId>syxweb</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>syxweb</name>
    <description>webApp</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
       <!-- <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
-->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.42.Final</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.54</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

pom里有一些不用的依赖可以自行剔除

1、如何配置RestTemplate(超时时间、连接池)

package com.syx.config;

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.net.URI;

/**
 * @author:whh
 * @date: 2022-11-07 20:42
 * <p></p>
 */
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();

        /**
         * 使用客户端类API调用远程交易时必须设置相应的超时时间,如果远程交易有问题如长时间未响应,若未设置超时时间,则会耗尽客户端所在服务器的资源
         */
        // 连接超时
        requestFactory.setConnectTimeout(5000);
        //读超时
        requestFactory.setReadTimeout(10000);
        //连接池获取连接超时时间
        requestFactory.setConnectionRequestTimeout(5000);

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        //Httpclient连接池的方式,同时支持netty,okHttp以及其他http框架
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        connectionManager.setMaxTotal(200);
        // 同路由并发数
        connectionManager.setDefaultMaxPerRoute(50);
        //配置连接池
        httpClientBuilder.setConnectionManager(connectionManager);

        // 最大连接数
        connectionManager.setMaxTotal(500);
        // 同路由并发数(每个主机的并发)
        connectionManager.setDefaultMaxPerRoute(100);
        httpClientBuilder.setConnectionManager(connectionManager);
        requestFactory.setHttpClient(httpClientBuilder.build());
        restTemplate.setRequestFactory(requestFactory);
        return restTemplate;
    }
}

2、使用RestTemplate发送REST请求

2.1 RestTemplate发送get请求
@Test
    public void func4() {
    	//远程REST调用API
        String uri = "http://localhost:8888/user/testGet";
        //发送请求
        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
        //打印响应
        System.out.println(response.getBody());

    }
2.2 RestTemplate发送POST请求并携带json数据
 @Test
    public void func5() {
        String uri = "http://localhost:8888/user/testJson";
        //请求头中设备传递的数据类型未json
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        User user = new User();
        user.setId("1");
        user.setUsername("zsda");
        String s = JSON.toJSON(user).toString();
        //将json数据及请求头封装到请求体中
        HttpEntity<String> formEntity = new HttpEntity<String>(s, headers);
       //发送请求
        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, formEntity, String.class);
        System.out.println(response.getBody());

    }

服务端代码如下:其中必须指定@RequestBody注解,用于springmvc将请求的json数据转换为java bean

 /**
     * 接受JSON类型的数据
     * @param user
     */
    @RequestMapping(value = "/testJson",method = RequestMethod.POST)
    public void queryForJson(@RequestBody User user){
        System.out.println(user);
    }
2.3 RestTemplate发送POST请求并携带multipart/form-data类型数据
 @Test
    public void func2() {
    
        HttpHeaders headers = new HttpHeaders();
        //设置请求头为multipart/form-data类型数据
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //MultiValueMap用于存放MULTIPART_FORM_DATA数据(其实就是key,value类型的键值对)
        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
        form.add("id", "1");
        form.add("name", "张三");
     
        String uri = "http://localhost:8888/user/test";
        HttpEntity< MultiValueMap<String, String>> entity = new HttpEntity<>(form,headers);
        //发送请求
        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
        System.out.println(response.getBody());

    }

服务端代码如下:

 @RequestMapping(value = "/testPost",method = RequestMethod.POST)
    public User queryForPost(String id,String name){
        User user = new User();
        user.setUsername(name);
        return user;
    }

3、使用RestTemplate进行文件上传

文件上传其实就是上传multipart/form-data类型的数据

 @Test
    public void func6() {
        FileSystemResource file = new FileSystemResource("C:\\Users\\xxx\\Desktop\\xxx.jpg");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        try {
            headers.setContentLength(file.contentLength());
        } catch (IOException e) {
            e.printStackTrace();
        }
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("file", file);
        String uri = "http://localhost:8888/user/upload";
        HttpEntity< MultiValueMap<String, Object>> entity = new HttpEntity<>(form,headers);
        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
        System.out.println(response.getBody());

    }

服务端代码如下:

  @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public void uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
    System.out.println(file.getOriginalFilename());
        file.transferTo(new File("C:\\Users\\xxx\\Desktop\\xxx-temp.jpg"));
        
    }

4、配置RestTemplate用于get请求携带multipart/form-data数据

原生的RestTemplate在发送get请求时,无法携带body数据,但是有时候咱们的业务场景需要这样做,所以我们可以对RestTemplate重新配置达到该目的。

package com.syx.config;

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.net.URI;

/**
 * @author:whh
 * @date: 2022-11-07 20:42
 * <p></p>
 */
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory() {
            @Override
            protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
                if (httpMethod == HttpMethod.GET) {
                    return new HttpGetRequestWithEntity(uri);
                }
                return super.createHttpUriRequest(httpMethod, uri);
            }
        };

        /**
         * 使用客户端类API调用远程交易时必须设置相应的超时时间,如果远程交易有问题如长时间未响应,若未设置超时时间,则会耗尽客户端所在服务器的资源
         */
        // 连接超时
        requestFactory.setConnectTimeout(5000);
        //读超时
        requestFactory.setReadTimeout(10000);
        //连接池获取连接超时时间
        requestFactory.setConnectionRequestTimeout(5000);

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        //Httpclient连接池的方式,同时支持netty,okHttp以及其他http框架
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        connectionManager.setMaxTotal(200);
        // 同路由并发数
        connectionManager.setDefaultMaxPerRoute(50);
        //配置连接池
        httpClientBuilder.setConnectionManager(connectionManager);

        // 最大连接数
        connectionManager.setMaxTotal(500);
        // 同路由并发数(每个主机的并发)
        connectionManager.setDefaultMaxPerRoute(100);
        httpClientBuilder.setConnectionManager(connectionManager);
        requestFactory.setHttpClient(httpClientBuilder.build());
        restTemplate.setRequestFactory(requestFactory);
        return restTemplate;
    }

    private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
        public HttpGetRequestWithEntity(final URI uri) {
            super.setURI(uri);
        }
        @Override
        public String getMethod() {
            return HttpMethod.GET.name();

        }
    }
}

重写一下HttpComponentsClientHttpRequestFactory 的createHttpUriRequest方法在请求方式为get的时候使用我们自定义的HttpGetRequestWithEntity 类

 @Test
    public void func2() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
        form.add("id", "1");
        form.add("name", "张三");
        form.add("sex","男");
        String uri = "http://localhost:8888/user/test";
        HttpEntity< MultiValueMap<String, String>> entity = new HttpEntity<>(form,headers);
        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
        System.out.println(response.getBody());

    }

服务端代码:

 @RequestMapping(value = "/test",method = RequestMethod.GET)
    public User query(User user){
        return user;
    }

ok~咱们的RestTemplate的使用方式就讲完啦

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot项目使用RestTemplate可以方便地进行HTTP请求。你可以通过创建RestTemplate实例来使用它。在你提供的代码,你展示了两种使用RestTemplate的方式。 第一种方式是通过自己创建RestTemplate实例并设置连接超时和读取超时的方式。你可以使用SimpleClientHttpRequestFactory来设置连接超时和读取超时的时间,然后将其设置为RestTemplate的请求工厂。这样就可以创建一个自定义配置的RestTemplate实例。 第二种方式是通过使用注解@Autowired将RestTemplate实例注入到你的代码。这种方式需要在Spring Boot项目配置RestTemplate的Bean,然后使用@Autowired注解将其注入到需要使用的地方。 RestTemplate提供了多种方法来发送HTTP请求,包括GET请求、POST请求、PUT请求、DELETE请求等。你可以根据需要选择合适的方法来发送请求。在你提供的代码,展示了使用postForObject方法发送POST请求的示例。你可以指定请求的URL、请求的参数和返回结果的类型,然后使用postForObject方法发送请求并获取返回结果。 总之,Spring BootRestTemplate是一个方便的HTTP请求工具,可以帮助你发送各种类型的HTTP请求。你可以根据需要选择合适的方式来使用RestTemplate。 #### 引用[.reference_title] - *1* [Springboot 使用RestTemplate](https://blog.csdn.net/qq_30938705/article/details/109804221)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [SpringBoot使用RestTemplate](https://blog.csdn.net/watson2017/article/details/124865399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值