远程调用(HttpClient,RestTemplate,整合自定义连接池,整合SpringBoot测试类)

远程调用

1.概述

  • 一个项目想要调用另一个项目的功能

  • “用户管理系统”调用“商品管理系统”这个现象,

    ​ 我们称为“远程调用”此时“用户管理系统”相当于模拟“浏览器”。

2.调用方式

  • RPC : 自定义数据格式的远程调用方式,更偏向于底层
    • 常见框架 : dubbo
  • Http : 采用了http远程调用协议,规定了数据传输的方式,缺点是消息封装臃肿
    • 现在热门的Rest风格,就可以通过http协议来实现
    • 常见框架 : HttpClient,RestTemplate
区别 HTTP RPC
速度 较慢
难度 简单 复杂
灵活性 灵活,跨平台、跨语言

3HttpClient入门

  • 确定maven环境
   <!--确定spring boot的版本-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <dependencies>
        <!--web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--httpclient-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>
        <!--支持lombok-->
        <dependency>
            <groupId>lombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.0</version>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.49</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
  • 使用HttpClient发送Get请求
		CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
		try {
            //1 创建Httpclient对象(默认连接),相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();

            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpGet httpGet = new HttpGet("http://localhost:9090/user");

            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpGet);

            //4 判断状态码
            if(response.getStatusLine().getStatusCode() == 200){
                //5.1 获得响应数据的类型
                System.out.println(response.getEntity().getContentType());
                //5.2 获得响应体内容并使用EntityUtils工具进行处理
                String str = EntityUtils.toString(response.getEntity(),"UTF-8");
                System.out.println(str);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
          //6 释放资源
          response.close();
          httpClient.close();
        }
  • 使用HttpClient发送Post请求

    		CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
            try {
                httpClient = HttpClients.createDefault();
    
                HttpPost httpPost = new HttpPost("http://localhost:9090/user");
                //  设置请求头
                httpPost.setHeader("content-type","application/json;charset=utf-8");
                //  设置并处理请求体
                String str = "{\"username\":\"jack\",\"password\":\"1111\"}";
                httpPost.setEntity(new StringEntity(str,"utf-8"));
    
                response = httpClient.execute(httpPost);
    
                if (response.getStatusLine().getStatusCode() == 200){
                    System.out.println(EntityUtils.toString(response.getEntity()));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                response.close();
                httpClient.close();
            }
    
  • 使用HttpClient发送Put请求

    		CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
            try {
                httpClient = HttpClients.createDefault();
                HttpPut httpPut = new HttpPut("http://localhost:9090/user");
                httpPut.setHeader("content-type","application/json;charset=utf-8");
                String jsonStr = JSON.toJSONString(new User(1, "jack", "1111", 18));
                httpPut.setEntity(new StringEntity(jsonStr,"utf-8"));
    
                response = httpClient.execute(httpPut);
    
                if (response.getStatusLine().getStatusCode() == 200){
                    System.out.println(EntityUtils.toString(response.getEntity()));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                response.close();
                httpClient.close();
            }
    
  • 使用HttpClient发送Delete请求

    		CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
            try {
                //1, 创建客户端
                httpClient = HttpClients.createDefault();
                //2, 创建DELETE实例
                HttpDelete httpDelete = new HttpDelete("http://localhost:9090/user/1");
                //3, 发送请求
                response = httpClient.execute(httpDelete);
                //4, 判断状态码
                if (response.getStatusLine().getStatusCode() == 200){
                    //5, 实用工具处理响应数据
                    System.out.println(EntityUtils.toString(response.getEntity()));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //6, 释放资源
                response.close();
                httpClient.close();
            }
    

4.RestTemplate

  • RestTemplate是Spring提供的用于访问Rest服务的客户端,

    ​ RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率

  • Get请求

      [@Test](https://my.oschina.net/azibug)
        public void testGet(){
            RestTemplate restTemplate = new RestTemplate();
            //  设置url,返回值类型
            ResponseEntity<BaseResult> entity = restTemplate.getForEntity("http://localhost:9090/user", BaseResult.class);
            //  返回状态码
            System.out.println(entity.getStatusCode());
            //  返回响应体
            System.out.println(entity.getBody().getData());
        }
    
  • Post请求

     [@Test](https://my.oschina.net/azibug)
        public void testLogin(){
            RestTemplate restTemplate = new RestTemplate();
            //  设置url,请求体(自动处理),返回值类型
            ResponseEntity<User> entity = restTemplate.postForEntity("http://localhost:9090/user/login", new User(1,"jack","1234",18), User.class);
            System.out.println(entity.getStatusCodeValue());
            System.out.println(entity.getBody());
        }
    
  • Put请求

    [@Test](https://my.oschina.net/azibug)
        public void testPut(){
            RestTemplate restTemplate = new RestTemplate();
             //  设置url
            restTemplate.put("http://localhost:9090/user",new User(1,"jack","1234",18));
            System.out.println("修改成功");
        }
    
  • Delete请求

     [@Test](https://my.oschina.net/azibug)
        public void testDelete(){
            RestTemplate restTemplate = new RestTemplate();
            //  设置url
            restTemplate.delete("http://localhost:9090/user/1");
            System.out.println(" 删除成功");
        }
    

5.SpringBoot 整合 HttpClient及RestTemplate自定义连接池

package com.czxy.config;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
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.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.List;

/**
 * Created by 澈 on 2019/12/3.
 */
@Configuration
public class HttpClientConfig {

    //1. 自定义连接 httpClient
    @Bean
    public CloseableHttpClient httpClient(PoolingHttpClientConnectionManager connectionManager,
                                          RequestConfig requestConfig){
        return HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    //2. 配置PoolingHttpClientConnectionManager
    @Bean
    public PoolingHttpClientConnectionManager connectionManager(){
        //1.  HttpClient连接管理器
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        //1.1.  最大连接数
        connectionManager.setMaxTotal(1000);
        //1.2.  设置并发访问数
        connectionManager.setDefaultMaxPerRoute(20);

        return connectionManager;
    }

    //3. 配置RequestConfig
    @Bean
    public RequestConfig requestConfig(){
        //1.3.  请求配置RequestConfig
        return RequestConfig.custom()
                .setConnectTimeout(1000)
                .setConnectionRequestTimeout(500)
                .setSocketTimeout(10 * 1000)
                .build();
    }

    //4. 创建一个工厂
    @Bean
    public ClientHttpRequestFactory requestFactory(HttpClient httpClient){
        return new HttpComponentsClientHttpRequestFactory(httpClient);
    }

    //5. 配置restTemplate
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory){
        RestTemplate template = new RestTemplate(requestFactory);
        //乱码处理
        List<HttpMessageConverter<?>> list = template.getMessageConverters();
        for (HttpMessageConverter<?> mc : list) {
            if (mc instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8"));
            }
        }
        return template;
    }
}

6.整合SpringBoot测试类

  • 在测试代码中可以进行Spring容器的注册
package com.czxy;

import com.alibaba.fastjson.JSON;
import com.czxy.domain.User;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * Created by 澈 on 2019/12/4.
 */
@RunWith(SpringRunner.class)    //spring 整合junit
@SpringBootTest(classes = HttpClientApplication.class)      //spring整合启动类
public class Test04 {
  	
    @Resource
    private CloseableHttpClient httpClient;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private PoolingHttpClientConnectionManager connectionManager;
    @Resource
    private RequestConfig requestConfig;

    @Test
    public void testDemo02(){
        System.out.println(httpClient);
        System.out.println(restTemplate);
        System.out.println(connectionManager);
        System.out.println(requestConfig);
    }
}
发布了31 篇原创文章 · 获赞 0 · 访问量 186

猜你喜欢

转载自blog.csdn.net/weixin_46759279/article/details/105713288