远程服务调用的简单应用,并轻松解决LinkedHashMap无法转成相关实体类的问题

news2025/1/12 8:39:21

🏀(一)为啥需要远程服务调用?

    🐠知其然还要知其所以然,在我们的生产项目上一般而言会部署多个微服务,每个微服务会负责不同版块的业务工作。如果某个微服务需要借助另外的某些微服务中的接口才能完成相应操作时,那么服务与服务之间就会存在相互调用的情况,远程服务调用因此油然而生!例如:跨数据库调用、设备对接等业务功能。

🏀(二)如何远程服务调用?

    🐠大伙开始接项目做的时候,都是单体项目开始做起的,也就是我们所说的SpringBoot框架,搞懂这个后才慢慢介入到微服务架构,也就是SpringCloud。SpringCloud简单点说就是多个SpringBoot拼凑而成的大家庭,搞懂了单体,多个微服务架构也就不解自通了。

    🐠每个服务相关的接口流程就过多的阐述了,如果不清楚的小伙伴可以移步到我在此之前所撰写的简单开发的博文,这个基于SpringBoot_后端接口流程里面有详细的介绍。下面将通过相关项目实例介绍如何远程服务调用

💌(1)创建新的应用模块

    🍑为了将所有跨远程服务调用的流程集中性进行管理,那么新开一个应用模块相当有必要,在新开应用模块下汇集所有的远程服务及相关的实体类、服务熔断降级类及自动配置文件等。如下图所示:
在这里插入图片描述

💌(2) 创建远程服务

    🍑创建远程服务的过程,其实就是将自己在某个服务中撰写的接口挪过来放在新开应用模块下的某个Service下即可,而需要注意的点便是:@FeignClient注解中要写明所对应的相关服务,以及“熔断降级”fallbackFactory所指明的类。

/**
 * @InterfaceName: RemoteReportService
 * @Description:
 * @Author: YuHao
 * @Date: 2023/06/07
 */
@FeignClient(contextId = "remoteReportService", value = "***相关应用服务名称", fallbackFactory = RemoteReportFallbackFactory.class)
public interface RemoteReportService {

  
    @GetMapping("/clickReport/getRoadSectionTrafficReport")
    R getRoadSectionTrafficReport(@RequestParam("beginDate") String beginDate, @RequestParam("endDate")String endDate,
                                                               @RequestParam("directionList") List<String> directionList, @RequestParam("roadSectionNameList")List<String> roadSectionNameList);

    @GetMapping("/sa/getMainLineAndServiceAreaFlow")
    R getMainLineAndServiceAreaFlow(@RequestParam("beginDate") String beginDate,@RequestParam("lineYearBeginDate") String lineYearBeginDate,@RequestParam("lineAllBeginDate") String lineAllBeginDate, @RequestParam("endDate")String endDate,@RequestParam("deviceIps") List<String> deviceIps,@RequestParam("gantryIds") List<String> gantryIds);

}

💌(3)创建服务熔断降级工厂类

    🍑这一步的过程是防止某个被调取的服务挂掉了之后,去调用的服务还在不停地发送请求,进而发生雪崩等情况的出现。当服务请求不到时,该类的创建能发挥关键作用,查询相关日志也能及时发现报错点的位置。

/**
 * @ClassName: RemoteReportFallbackFactory
 * @Description:
 * @Author: YuHao
 * @Date: 2023/06/07
 */
@Component
@Slf4j
public class RemoteReportFallbackFactory implements FallbackFactory<RemoteReportService> {

    @Override
    public RemoteReportService create(Throwable cause) {

        log.error("***报表获取暂无:{}", cause.getMessage());

         return new RemoteReportService() {
             @Override
             public R getRoadSectionTrafficReport(String beginDate, String endDate, List<String> directionList, List<String> roadSectionNameList) {
                 return R.fail("****报表获取失败:" + cause.getMessage());
             }

             @Override
             public R getMainLineAndServiceAreaFlow(String beginDate,String beginYearLineDate,String beginAllLineDate, String endDate, List<String> deviceIps, List<String> gantryIds) {
                 return R.fail("****报表获取失败:" + cause.getMessage());
             }

         };

    }
}

💌(4)spring.factories配置

    🍑spring.factories 配置文件是将 SpringBoot 包以外的 Bean注册到 SpringBoot 的 spring 容器中。由于SpringBoot中的@Compone
ntScan 注解只能扫描 SpringBoot包内的 Bean 并注册到 spring 容器中,因此需借助org.springframework.boot.autoconfigure.EnableAutoConfi
guration来注册SpringBoot包外的Bean。而 spring.factories 配置文件,则是用来记载SpringBoot包外需要注册的Bean的相关类名称。这个配置文件常常容易被忽视,刚开始使用的时候,本人也常未将需要注册的类配置进来,导致我需要服务发现不了,导致远程服务不生效。所以当前面的三个步骤完成以后,记得需要手动将需要的类型配置进来。案例配置如下图所示:
在这里插入图片描述

💌(5)远程服务调用

    🍑在本服务中远程调用其他的指定服务,使用@Resource或者@Autowired自动注入即可使用到指定服务的相关接口,而相关的调用过程如下实例所示,拿到返回的结果数据再进行相关的业务处理即可完成此服务模块Service层的撰写。

	//相关业务代码操作已省略...
	@Resource/@Autowired
    private RemoteReportService remoteReportService;

 	R<List<RoadSectionTrafficRep>> r = remoteReportService.getRoadSectionTrafficReport(beginDate, endDate, directionList, roadSectionNameList);

🏀(三)解决LinkedHashMap无法转成相关实体类的问题

    🥘LinkedHashMap无法转成相关实体类,其实这个问题一般是会在远程调用服务中出现得较多,可能因为返回格式等问题导致最终无法转成我们所需的数据类型格式。

    🥘第一需要声明好所返回的实体类,也就是说我们在R中要注明好泛型,不然程序可能不好定位返回的格式是什么类型的数据。

    🥘第二参考Alibaba fastjson开源库,前后端接口联调少不了的就是借用json来打交道,因为json是公认的标准的数据交换格式,fastjson将常用的转换分析方式基本都包含(神器推荐!!!),相关分析转换方法如下实例代码所示:

public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray

public static final JSONObject parseObject(String text)// 把JSON文本parse成JSONObject 
    
public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean 

public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray 

public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合 

public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本 

public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本 

public static final Object toJSON(Object javaObject); //将JavaBean转换为JSONObject或者JSONArray。

    🥘在返回参数中写明泛型实体类,并参考fastjson开源库中相关的分析转换方法,即可快速解决此类问题,相关实例代码如下所示:

	@Override
    public List<RoadSectionTrafficRep> getRoadSectionTraffic(String beginDate, String endDate, List<String> directionList, List<String> roadSectionNameList) {
        R<List<RoadSectionTrafficRep>> r = remoteReportService.getRoadSectionTrafficReport(beginDate, endDate, directionList, roadSectionNameList);
        List<RoadSectionTrafficRep> list = r.getData();
        //list转成字符串
        String jsonObject = JSON.toJSONString(list);
        //json字符串再转成实体类
        List<RoadSectionTrafficRep> roadSectionTrafficRepList = JSON.parseArray(jsonObject, RoadSectionTrafficRep.class); //把JSON文本parse成JavaBean集合 
        return roadSectionTrafficRepList;                       
    }

🍆🍆🍆路过的小伙伴,如果本篇博文对你的学习或者工作有所帮助,可以点赞+收藏+关注一波呀~👊👊👊小编后续每过一段时间会整理出相关项目实例的博文,感谢您的支持哦!!!✈️✈️✈️
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/620776.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

尚硅谷甄选

搭建后台管理系统模板 项目初始化 今天来带大家从0开始搭建一个vue3版本的后台管理系统。一个项目要有统一的规范&#xff0c;需要使用eslintstylelintprettier来对我们的代码质量做检测和修复&#xff0c;需要使用husky来做commit拦截&#xff0c;需要使用commitlint来统一提…

tb6612电机驱动与JGB37-520减速直流电机

tb6612电机驱动与JGB37-520减速直流电机 文章目录 tb6612电机驱动与JGB37-520减速直流电机电机驱动模块TB6612TB6612的引脚说明真值表&#xff08;直流电机的驱动状态&#xff09;TB6612的正转反转原理 直流电机原理减速器编码器一、关于编码器的介绍二、编码器的工作原理&…

Linux:DHCP服务

我的DHCP服务器 是 centos7 使用的yum安装DHCP服务&#xff08;如果不会搭建yum库可以查看&#xff09; Linux&#xff1a;rpm查询安装 && yum安装_鲍海超-GNUBHCkalitarro的博客-CSDN博客 我的环境为&#xff1a; 两台centos7一台win10 第一台centos7 为 DHCP服务器…

【Python 私有变量和私有方法】零基础也能轻松掌握的学习路线与参考资料

Python是一种面向对象的编程语言。在Python类中&#xff0c;私有变量和私有方法是常见的概念。私有变量和私有方法是指只能在类内部访问的变量和方法。在本文中&#xff0c;我们将介绍Python私有变量和私有方法的学习路线&#xff0c;并给出参考资料和优秀实践。 学习Python面…

【MySQL数据库 | 第七篇】图形化界面工具DataGrip基础应用教学

目录 前言&#xff1a; DataGrip安装界面&#xff1a; 利用DataGrip创建数据库&#xff1a; 利用DataGrip为数据库创建表&#xff1a; 利用datagrip修改表&#xff1a; 添加元素&#xff1a; 结束&#xff01; 前言&#xff1a; 在之前我们一直接触的是MySQL命令行语句开…

macOS Sonoma 14beta With OpenCore 0.9.3 and winPE双引导分区黑苹果原版镜像

镜像特点&#xff08;原文地址&#xff1a;http://www.imacosx.cn/113888.html&#xff09; 完全由黑果魏叔官方制作&#xff0c;针对各种机型进行默认配置&#xff0c;让黑苹果安装不再困难。系统镜像设置为双引导分区&#xff0c;全面去除clover引导分区&#xff08;如有需要…

RL - 强化学习 马尔可夫决策过程 (MDP) 转换 马尔可夫奖励过程 (MRP)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131097165 马尔可夫决策过程&#xff08;Markov Decision Process&#xff0c;MDP&#xff09;和马尔可夫奖励过程&#xff08;Markov R…

FluxMQ 规则引擎 《一》

规则引擎介绍 演示环境 http://demo.fluxmq.com:50000/ 账号&#xff1a;fluxmq密码&#xff1a;fluxmq 简介 FluxMQ Rule Engine (以下简称规则引擎) 用于配置FluxMQ 消息流与设备事件的处理、响应规则。规则引擎不仅提供了清晰、灵活的 “配置式” 的业务集成方案&#xff0…

(二)CSharp-关于内存分配的总结和疑惑(未解决)

同时看了好几本书&#xff0c;对变量的内存分配概念总是稀里糊涂的。所以干脆专门写一篇文章来对C#内存分配进行研究和总结。 1、值类型和引用类型 对值类型&#xff1a; 值类型实例通常存在线程的堆栈里。即所有值类型的非成员数据都放在线程的堆栈里。如果值类型是类的数据…

4.使用Express跨域资源共享(继上一章)

4.5、CORS跨域资源共享 1.接口的跨域问题 刚才编写的GET和POST接口&#xff0c;存在一个很严重的问题&#xff1a;不支持跨域请求。 解决接口跨域问题的方案主要有两种&#xff1a; ①CORS&#xff08;主流的解决方案&#xff0c;推荐使用&#xff09; ②JSONP&#xff08…

Windows软件架构概念

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来聊聊Windows软件架构的概念。 Shaw和Garlan在他们划时代的著作中以如下方式讨论了软件的体系结构&#xff1a;从第一个程序被划分成模块开始&#xff0c;软件系统就有了体系结构。现在&#xff0c…

PostgreSQL部署出现只有超级用户能创建扩展

最近在Windows Server服务器上部署PostgreSQL12遇到了一个问题,部署完成时,任务问题都没有,也可以远程连接。但是在给数据库添加扩展时出现了如下所述的问题: 执行sql命令create extension "uuid-ossp"出现问题如下:create extension “uuid-ossp” 错误: 创建扩…

文心一言 VS 讯飞星火 VS chatgpt (34)-- 算法导论5.3 1题

一、Marceau 教授不同意引理 5.5 证明中使用的循环不变式。他对第1次送代之前循环不变式是否为真提出质疑。他的理由是&#xff0c;我们可以很容易宣称一个空数组不包含0排列。因此一个空的子数组包含一个0排列的概率应是 0&#xff0c;从而第 1次选代之前循环不变式无效。请重…

Python3+Selenium2完整的自动化测试实现之旅(三):Selenium-webdriver提供的元素定位方法

目录 前言 前端技术名词解释 Selenium-webdriver定位元素 一、 通过id定位 二、通过name定位 三、通过class定位 四、 通过tag定位 五、 通过link定位 六、通过partial_link定位 七、 通过Xpath定位 八、通过CSS定位 总结 前言 本篇以实例介绍selenium下的webdriv…

mysql数据库备份文件回复的方法

备份数据表的恢复 前提配置 关闭防火墙 systemctl stop firewalld iptables -F setenforce 0 安装了mysql数据库 以下列库表为例 先有一个数据库mydb&#xff0c;包含两个数据表customer,timestamps; 其中customer数据表包含数据如下&#xff1a; 备份数据表的回复 第一步…

回溯算法之深度优先搜索

目录 放牌 员工的重要性 图像渲染 岛屿的周长 被围绕的区域 岛屿的数量 岛屿的最大面积 电话号码的字母组合 二进制手表 组合总和 活字印刷 N皇后 深度优先搜索&#xff08;Depth First Search&#xff09;------ 一条道走到黑 放牌 假如有编号为1~3的3张扑克牌…

cpython编译与运行

一.配置环境 python 本身不能运行 cpython 的语法&#xff0c;需要 编译 后引用 需要 gcc 编译器 和 cython 编译器 gcc编译器 把 c语言 编译成扩展模块 Cython 编译器是一种源到源的编译器 python 语法编译成 c语法 1.安装gcc 编译器 gcc 编译器可以下载 Visual Studio 或者…

Android系统的启动流程(一):进入Zygote进程的初始化

Android系统的启动流程 概要 本篇文章主要是从Android系统启动电源开始介绍到程序运行到Java框架层并且完成Zygote进程的启动为止。下面先给出一张简单的概要图&#xff0c;本篇文章将会从源码进行分析Android的部分启动流程&#xff0c;这里的源码来自于AndroidCodeSearch,截…

基于RK3588的人工智能边缘计算大算力网关

智能运维系统从下至上分为终端层、边缘层、平台层和应用层&#xff0c;如图 1 所示。终端层 是整个系统的神经末梢&#xff0c;负责现场数据的采集&#xff0c;除摄像机外&#xff0c;还包括各类传感器、控制器 等物联网设备。边缘层汇总各个现场终端送来的非结构化视频数据和…

BERT(Transformer Encoder)详解和TensorFlow实现(附源码)

文章目录 一、BERT简介1. 模型2. 训练2.1 Masked Language Model2.2 Next Sentence Prediction2.3 BERT的输出 3. 微调 二、源码1. 加载BERT模型2. 加载预处理模型3. 加载BERT4. 构建BERT微调模型5. 训练6. 推理 一、BERT简介 1. 模型 BERT的全称为Bidirectional Encoder Repr…