Fein调用接口报错feign.FeignException: status 404 reading BrandClient#queryBrandById(Long); content:

Feign调用微服务接口问题解决

问题描述

在微服务开发中,我们会用到Fein调用公共api接口,但是在调用的时候难免会出现错误,如:

feign.FeignException: status 404 reading BrandClient#queryBrandById(Long); content:

调用后去查看微服务的提供方的控制台日志数据,发现,请求已经通过网关到达了微服务的提供方,并且数据库中也有查询的相关数据,但是接口调用方却怎么也接收不到返回值。排查了路径,注解,参数,函数,接口…最终还是没能请求到数据:

分析

微服务提供方接口api:
在这里插入图片描述
消费者消费:
在这里插入图片描述
在这里插入图片描述
既然消费者的请求已经到达了微服务提供方,不用怀疑,消费者是不会有问题的,肯定是在微服务提供方。

解决方案

既然确定了问题是在微服务提供者,此时我们就可以去微服务提供方对应模块排查。
微服务提供方自测controller控制器:

import com.xjitcm.PageResult;
import com.xjitcm.SaleSysItemServiceApplication;
import com.xjitcm.controller.BrandController;
import com.xjitcm.pojo.Brand;
import com.xjitcm.utils.JsonStrToMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;

import java.util.Map;
@SpringBootTest(classes = SaleSysItemServiceApplication.class)
public class TestBrandController {
    BrandController brandController = new BrandController();
    @Test
    public void testBrandController(){
        Brand brand = brandController.queryBrandById(1527L);
    }

}

测试仍然没有通过,依然是请求到达,查询到了数据,但是无返回值:
在这里插入图片描述
此时我们就明白了,问题就在控制器层(controller),在ssm架构中,我们的控制器返回的是视图,但是在微服务架构开发中,控制器返回的不能再是视图了,而是一些数据(返回JSON,状态码等)。
因此,我们需要重新配置控制层,将控制层设置为可以返回数据,而不是视图。在ssm架构中开发时候,通常我们为了返回视图,在控制层我们使用的是@Controller注解,在微服务架构中我们要做的就是将@Controller注解替换为@RestController,这样就完成了我们的需求,返回数据。
注意:
api接口的注解和控制层的注解都要使用@RestController,否则,消费者调用接口无法拿到数据,本人就是在这个地方糊涂了。
在这里插入图片描述

@RestControlle与@Controller

参考的博文地址
@RestController注解相当于@ResponseBody + @Controller合在一起的作用。
如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。
注意:在controller类中,添加RestController后后台不能重定向页面,如果需要重定向页面,则需要使用Controller,在需要返会数据的方法上添加@ResponseBody

<think>嗯,用户的问题是关于在后端使用Feign调用文件上传接口时,如何将文件流转换为MultipartFile进行传输。我需要结合他们提供的引用内容来给出解决方案。首先,用户提到了几个引用,其中引用1和2展示了如何将Workbook和File转换为MultipartFile,而引用3讨论了Feign的配置。 用户的需求是处理文件流到MultipartFile的转换,并在Feign中使用。首先,我需要考虑文件流的来源。可能的情况是用户有一个文件流,比如从上传请求中获取的InputStream,或者从其他来源读取的字节流。接下来,如何将这个流包装成MultipartFile是关键步骤。 根据引用1中的代码,使用DiskFileItemFactory创建FileItem,然后通过输出流写入数据,最后转换为CommonsMultipartFile。这可能是一个可行的方法。同样,引用2中的例子也类似,使用FileItem来处理文件内容,并生成MultipartFile。不过,用户提到的是文件流,而不是具体的文件或Workbook。因此,需要将输入流的内容写入到FileItem的输出流中。例如,读取文件流的字节,并写入到FileItem的OutputStream,这样就可以生成对应的MultipartFile。另外,Feign的文件上传需要正确配置Multipart支持。引用3中的配置类添加了CommonsMultipartResolver,这可能需要在Spring Boot应用中配置,以确保正确处理multipart请求。同时,Feign客户端需要使用@RequestPart注解,并设置正确的consumes类型为MediaType.MULTIPART_FORM_DATA_VALUE,这样才能正确传输文件。还需要注意Feign的依赖,确保引入了feign-form模块,否则可能无法处理multipart/form-data的编码。比如,添加feign-form和feign-form-spring的依赖。可能的问题点包括:FileItem的参数名称是否与接口参数一致,流是否正确关闭,以及Feign的配置是否正确。比如,在创建FileItem时,第一个参数需要与服务端接口的@RequestParam名称匹配,否则会导致接收不到文件。 另外,异常处理也很重要,比如在读写流时可能出现的IOException,需要进行捕获和处理,确保资源被正确释放。例如,使用try-with-resources来自动关闭流,避免资源泄漏。 总结步骤应该是:1. 将文件流转换为MultipartFile,使用DiskFileItemFactory和FileItem。2. 配置Feign支持multipart请求,包括添加解析器和依赖。3.Feign客户端接口中正确使用@RequestPart注解。4. 处理异常和资源管理,确保流的正确关闭。 可能还需要提醒用户注意文件流的来源,例如是否是临时文件,是否需要考虑并发情况下的线程安全,或者大文件处理时的内存问题。例如,使用临时文件来缓存流数据,避免内存溢出。 最后,验证整个流程是否可行,比如编写测试用例,通过Feign客户端调用上传接口,确保文件正确传输,并且服务端能够接收到MultipartFile参数。</think>### 分步实现Feign文件流转换为MultipartFile传输 #### 一、核心实现步骤 1. **文件流转换为MultipartFile** 使用`DiskFileItemFactory`创建临时文件项,将输入流写入输出流: ```java public static MultipartFile inputStreamToMultipartFile(InputStream inputStream, String fileName) throws IOException { DiskFileItemFactory factory = new DiskFileItemFactory(); FileItem item = factory.createItem("file", MediaType.APPLICATION_OCTET_STREAM_VALUE, true, fileName); try (OutputStream os = item.getOutputStream(); InputStream is = inputStream) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } } return new CommonsMultipartFile(item); } ``` - `createItem`第一个参数`"file"`需与服务端接口参数名一致[^2] - 使用try-with-resources确保流自动关闭 2. **Feign客户端接口配置** ```java @FeignClient(name = "file-service") public interface FileUploadClient { @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) ResponseEntity<String> uploadFile(@RequestPart("file") MultipartFile file); } ``` - 必须声明`consumes = MULTIPART_FORM_DATA_VALUE`[^3] #### 二、必选配置项 1. **Spring Boot配置类** ```java @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) public CommonsMultipartResolver multipartResolver() { return new CommonsMultipartResolver(); } ``` 2. **Maven依赖** ```xml <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> ``` #### 三、实际应用场景 ```java @RestController public class FileController { @Autowired private FileUploadClient fileUploadClient; @PostMapping("/upload") public String handleFileUpload(@RequestParam("file") MultipartFile file) { try (InputStream is = file.getInputStream()) { MultipartFile convertedFile = inputStreamToMultipartFile(is, file.getOriginalFilename()); return fileUploadClient.uploadFile(convertedFile).getBody(); } } } ``` #### 四、注意事项 1. **性能优化** - 大文件建议使用临时文件缓存: ```java File tempFile = Files.createTempFile("upload", ".tmp").toFile(); try (FileOutputStream fos = new FileOutputStream(tempFile)) { IOUtils.copy(inputStream, fos); } ``` 2. **常见错误** - 参数名不一致导致接收null:确保`@RequestPart("file")`与`createItem`第一个参数匹配 - 流未关闭导致内存泄漏:必须使用try-with-resources - 缺少feign-form依赖导致编码失败
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xjitcm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值