SpringCloud + Nacos环境下抽取Feign独立模块并支持MultipartFile

文章目录

  • 一、前提条件和背景
      • 1. 前提
      • 2. 背景
  • 二、Feign模块
      • 1. 依赖引入
      • 2. `application.yaml`配置
      • 3. 扩展支持MultipartFile
      • 4. 将media-api注册到feign
  • 三、Media模块
  • 四、Content模块
      • 1. 引入依赖
      • 2. 启用FeignClient
      • 3. 测试
  • 五、需要澄清的几点

一、前提条件和背景

1. 前提

已经部署好Nacos,本文以192.168.101.65:8848为例。

2. 背景

有两个微服务mediacontent,都已经注册到Nacos
后者通过引用Feign实现远程调用前者。
两个微服务都被分为3个子模块:api、service、model,对应三层架构。

请根据自身情况出发阅读本文。

二、Feign模块

1. 依赖引入

首先需要Feign依赖和扩展。

 <!--   openfeign     -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-loadbalancer</artifactId>
     <version>4.1.0</version>
 </dependency>
 <dependency>
     <groupId>io.github.openfeign</groupId>
     <artifactId>feign-httpclient</artifactId>
 </dependency>
 <!--feign支持Multipart格式传参-->
 <dependency>
     <groupId>io.github.openfeign.form</groupId>
     <artifactId>feign-form</artifactId>
     <version>3.8.0</version>
 </dependency>
 <dependency>
     <groupId>io.github.openfeign.form</groupId>
     <artifactId>feign-form-spring</artifactId>
     <version>3.8.0</version>
 </dependency>

需要测试依赖(可选),为了MockMultipartFile类才引入的,非必需功能。

<!--    测试    -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>6.1.2</version>
	<scope>compile</scope>
</dependency>

其次需要涉及到的微服务的数据模型,根据个人情况而定。

如果只想要它们的数据模型,而不引入不必要的依赖,可以使用通配符*全部过滤掉。

 <!--   数据模型pojo     -->
 <dependency>
     <groupId>com.xuecheng</groupId>
     <artifactId>xuecheng-plus-media-model</artifactId>
     <version>0.0.1-SNAPSHOT</version>
	     <exclusions>
	          <exclusion>
	              <groupId>*</groupId>
	              <artifactId>*</artifactId>
	          </exclusion>
	      </exclusions>
 </dependency>
 <dependency>
     <groupId>com.xuecheng</groupId>
     <artifactId>xuecheng-plus-content-model</artifactId>
     <version>0.0.1-SNAPSHOT</version>
	     <exclusions>
	         <exclusion>
	             <groupId>*</groupId>
	             <artifactId>*</artifactId>
	         </exclusion>
	     </exclusions>
 </dependency>

2. application.yaml配置

填入以下内容,大抵为超时熔断处理。(可选),甚至可以留空。

feign:
  hystrix:
    enabled: true
  circuitbreaker:
    enabled: true
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000
ribbon:
  ConnectTimeout: 60000
  ReadTimeout: 60000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 1

3. 扩展支持MultipartFile

新建一个配置类,如下,
主要是Encoder feignEncoder()使得Feign支持MultipartFile类型传输。
MultipartFile getMultipartFile(File file)是一个工具方法,和配置无关。

@Configuration
public class MultipartSupportConfig {

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Bean
    @Primary//注入相同类型的bean时优先使用
    @Scope("prototype")
    public Encoder feignEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }

    //将file转为Multipart
    public static MultipartFile getMultipartFile(File file) {
        try {
            byte[] content = Files.readAllBytes(file.toPath());
            MultipartFile multipartFile = new MockMultipartFile(file.getName(),
                    file.getName(), Files.probeContentType(file.toPath()), content);
            return multipartFile;
        } catch (IOException e) {
            e.printStackTrace();
            XueChengPlusException.cast("File->MultipartFile转化失败");
            return null;
        }
    }
}

4. 将media-api注册到feign

新建一个类,如下。
@FeignClient(value)要和服务名称对上,即media模块spring.application.name=media-api
@FeignClient(path)要和服务前缀路径对上,即media模块server.servlet.context-path=/media
然后MediaClient中的方法定义尽量和media模块对应的controller函数保持一致。

@FeignClient(value = "media-api", path = "/media")
public interface MediaClient {

    @RequestMapping(value = "/upload/coursefile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public UploadFileResultDto upload(
            @RequestPart("filedata") MultipartFile file,
            @RequestParam(value = "objectName", required = false) String objectName
    );
}

三、Media模块

被调用方media模块无需做什么修改。

四、Content模块

测试在content-api上操作。

1. 引入依赖

content模块需要引入刚才feign模块的依赖。

<dependency>
   <!-- 根据自身情况引入 -->
</dependency>

2. 启用FeignClient

在启动类上加上@EnableFeignClients注解。

3. 测试

新建测试类,如下

package com.xuecheng.content.service.jobhandler;

import com.xuecheng.feign.client.MediaClient;
import com.xuecheng.media.model.dto.UploadFileResultDto;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

@SpringBootTest
class CoursePublishTaskTest {
    @Autowired
    MediaClient mediaClient;

    @Test
    void generateCourseHtml() {
        MultipartFile file = new MockMultipartFile(
                "filedata",
                "filename.txt",
                "text/plain",
                "Some dataset...".getBytes()
        );
        UploadFileResultDto upload = mediaClient.upload(file, "/static-test/t-1");
        System.out.println(upload);
    }
}

启动Media模块,启动测试方法,
具体的Debug和检验,可以通过Media模块对应的controller函数打印日志,检查是否通过MediaClient 被触发。

五、需要澄清的几点

  1. Feign模块不需要注册到Nacos且不需要服务发现
    正确。feign-client模块只是一个包含Feign客户端接口的库,它自身并不是一个独立的微服务。因此,它不需要注册到Nacos,也不需要服务发现功能。这个模块只是被其他微服务模块(如content模块)作为依赖引入。这样做的主要目的是为了代码的重用和解耦,允许任何微服务通过引入这个依赖来调用其他服务。

  2. 只有调用者(如content模块)需要使用@EnableFeignClients注解,被调用者(如media模块)不需要
    正确。@EnableFeignClients注解是用来启用Feign客户端的,它告诉Spring Cloud这个服务将会使用Feign来进行远程服务调用。因此,只有需要使用Feign客户端的服务(在这个例子中是content模块)需要添加这个注解。而被调用的服务(如media模块),只需作为普通的Spring Boot应用运行,提供REST API即可,无需使用@EnableFeignClients

  3. 如何在服务间共享数据模型(如DTOs)而不引入不必要的依赖。
    解决这个问题的一种方法是创建一个共享的库或模块,这个库包含所有服务共享的数据模型。另一种使用依赖剥离,使用通配符(*)可以排除pom.xml中特定依赖的所有传递性依赖。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计组学习笔记2024/2/5

记录每天学到了什么,同时在挪移图片过程中再次理解加深印象 学计算机最重要的是理解,而不是整齐的笔记,不要主次搞混,所以以后记笔记的模式也要改一下(主要还是自己太菜,还达不到一边做到整齐笔记的同时还能够有时间做到理解,所以只能舍弃整齐时间保留理解时间)(不过如果有现成…

JDK和Spring的SPI机制原理分析

目录 一、JDK 二、Spring框架介绍 三、SPI机制原理 一、JDK JDK是Java Development Kit的缩写&#xff0c;是Java开发工具包的意思。它是用于开发Java应用程序和运行Java程序的软件包。JDK包含了Java编译器&#xff08;javac&#xff09;和Java虚拟机&#xff08;JVM&#…

SpringBoot实战第二天

今日战报 继续完善用户相关接口开发&#xff1a; 1.完成获取用户信息功能 2.完成更新用户信息功能 3.完成更新用户头像功能 4.完成更新用户密码功能 获取用户信息 接口文档 如接口文档所示&#xff0c;我们需要做的就是从header中的Authorization中读取token&#xff0c;解码…

浅谈QT的几种线程的使用和区别。

简介&#xff1a; 线程是操作系统中的基本执行单元&#xff0c;是一个独立的执行路径。每个线程都有自己的栈空间&#xff0c;用于存储本地变量和函数调用的上下文。多个线程可以在同一进程中并发执行&#xff0c;从而实现并发处理&#xff0c;提高程序的性能和响应能力。 与进…

Unet 实战分割项目、多尺度训练、多类别分割

1. 介绍 之前写了篇二值图像分割的项目&#xff0c;支持多尺度训练&#xff0c;网络采用backbone为vgg的unet网络。缺点就是没法实现多类别的分割&#xff0c;具体可以参考&#xff1a;二值图像分割统一项目 本章只对增加的代码进行介绍&#xff0c;其余的参考上述链接博文 本…

追觅发布多款旗舰新品,双机械臂扫地机器人X40领衔登场

2月2日&#xff0c;追觅科技全球首创仿生“双”机械臂新品发布会在苏州举行。会上&#xff0c;追觅科技中国区总裁郭人杰分享了追觅科技全球化发展的业绩成果。郭人杰称&#xff0c;2019-2023年&#xff0c;追觅科技5年复合年增长率超过100%&#xff0c;增速领跑智能清洁行业&a…

JAVA中的代码块

一、基本语法 [修饰符]{代码; }; {System.out.println(111); } 1.修饰符可选&#xff0c;要写的话也只能写static2.代码块分为两类 使用static修饰的是静态代码块 没有static修饰的叫普通代码块3.逻辑语句可以为任何逻辑语句4.;可以不写 1)静态代码块 作用是对类进行初始化…

SpringBoot源码解读与原理分析(十八)启动SpringApplication逻辑分析

文章目录 6.2 启动SpringApplication6.2.1 前置准备6.2.1.1 计时器对象的使用6.2.1.2 awt的设置6.2.1.3 对比SpringBoot 2.0.x-2.2.x6.2.1.4 对比SpringBoot 2.4.x 6.2.2 获取SpringApplicationRunListeners6.2.2.1 EventPublishingRunListener6.2.2.2 与其他版本的对比 6.2.3 …

TP框架 之think-auth权限认证

一、安装think-auth composer require 5ini99/think-auth二、数据表 -- ---------------------------- -- think_auth_rule&#xff0c;规则表&#xff0c; -- id:主键&#xff0c;name&#xff1a;规则唯一标识, title&#xff1a;规则中文名称 status 状态&#xff1a;为1正常…

我在代码随想录|写代码Day26 |回溯算法|332. 重新安排行程 , 51. N皇后 , 37. 解数独

学习目标&#xff1a; 博主介绍: 27dCnc 专题 : 数据结构帮助小白快速入门 &#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d; ☆*: .&#xff61;. o(≧▽≦)…

私域市场如何突破?解锁高效转化的三个核心要素!

一、私域电商三要素 一是私域、二是社交、三是电商。 私域就是承载用户的地方&#xff0c;比如微信&#xff0c;然后做好私域运营。 社交就是通过内容触达用户于用户建立社交关系。 电商就是通过私域卖产品给用户。 私域电商有几个公式&#xff1a; 社交红利信息关系链互…

redis(6)

文章目录 一、redis clusterRedis Cluster 工作原理Redis cluster 基本架构Redis cluster主从架构Redis Cluster 部署架构说明部署方式介绍 原生命令手动部署原生命令实战案例&#xff1a;利用原生命令手动部署redis cluster 实战案例&#xff1a;基于Redis 5 的redis cluster部…

Nicn的刷题日常之获得月份天数

目录 1.题目描述 描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 2.解题 1.题目描述 描述 KiKi想获得某年某月有多少天&#xff0c;请帮他编程实现。输入年份和月份&#xff0c;计算这一年这个月有多少天。 输入描述&#xff1a; 多组输入&#xff0c;一行有两…

外包干了10个月,技术退步明显...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

如何把大容量10G的文件分享给别人?整理了3个简单的方法~

如果文件过大&#xff0c;比如10G的文件发送起来简直问题重重&#xff0c;不仅费时费流量而且还很可能在发送的中途失败&#xff0c;这时候就需要借助一些压缩软件对文件进行压缩&#xff0c;下面就向大家介绍3个好用的压缩软件~ 方法一&#xff1a;使用嗨格式压缩大师压缩后发…

深入理解Java中的二叉树

目录 一、什么是二叉树? 二、二叉树的主要类型 三、二叉树的实现 四、二叉树的应用 五、关于二叉树的题目 引言: 二叉树是计算机科学中常用的一种数据结构&#xff0c;它是由节点组成的层级结构&#xff0c;每个节点最多有两个子节点。在Java编程语言中&#xff0c;二…

架构学习(三):scrapy-redis源码分析并实现自定义初始请求

scrapy-redis源码分析并实现自定义初始请求 前言关卡&#xff1a;如何自定义初始请求背景思考简单又粗暴的方式源码分析 结束 前言 通过这篇文章架构学习(二)&#xff1a;原生scrapy如何接入scrapy-redis&#xff0c;初步入局分布式&#xff0c;我们正式开启scrapy-redis分布式…

C语言递归与迭代并举:双重视角下的C语言阶乘计算实现

引言 计算一个正整数的阶乘是常见的数学问题。阶乘的定义为&#xff1a;n的阶乘&#xff08;记作n!&#xff09;是所有小于及等于n的正整数的乘积。例如&#xff0c;5的阶乘&#xff08;5!&#xff09;就是54321120。下面我们将通过一个使用递归方法实现阶乘的C语言代码示例&am…

Qt|实现时间选择小功能

在软件开发过程中&#xff0c;QtDesigner系统给出的控件很多时候都无法满足炫酷的效果&#xff0c;前一段时间需要用Qt实现选择时间的小功能&#xff0c;今天为大家分享一下&#xff01; 首先看一下时间效果吧&#xff01; 如果有需要继续往下看下去哟~ 功能 1&#xff1a;开…

linux 05重定向和管道管理

01.重定向 例子&#xff1a; 关键字 > date 中的数据要写入 887.txt 02.FD 进程的句柄文件 进程的信息的传输&#xff1a; porcess 会有 0 号文件来接收键盘的信息 1 号文件 向终端 来输出信息 FD文件存储在proc文件中&#xff0c;可以看看 举个例子&#xff1a; 查看pro…