SPRING+OPENFEIGN上传文件报错

SPRING+OPENFEIGN上传文件报错

OPENFEIGN 版本

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

情况一

@FeignClient(url = "http://localhost:8080",configuration = MyConfig.class)
public interface SpringFeignTestInterface {

    @RequestMapping(value = "/upload/{folder}", method = POST)
    public ResponseEntity<UploadInfo> upload(@PathVariable("folder") String folder, @RequestParam("file") MultipartFile file, @RequestParam("metadata") UploadMetadata metadata) ;

}

直接使用 @RequestParam 标注上传文件,不能够正确运行

情况二

@ApiModel("文件上传请求")
public class FileUploadRequest {

	@ApiModelProperty(value = "上传的文件", required = true)
	private MultipartFile file;
    
    private String operator;

}

@FeignClient(url = "http://localhost:8080",configuration = MyConfig.class)
public interface SpringFeignTestInterface {

    @RequestMapping(value = "/upload/{folder}", method = POST)
    public ResponseEntity<UploadInfo> upload(@RequestPart("request") FileUploadRequest request) ;

}

即使是将文件封存在 object 对象中,使用 @RequestPart 标注,也不能运行。这样的结果是只把文件传过去了,与其在一个类中的操作员,并不会随着一起传到文件管理系统。

情况三

@FeignClient(url = "http://localhost:8080",configuration = MyConfig.class)
public interface SpringFeignTestInterface {

    @RequestMapping(value = "/upload/{folder}", method = POST)
    public ResponseEntity<UploadInfo> upload(@RequestPart("folder") String folder, @RequestPart("file") MultipartFile file, @RequestPart("metadata") UploadMetadata metadata) ;

}

fegin 客户端接口使用多个 @RequestPart 标注所有的参数,项目在正确启动、使用过程中,不会出现错误,所有参数也能够正确传输,但是在跑 @Test 单元测试过程中,即使没有调用 FeignClient 中的方法,只是将其注入在 @Service 标注的类中,也会出现错误。具体错误信息如下。

Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract org.springframework.http.ResponseEntity au.com.macquarie.bfs.ml.store.v1.StoreClient.createFile(org.springframework.web.multipart.MultipartFile,java.util.Map)

情况四

@FeignClient(url = "http://localhost:8080",configuration = MyConfig.class)
public interface SpringFeignTestInterface {

    @RequestMapping(value = "/upload/{folder}", method = POST)
    public ResponseEntity<UploadInfo> upload(@PathVariable("folder") String folder, @PathVariable("file") MultipartFile file, @PathVariable("metadata") UploadMetadata metadata) ;

}

标注 @PathVariable ,当被该注解标注的时候,实际 URL 中没有相应的参数,则会被解析为 formParams 参数

情况五

@FeignClient(url = "http://localhost:8080",configuration = MyConfig.class)
public interface SpringFeignTestInterface {

    @RequestMapping(value = "/upload/{folder}", method = POST)
    public ResponseEntity<UploadInfo> upload(@RequestParam("folder") String folder, @RequestPart("file") MultipartFile file, @RequestParam("metadata") UploadMetadata metadata) ;

}

仅在要上传的文件标注 @RequestPart ,其他参数 标注 @RequestParam ,这是目前发现的最合适的办法。

GITHUB 上的示例

githubfeign使用示例.png

注意:

上述的操作都实现了自己 Feign 编码器。使用 feign 默认解析器(JacksonEncoder) 上述好多情况不一定能够复现。

	@Configuration
	public class MyConfig {

		@Autowired
		private ObjectFactory<HttpMessageConverters> messageConverters;

		@Scope("prototype")
		@Primary
		@Bean
		public Encoder feignFormecoder() {
			return new SpringFormEncoder(new SpringEncoder(messageConverters));
		}
	}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×