SpringCloud微服务服务间调用之OpenFeign介绍(一)
SpringCloud微服务服务间调用之OpenFeign介绍(二) 启用fallback机制
SpringCloud微服务服务间调用之OpenFeign介绍(三) timeout问题
注意事项:本博客所有代码是为了介绍相关内容而编写或者引用的,示例代码并非可直接用于生产的代码。仅供参考而已。
前面三篇介绍FeignClient的各种主要功能,今天介绍一下如何通过FeignClient上传文件
完成的FeignClient代码在这里, 我们需要一个服务file-service提供一个接口上传文件(代码在这里)。下面的介绍以FeignClent端为主。 文件服务提供方不再赘述。
1, 新增加的依赖
<dependency>
<groupId>io.github.openfeign.formgroupId>
<artifactId>feign-form-springartifactId>
<version>3.2.2version>
dependency>
<dependency>
<groupId>io.github.openfeign.formgroupId>
<artifactId>feign-formartifactId>
<version>3.2.2version>
dependency>
2, 配置feignFormEncoder bean
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignFormEncoder(){
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
3,生成或获取MultipartFile
可以通过mock或者直接通过request获取. 其中MockMultipartFile需要添加依赖对应版的spring-test,我添加的4.3.13版本。
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.3.13.RELEASEversion>
dependency>
@Autowired
private FileServiceClient fileSvcClient;
@ApiOperation(value = "上传文件, 演示服务间调用传递文件")
@ApiImplicitParams({
@ApiImplicitParam(name = "content", defaultValue = "abcd", value = "文件内容", required = true, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "fileName",defaultValue = "fileRule01.txt", value = "文件名称", required = true, dataType = "string", paramType = "query")
})
@PostMapping(value = "/testFileUpload", produces = "application/json;charset=UTF-8")
public String testUploadFile(@RequestParam(required = true, defaultValue = "fileRule01.txt") String fileName,
@RequestParam(required = true, defaultValue = "abcd") String content,
HttpServletRequest request) {
String result = "not upload";
try {
byte[] bytes = content.getBytes("UTF-8");
MultipartFile multipartFile = new MockMultipartFile("file", fileName, "text/plain", bytes);
String comment = "演示FeignClient文件上传";
result = fileSvcClient.uploadFile(multipartFile, "mypath1/", comment);
}
catch (UnsupportedEncodingException ex) {
log.warn("Failed to convert content={} to bytes", content, ex);
}
return result;
}
@ApiOperation(value = "上传文件, 演示服务间调用传递文件")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", defaultValue = "file1.txt", value = "文件内容", required = true, dataType = "file", paramType = "query")
})
@PostMapping(value = "/testFileUploadDirectly", produces = "application/json;charset=UTF-8")
public String testUploadFileDirectly(@RequestParam("file") MultipartFile file) {
String result = "not upload";
try {
MultipartFile multipartFile = file;
String comment = "演示FeignClient文件上传";
result = fileSvcClient.uploadFile(multipartFile, "mypath1/", comment);
}
catch (Exception ex) {
log.warn("Failed to upload", ex);
}
return result;
}
4, 配置FeignClient
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
/**
* Simple to Introduction
* className: FileServiceClient
*
* @author EricYang
* @version 2018/12/07 19:50
*/
@FeignClient(value = "file-service", fallbackFactory = FileServiceFactory.class)
public interface FileServiceClient {
/**
* @param filePath
* @param comment
* @return
*/
@PostMapping(value = "/v1/file/uploadFile", produces = "application/json;charset=UTF-8", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String uploadFile(@RequestPart("file") MultipartFile file, @RequestParam("filePath") String filePath,
@RequestParam("comment") String comment);
}
@Component
@Slf4j
class FileServiceFactory implements FallbackFactory<FileServiceClient> {
@Override
public FileServiceClient create(final Throwable throwable) {
return new FileServiceClient() {
@Override
public String uploadFile(MultipartFile file, @RequestParam("filePath") String filePath,
@RequestParam("comment") String comment) {
log.warn("Failed to uploadFile. Fallback reason = {}", throwable.getMessage());
throw new RuntimeException(throwable.getCause());
}
};
}
}
5 测试
首先我们启动两个服务,第一个是file-service就是提供文件上传服务的工程, 第二个是FeignClient公共,它通过服务间调用,调用file-service来上传文件。