SpringCloud微服务服务间调用之OpenFeign介绍(四) 文件传输

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来上传文件。

consul上两个服务都注册完毕
SpringCloud微服务服务间调用之OpenFeign介绍(四) 文件传输_第1张图片

通过ARC调用feignClient工程的接口
SpringCloud微服务服务间调用之OpenFeign介绍(四) 文件传输_第2张图片

MockMultipartFile方式调用feignclient
SpringCloud微服务服务间调用之OpenFeign介绍(四) 文件传输_第3张图片

你可能感兴趣的:(FeignClient,springcloud)