互联网技术 之 远程调用

远程调用相关知识

1. 什么是远程调用

  • 远程调用: 一个项目调用另外一个项目模块(功能)
  • 调用过程: 模拟浏览器过程

2.常见远程调用方式

  • RPC: 自定义数据格式的远程调用方式。 更偏向于底层,通信速度快, 效率高。
    常见框架: dubbo
  • HTTP: 采用http协议远程调用方式, 规定了数据传输的格式 ,缺点是消息封装臃肿(请求头行体,响应头行体).。在热门的Rest风格,就可以通过http协议来实现。
    常见框架: HttpClient , RestTemplate
    在这里插入图片描述
  • 选择:
    微服务.更加强调的是 独立,自主,灵活, 一般都会采用基于Http的Rest风格.

3.HttpClient入门

  • 概述
    HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
  • 语法

GET请求(Delete同理)

//get请求
  CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;

        try {
            //    1,创建客户端
            httpClient = HttpClients.createDefault();
            //    2,创建get实例
            HttpGet httpGet = new HttpGet("请求路径");
            //    3,发送请求
            response = httpClient.execute(httpGet);
            //    4,判断响应状态码
            if(response.getStatusLine().getStatusCode() == 200){
                //    5,获得响应结果
                String str = EntityUtils.toString(response.getEntity());
                System.out.println(str);
            }
          
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //    6,释放资源
            httpClient.close();
            response.close();
        }
//get请求, 多条件查询

          CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;

        try {
            //    1,创建客户端
            httpClient = HttpClients.createDefault();
            //    2,获得get请求实例
            //2.1设置拼接参数
            StringBuilder sbf = new StringBuilder();
            sbf.append("username=wang");
            sbf.append("&");
            sbf.append("password=1234");
            HttpGet httpGet = new HttpGet("请求路径" +"?" + sbf.toString());
            //    3,发送请求
            response = httpClient.execute(httpGet);
            //    4,判断响应状态码
            if(response.getStatusLine().getStatusCode() == 200){
                //    5,获得响应结果
                String str = EntityUtils.toString(response.getEntity());
                System.out.println(str);
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //    6,释放资源
            response.close();
            httpClient.close();
        }

POST请求(PUT同理)

CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            //获取post请求实例
            HttpPost httpPost = new HttpPost("http://localhost:9090/user");
            //    2.1 设置请求头
            httpPost.setHeader("Content-Type","application/json;charset=utf-8");
            //    2.2 设置请求体
            //    处理json数据
            User user = new User(4, "小王", "1234", 12);
            String jsonstr = JSON.toJSONString(user);

            httpPost.setEntity( new StringEntity(jsonstr,"UTF-8"));
            response =  httpClient.execute(httpPost);
            if(response.getStatusLine().getStatusCode() == 200){
                String str = EntityUtils.toString(response.getEntity());
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            response.close();
            httpClient.close();
        }

4.HttpClient高级

  1. 使用HttpClients.custom()可以构建自定义 CloseableHttpClient 对象
    setConnectionManager 用于配置连接
    setDefaultRequestConfig 用于配置请求

    1. 通过PoolingHttpClientConnectionManager 可以为连接配置连接数和并发数
    2. 通过 RequestConfig.custom() 可以配置各种超时时间

    (自定义httpclient 及 springboot,RestTemplate 整合 HTTPClient 完整版详见文档最后 )

5.RestTemplate

1.概述:

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

2.语法

注意: 使用RestTemplate封装数据时,BaseResult必须提供无参构造

//1, 创建核心类
RestTemplate restTemplate = new RestTemplate();
//get请求
 ResponseEntity<返回值类型> entiy =
           restTemplate.getForEntity("请求路径", 返回值类型.class);
//post请求
ResponseEntity<返回值类型> entiy
          = restTemplate.postForEntity("请求路径", 请求参数, 返回值类型.class);
//put请求
 restTemplate.put("请求路径",请求参数);
//delete请求
 restTemplate.delete("请求参数");
//返回值获取
entiy.getStatusCode()    //获取状态码
entiy.getBody()          //获取内容

3.配置类的使用

  • 步骤一 : 编写配置类, 将需要new的对象交于spring进行管理
@Configuration    //配置类, springboot会自动扫描
public class{
	@Bean		//spring将管理此方法创建的对象
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}
  • 步骤二 : 在任意位置, 通过 @Resource 进行注入
public class AdminClient{
    @Resource	//因为配置类已经构建对象, 此处自动注入
    public RestTemplate restTemplate;
    //..使用即可
}

6.基于http协议远程调用对比

  • HttpClient 更偏向于底层,学习时原理。相当于模型浏览器。 但操作比较繁琐。
  • RestTemplate 对整个请求进行简化.
  • 实际开发中RestTemplate整合HttpClient

在这里插入图片描述

7. http配置类(完整版)

package com.czxy.config;

import lombok.Setter;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 zhaorenhui.
 */
@Configuration
@ConfigurationProperties(prefix = "http")
@Setter
public class HttpConfig {

    private Integer maxTotal;
    private Integer defaultMaxPerRoute;
    private Integer connectTimeout;
    private Integer connectionRequestTimeout;
    private Integer socketTimeout;
    private Integer staleConnectionCheckEnabled;
    
// springBoot整合httpClient
    @Bean
    public PoolingHttpClientConnectionManager connectionManager(){
        //1 配置连接管理
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        // 1.1 设置最大连接数
        connectionManager.setMaxTotal(maxTotal);
        // 1.2 设置并发访问数
        connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return connectionManager;
    }

    @Bean
    public RequestConfig requestConfig(){
        //2 请求配置
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(connectTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout)
            .setSocketTimeout(socketTimeout)
            .build();
        return requestConfig;
    }

    @Bean
    public HttpClient httpClient(HttpClientConnectionManager connectionManager, RequestConfig requestConfig){
        // 3 获得工具类
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                //重定向策略
                .setRedirectStrategy(new LaxRedirectStrategy())
                .build();
        return httpClient;
    }

// RestTemplate整合HttpClient
    @Bean
    public ClientHttpRequestFactory requestFactory(HttpClient httpClient ){
        return new HttpComponentsClientHttpRequestFactory(httpClient);
    }

    @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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值