【微服务~远程调用】HttpClient入门

简介: 【微服务~远程调用】HttpClient入门

概述

       前言

2个团队,分别开发了“商品管理系统”和“用户管理系统”

image.png问题:“商品管理系统”需要使用“用户管理系统”某个功能,怎么办?

根据用户的会员等级,显示不同的打折

image.png

什么是远程调用

  • 客户端程序通过接口调用服务端程序,并获得该服务返回的数据的过程,称为远程调用。
  • “商品管理系统”调用“用户管理系统”的过程,就是“远程调用”。此时“商品管理系统”相当于模拟“浏览器”。

68dcf8aa8e0b4f2f8934cf9783192b9d.png

  调用方式

常见的远程调用方式有2种:

  • RPC:Remote Produce Call远程过程调用,==自定义数据==格式的远程调用方式。基于原生TCP通信,速度快,效率高。
  • Http:采用http协议远程调用方式,==规定==了数据传输的格式,缺点是消息封装臃肿。现在热门的Rest风格,就可以通过http协议来实现。

常见框架 :

  • RPC常见框架: dubbo、WebService
  • Http常见框架:HttpClient、RestTemplate

区别

HTTP

RPC

速度

较慢

难度

简单

复杂

灵活性

灵活,跨平台、跨语言


  如何选择

  • 那么我们该怎么选择呢?
  • ==微服务==,基于Spring Cloud的微服务,更加强调的是独立、自治、灵活,一般都会采用基于Http的Rest风格服务。

搭建环境

image.png

父项目

  • 项目名:nacos-parent-2.1
  • 添加坐标:
 <parent>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-build</artifactId>
        <version>2.3.5.RELEASE</version>
    </parent>
    <properties>
        <spring.cloud.version>Hoxton.SR12</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.7-SNAPSHOT</spring.cloud.alibaba.version>
        <mybatis.plus.starter.version>3.4.0</mybatis.plus.starter.version>
        <durid.starter.version>1.1.10</durid.starter.version>
        <swagger.version>2.7.0</swagger.version>
        <jwt.jjwt.version>0.9.0</jwt.jjwt.version>
        <jwt.joda.version>2.9.7</jwt.joda.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- Spring Dependencies -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- mybatis-plus -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis.plus.starter.version}</version>
            </dependency>
            <!-- Druid连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${durid.starter.version}</version>
            </dependency>
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

   测试数据项目

环境

  • 项目:nacos-data
  • 添加依赖
  <dependencies>
        <!--web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
        <!--支持lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
  • yml配置
server:
  port: 7778
  • 拷贝BaseResult 和 Swagger2ConfigurationV3
  • 编写启动类
1.package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * Created by liangtong.
 */
@SpringBootApplication
public class DataApplication {
    public static void main(String[] args) {
        SpringApplication.run(DataApplication.class, args);
    }
}

基本功能

  • 创建JavaBean
package com.czxy.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * Created by liangtong.
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer uid;
    private String username;
    private String password;
    private Integer age;
}
  • 编写基本功能(模拟数据)
package com.czxy.controller;
import com.czxy.domain.User;
import com.czxy.vo.BaseResult;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by liangtong.
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping
    public BaseResult findAll(){
        List<User> list = new ArrayList<>();
        list.add(new User(1,"jack","1234",18));
        list.add(new User(2,"rose","5678",21));
        list.add(new User(3,"tom","6666",25));
        return BaseResult.ok("查询所有",list);
    }
    @GetMapping("/{uid}")
    public BaseResult findById(@PathVariable("uid")Integer uid){
        User user = new User(1,"jack","1234",18);
        return BaseResult.ok("查询成功",user);
    }
    @GetMapping("/search")
    public BaseResult search(User user){
        System.out.println(user);
        return BaseResult.ok("查询成功",user);
    }
    @PostMapping
    public BaseResult save(@RequestBody User user){
        System.out.println(user);
//        return ResponseEntity.status(302).body(BaseResult.ok("添加成功"));
        return BaseResult.ok("添加成功");
    }
    @PutMapping
    public BaseResult update(@RequestBody User user){
        System.out.println(user);
        return BaseResult.ok("更新成功");
    }
    @DeleteMapping("/{uid}")
    public BaseResult deleteById(@PathVariable("uid")Integer uid){
        System.out.println(uid);
        return BaseResult.ok("删除成功");
    }
}

测试

http://localhost:7778/swagger-ui.html


HttpClient入门

概述

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


搭建环境

  • 创建项目:nacos-http
  • pom配置
 <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>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </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>
  • 创建启动类
package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HttpApplication {
    public static void main(String[] args) {
        SpringApplication.run(HttpApplication.class, args);
    }
}
  • 编写测试类
package com.czxy;
public class TestHttp {
}

 基本功能    

GET请求--无参:查询所有

以get请求的方式,获得所有结果


1.创建客户端 (相当于打开浏览器)。CloseableHttpClient


2.创建GET请求实例(确定访问路径) HTTPGet


3.发送请求(回车访问)execute


4.判断响应的状态码200


5.通过工具处理响应内容


6.关闭资源


代码

@Test
    public void testFindAll() {
        try {
            //1 创建Httpclient对象,相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();
            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpGet httpGet = new HttpGet("http://localhost:7778/user");
            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if(response.getStatusLine().getStatusCode() == 200) {
                String str = EntityUtils.toString(response.getEntity());
                System.out.println(str);
            }
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 如果响应的数据乱码,需要手动设定

image.png

练习:GET请求:查询详情

 @Test
    public void testFindId() {
        String id = "1";
        try {
            //1 创建Httpclient对象,相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();
            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpGet httpGet = new HttpGet("http://localhost:7778/user/" + id);
            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if(response.getStatusLine().getStatusCode() == 200) {
                String str = EntityUtils.toString(response.getEntity(),"UTF-8");
                System.out.println(str);
            }
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

GET请求--有参:拼凑URL

  • 基本使用
    @Test
    public void testDemo03(){
        try {
            //1 创建Httpclient对象,相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();
            StringBuilder params = new StringBuilder();
            params.append("username=张三");
            params.append("&");
            params.append("password=1234");
            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpGet httpGet = new HttpGet("http://localhost:7778/user/search" + "?" + params.toString());
            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if(response.getStatusLine().getStatusCode() == 200){
                // 3.1 获得响应数据的类型
                System.out.println(response.getEntity().getContentType());
                // 3.2 获得响应体内容
                String str = EntityUtils.toString(response.getEntity(),"UTF-8");
                System.out.println(str);
            }
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 拼凑特殊数据:URL中的特殊符号,需要使用URLEncoder处理
@Test
    public void testDemo04(){
        try {
            //1 创建Httpclient对象,相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();
            StringBuilder params = new StringBuilder();
            params.append("username=" + URLEncoder.encode("&","UTF-8"));
            params.append("&");
            params.append("password=1234");
            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpGet httpGet = new HttpGet("http://localhost:7778/user/search" + "?" + params.toString());
            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if(response.getStatusLine().getStatusCode() == 200){
                // 3.1 获得响应数据的类型
                System.out.println(response.getEntity().getContentType());
                // 3.2 获得响应体内容
                String str = EntityUtils.toString(response.getEntity(),"UTF-8");
                System.out.println(str);
            }
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

POST请求:手动拼凑JSON

@Test
    public void testInsert() {
        try {
            //1 创建Httpclient对象,相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();
            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpPost httpPost = new HttpPost ("http://localhost:7778/user/");
            // 2.1 准备json数据
            String jsonStr = "{\n" +
                    "      \"uid\": \"1\",\n" +
                    "      \"username\": \"jack\",\n" +
                    "      \"password\": \"1234\",\n" +
                    "      \"age\": \"18\"\n" +
                    "    }";
            // 2.2 设置请求体
            httpPost.setEntity(new StringEntity(jsonStr,"UTF-8"));
            // 2.3 设置请求数据类型为json
            httpPost.setHeader("content-type","application/json;charset=UTF-8");
            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpPost);
            if(response.getStatusLine().getStatusCode() == 200) {
                String str = EntityUtils.toString(response.getEntity(),"UTF-8");
                System.out.println(str);
            }
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

POST请求:fastjson

  • fastjson 是阿里巴巴提供最快的json转换工具
  • 如果要使用fastjson,修改pom.xml文件,添加坐标(如果已有,忽略此步)
<!--fastjson-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.49</version>
</dependency>
  • 拷贝JavaBean:User
  • 代码
 @Test
    public void testInsert2() {
        try {
            //1 创建Httpclient对象,相当于打开了浏览器
            CloseableHttpClient httpClient = HttpClients.createDefault();
            //2 确定请求方式和请求路径,相当于在浏览器输入地址
            HttpPost httpPost = new HttpPost ("http://localhost:7778/user/");
            // 2.1 准备json数据
            User user = new User(1,"jack","1234",18);
            String jsonStr = JSON.toJSONString(user);
            // 2.2 设置请求体
            httpPost.setEntity(new StringEntity(jsonStr,"UTF-8"));
            // 2.3 设置请求数据类型为json
            httpPost.setHeader("content-type","application/json;charset=UTF-8");
            //3 执行请求并获取响应,相当于敲完地址后按下回车。
            CloseableHttpResponse response = httpClient.execute(httpPost);
            if(response.getStatusLine().getStatusCode() == 200) {
                String str = EntityUtils.toString(response.getEntity(),"UTF-8");
                System.out.println(str);
            }
            response.close();
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


相关文章
|
机器学习/深度学习 负载均衡 Java
【SpringBoot系列】微服务远程调用Open Feign深度学习
【4月更文挑战第9天】微服务远程调度open Feign 框架学习
1046 2
|
消息中间件 RocketMQ 微服务
分布式事物【库存微服务业务层实现、实现充值微服务、充值微服务之业务层实现、账户微服务之业务层实现】(九)-全面详解(学习总结---从入门到深化)(下)
分布式事物【库存微服务业务层实现、实现充值微服务、充值微服务之业务层实现、账户微服务之业务层实现】(九)-全面详解(学习总结---从入门到深化)
262 0
|
Java API 微服务
Java 21 与 Spring Boot 3.2 微服务开发从入门到精通实操指南
《Java 21与Spring Boot 3.2微服务开发实践》摘要: 本文基于Java 21和Spring Boot 3.2最新特性,通过完整代码示例展示了微服务开发全流程。主要内容包括:1) 使用Spring Initializr初始化项目,集成Web、JPA、H2等组件;2) 配置虚拟线程支持高并发;3) 采用记录类优化DTO设计;4) 实现JPA Repository与Stream API数据访问;5) 服务层整合虚拟线程异步处理和结构化并发;6) 构建RESTful API并使用Springdoc生成文档。文中特别演示了虚拟线程配置(@Async)和StructuredTaskSco
1351 0
|
Kubernetes Cloud Native 开发者
云原生入门:从容器到微服务
本文将带你走进云原生的世界,从容器技术开始,逐步深入到微服务架构。我们将通过实际代码示例,展示如何利用云原生技术构建和部署应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和启示。
|
Kubernetes 关系型数据库 MySQL
Kubernetes入门:搭建高可用微服务架构
【10月更文挑战第25天】在快速发展的云计算时代,微服务架构因其灵活性和可扩展性备受青睐。本文通过一个案例分析,展示了如何使用Kubernetes将传统Java Web应用迁移到Kubernetes平台并改造成微服务架构。通过定义Kubernetes服务、创建MySQL的Deployment/RC、改造Web应用以及部署Web应用,最终实现了高可用的微服务架构。Kubernetes不仅提供了服务发现和负载均衡的能力,还通过各种资源管理工具,提升了系统的可扩展性和容错性。
779 3
|
Cloud Native 持续交付 云计算
云原生入门指南:从容器到微服务
【10月更文挑战第28天】在数字化转型的浪潮中,云原生技术成为推动现代软件开发的关键力量。本篇文章将带你了解云原生的基本概念,探索它如何通过容器化、微服务架构以及持续集成和持续部署(CI/CD)的实践来提升应用的可伸缩性、灵活性和可靠性。你将学习到如何利用这些技术构建和部署在云端高效运行的应用,并理解它们对DevOps文化的贡献。
345 2
|
运维 Cloud Native Android开发
云原生之旅:容器化与微服务架构的融合之道安卓应用开发入门指南
本文将深入探讨云原生技术的核心要素——容器化和微服务架构,并揭示它们如何共同推动现代软件的开发与部署。通过实际案例分析,我们将看到这两种技术如何相辅相成,助力企业实现敏捷、可扩展的IT基础设施。文章旨在为读者提供一条清晰的道路,指引如何在云原生时代利用这些技术构建和优化应用。 本文将引导初学者了解安卓应用开发的基本概念和步骤,从安装开发环境到编写一个简单的“Hello World”程序。通过循序渐进的讲解,让读者快速掌握安卓开发的核心技能,为进一步深入学习打下坚实基础。
345 28
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
JSON Java 数据格式
【微服务】SpringCloud之Feign远程调用
本文介绍了使用Feign作为HTTP客户端替代RestTemplate进行远程调用的优势及具体使用方法。Feign通过声明式接口简化了HTTP请求的发送,提高了代码的可读性和维护性。文章详细描述了Feign的搭建步骤,包括引入依赖、添加注解、编写FeignClient接口和调用代码,并提供了自定义配置的示例,如修改日志级别等。
1209 1
|
监控 API 持续交付
后端开发中的微服务架构:从入门到精通
【10月更文挑战第26天】 在当今的软件开发领域,微服务架构已经成为了众多企业和开发者的首选。本文将深入探讨微服务架构的核心概念、优势以及实施过程中可能遇到的挑战。我们将从基础开始,逐步深入了解如何构建、部署和管理微服务。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的建议。
444 0

热门文章

最新文章