SpringCloud系列篇:核心组件之声明式HTTP客户端组件【远程消费】

news/2025/3/15 8:14:52/

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于SpringCloud的相关操作吧

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一. 远程消费组件是什么

二. 远程消费组件的详解

场景模拟

代码实操

1.生产者

2.消费者

3.复杂参数的处理

DTO

属性赋值


一. 远程消费组件是什么

        声明式HTTP客户端组件是一种用于简化HTTP请求的编程工具。它通过提供一种声明式的方式来发送HTTP请求,而无需编写繁琐的手动请求代码。声明式HTTP客户端组件通常与特定的编程框架或库一起使用,可以根据预定义的配置和注解来自动生成HTTP请求的代码。这种方式可以提高开发效率,减少错误,并使代码更具可维护性。通过声明式HTTP客户端组件,开发者可以将精力集中在业务逻辑上,而无需过多关注底层的HTTP请求细节。

二. 远程消费组件的详解

场景模拟

当你使用一个电子商务应用程序下订单时,应用程序需要与后端的服务器进行通信以处理你的请求。在这种情况下,声明式HTTP客户端组件可以被用来简化和优化与服务器的通信

假设你正在使用一个购物应用程序,你想要下一份外卖订单。你打开应用程序,并选择你所喜欢的餐厅和菜单项。当你点击"下订单"按钮时,应用程序会使用声明式HTTP客户端组件来发送HTTP请求到后端的服务器。

声明式HTTP客户端组件通过一种声明性的方式来定义和描述HTTP请求的结构和行为。在这个例子中,它会将你的订单信息(如餐厅ID、菜单项ID、送货地址等)转换为一个符合API规范的HTTP请求,并发送给服务器。

服务器收到请求后,会根据请求的内容来处理订单。它可能会验证订单信息、计算价格、生成订单号等。一旦服务器完成订单处理,它会将响应发送回给声明式HTTP客户端组件。

声明式HTTP客户端组件会解析服务器的响应并将其转换为应用程序可以理解的格式。例如,它可能会将响应转换为一个订单确认页面,显示订单的详细信息和预计送达时间。

通过使用声明式HTTP客户端组件,应用程序可以更轻松地与后端服务器进行通信,而无需手动构建和解析HTTP请求和响应。这使得应用程序的开发更加高效和简洁,并提供更好的用户体验。


代码实操

上面的就是一个场景模拟,现在话不多说,我们直接上代码

这里我们使用的是feign这个组件,所以需要导入相应的pom依赖

Feign: Feign是Spring Cloud提供的声明式、模板化的HTTP客户端, 它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

这里使用的例子还是生产者于消费者的例子,谁需要调用远程的服务,那么对应的那个项目的启动类中就需要添加一个注解--@EnableFeignClients 【主要是为开启feign接口扫描】

1.生产者

生产者主要是负责提供接口,其中可以使用以下几个注解接收远程调用的参数值

这里也有一个注意点:只要参数是复杂对象,即使指定了是GET方法,feign依然会以POST方法进行发送请求,同时生产者必 须支持POST请求并给参数添加@RequestBody注解

@PathVariable  路径传参
@RequestParam  多个参数中,指定接收的参数名
@RequestBody   接收复杂的参数类型(比如对象)
package com.provider.main;import com.provider.main.model.User;
import com.wh.common.dto.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;import java.util.Map;@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@RequestMapping("/{name}")public String pathparam(@PathVariable("name")String name) {log.info("name{}",name);return "么么哒";}@RequestMapping("/manyparam")public String manyparam(@RequestParam("name") String name, @RequestParam("pwd") String pwd) {log.info("name{},pwd{}",name,pwd);return "么么哒";}@RequestMapping("/objectparam")public String objectparam(@RequestBody UserDto userDto) {log.info("user{}",userDto);return "么么哒";}@RequestMapping("/copyproperties")public String copyproperties(@RequestBody User user){log.info("user{}",user);return "么么哒";}@RequestMapping("/mapparam")public String mapparam(@RequestBody Map<String, Object> map) {log.info("getByMore: more:" + map);return "provider say : yes";}}

2.消费者

消费者需要开启Feign功能,创建service,并使用Feign表示其需要远程对接的服务名称,

并使用@RequestMapping表示其映射的路径

        在这个feign组件的接口中编写代码时,还需要注意一些点:

  • FeignClient接口,不能使用@GettingMapping之类的组合注解
  • FeignClient接口中,如果使用到@PathVariable必须指定其value
  • 当使用feign传参数的时候,需要加上@RequestParam注解,否则对方服务无法识别参数
package com.consumer.main.service;import com.consumer.main.model.User;
import com.wh.common.dto.UserDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.Map;/*** @author是辉辉啦* @create 2024-01-06-22:18* 负责连接生产者的controller*/
@FeignClient("provider")
public interface FeignUserServise {/*** 路径传参* @param name* @return*/@RequestMapping("user/{name}")String pathparam(@PathVariable("name") String name);/*** 多个参数【指定参数接收名】* @param name* @param pwd* @return*/@RequestMapping("user/manyparam")String manyparam(@RequestParam("name") String name, @RequestParam("pwd") String pwd);/*** 参数是一个对象* @param userDto* @return*/@RequestMapping("user/objectparam")public String objectparam(@RequestBody UserDto userDto);/*** 参数是一个对象--属性复制* @param user* @return*/@RequestMapping("user/copyproperties")public String copyproperties(@RequestBody User user);/*** 参数是一个map集合* @param map* @return*/@RequestMapping("user/mapparam")public String mapparam(@RequestBody Map<String, Object> map);}

3.复杂参数的处理

前面也说到了复杂参数必须使用post请求发送,但这里还有一个点需要注意,我们在写代码时,可能会出现这样的情况:用户的信息需要被多个服务所调用。如果服务少还好说,我们可以直接在相应的服务中编写一个实体类,其中存放我们需要的字段就行了。

DTO

但要是服务多了呢,如果还是这样做的话,好像会很麻烦,所以我们可以直接写一个dto的类,这个dto的类很多模块都可能需要用到,所以我们可以创建一个公共的maven项目,将dto的类写在那个项目中就好了。

然后再将这个项目引入到对应需要使用的项目中便可

DTO:

DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是 为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的 性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象

消费者远程调用生产者 : 需要网络传输,这样就可以使用DTO同一封装对象,就不需要在两个项目中都把用户这个实体类复制过来了

 /*** 参数是一个对象* @param userDto* @return*/@RequestMapping("user/objectparam")public String objectparam(@RequestBody UserDto userDto);
属性赋值

使用了dto拿到值了,也需要将其中的值赋给相应的user对象,这里的话我们可以使用到一个映射框架--Orika

Orika:

Orika是java Bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象。 在开发多层应用程序中非常有用。在这些层之间交换数据时,通常为了适应不同API需要转换一个实例至 另一个实例。

使用它也需要引入相应的依赖

<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.4.6</version>
</dependency>

然后调用相应方法之前就可以做一个复制属性的操作了

 @RequestMapping("/test03")public String test03() {UserDto userDto = new UserDto();userDto.setPwd("root123");userDto.setName("root");userDto.setId(1L);DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();User u = mapperFactory.getMapperFacade().map(userDto, User.class);return feignUserServise.copyproperties(u);}

上面我们说的是属性一致的情况,那可能也会有属性不一样的时候

  @RequestMapping("/test03")public String test03() {UserDto userDto = new UserDto();userDto.setPwd("root123");userDto.setName("root");userDto.setId(2L);DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();mapperFactory.classMap(UserDto.class, User.class).field("name", "account").byDefault().register();User u = mapperFactory.getMapperFacade().map(userDto, User.class);return feignUserServise.copyproperties(u);}

 

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊 


http://www.ppmy.cn/news/1294953.html

相关文章

Java并发集合详解

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;在这篇博客中&#xff0c;咱们将一起深入探索Java中的并发集合。多线程编程是一个不可或缺的部分&#xff0c;它能让程序运行得更快&#xff0c;处理更多的任务。但同时&#xff0c;多线程也带来了一些挑战&…

1688商品详情API:实现商品详情自动化的关键步骤

一、准备工作 在使用1688商品详情API之前&#xff0c;我们需要进行一些准备工作。 注册与登录&#xff1a;首先&#xff0c;你需要在1688的开放平台上注册一个账号并创建一个应用。这样你就可以获得一个API密钥&#xff0c;这是调用API的凭证。阅读API文档&#xff1a;详细阅…

腾讯云取消免费10G CDN流量包:免费CDN时代结束

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 免费送了7-8年的腾讯云10G免费流量包&#xff0c;从2024年开始&#xff0c;停止赠送了!自此&#xff0c;国内绝大多数互联网大厂的CDN都开收费了! 大概从2016年开始&#xff0c;腾讯云为了抢夺CDN客户&#xff0…

搜索二维矩阵 II【矩阵】【二分】

Problem: 240. 搜索二维矩阵 II 文章目录 思路 & 解题方法复杂度暴力二分bisectZ 思路 & 解题方法 暴力、二分、Z 复杂度 时间复杂度: 暴力&#xff1a; O ( m n ) O(mn) O(mn) 二分&#xff1a; O ( m l o g n ) O(mlogn) O(mlogn) Z: O ( m n ) O(m n) O(mn) 空…

(leetcode)替换所有的问号 -- 模拟算法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 本题链接 力扣&#xff08;LeetCode&#xff09; 输入描述 string modifyString(string s) 输入一个字符串&#xff0c;字符串中仅包含小写字母和 ‘?’ 字符。 输出描述 将问号替换为小写字母&#xff0c;且这个替…

网络安全学习资源

好久没写博客了&#xff0c;记录一些宝藏学习资源&#xff0c;不定时更新 Regex Learn - Step by step, from zero to advanced. 这是一个我认为最好的正则表达式学习网站&#xff0c;很多正则表达式学习资料都只提供了一个概念&#xff0c;但是正则表达式需要大量的练习&#…

How to implement anti-crawler strategies to protect site data

How to implement anti-crawler strategies to protect site data 信息校验型反爬虫User-Agent反爬虫Cookie反爬虫签名验证反爬虫WebSocket握手验证反爬虫WebSocket消息校验反爬虫WebSocket Ping反爬虫 动态渲染反爬虫文本混淆反爬虫图片伪装反爬虫CSS偏移反爬虫SVG映射反爬虫字…

HAL——SPI

学习目标 掌握SPI配置方式掌握SPI读写操作 学习内容 需求 SPI配置 打开SPI1,选中全双工模式。观察下方自动生成的引脚&#xff0c;是否和自己开发板引脚对应。 修改引脚&#xff0c;来动右侧芯片引脚视图&#xff0c;找到开发板对应引脚&#xff0c;进行修改。 观察修改后的…