使用spring-cloud-FeignClient下载和上传文件

原创
2018/07/19 20:02
阅读数 1.6K

工作上,遇到一个问题。我需要用@FeignClient远程调用文件服务,下载一个doc文件,把它转换成ceb或pdf文件,在上传到文件系统。其实我就是在开发文件转换服务。那么,我们该怎么用FeignClient来下载文件?

 

 

Spring将响应转换为字节数组ByteArrayHttpMessageConverter,但它支持application / octet-stream和/ media类型。我们可以用byte[]来接收文件。例如下面这样写:

@FeignClient(value = "epolicy", path = "/epolicy/download", url = "http://10.1.118.45:8001") public interface EPolicyApi {

@RequestMapping(method = RequestMethod.POST)
byte[] download(@RequestParam("policyNo") String policyNo, @RequestParam("idNo") String idNo);

}

但是我们可以学习老外这么写:https://github.com/spring-cloud/spring-cloud-netflix/issues/2246

用feign-form上传文件

<dependency>
    <groupId>io.github.openfeign.form</groupId>
	<artifactId>feign-form</artifactId>
	<version>2.2.1</version>
</dependency>

<dependency>
	<groupId>io.github.openfeign.form</groupId>
	<artifactId>feign-form-spring</artifactId>
	<version>2.2.1</version>
</dependency
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

public class InMemoryMultipartFile implements MultipartFile {

    private final String name;
    private final String originalFileName;
    private final String contentType;
    private final byte[] payload;

    public InMemoryMultipartFile(File file) throws IOException {
        this.originalFileName = file.getName();
        this.payload = FileCopyUtils.copyToByteArray(file);
        this.name = "file";
        this.contentType = "application/octet-stream";
    }

    public InMemoryMultipartFile(String originalFileName, byte[] payload) {
        this.originalFileName = originalFileName;
        this.payload = payload;
        this.name = "file";
        this.contentType = "application/octet-stream";
    }

    public InMemoryMultipartFile(String name, String originalFileName, String contentType, byte[] payload) {
        if (payload == null) {
            throw new IllegalArgumentException("Payload cannot be null.");
        }
        this.name = name;
        this.originalFileName = originalFileName;
        this.contentType = contentType;
        this.payload = payload;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getOriginalFilename() {
        return originalFileName;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public boolean isEmpty() {
        return payload.length == 0;
    }

    @Override
    public long getSize() {
        return payload.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return payload;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(payload);
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        new FileOutputStream(dest).write(payload);
    }
}

 

@FeignClient(value = "material", configuration = MaterialClient.MultipartSupportConfig.class)
public interface MaterialClient {

    @PostMapping("/uploadFile")
    @Headers("Content-Type: multipart/form-data")
    ResponseMO uploadFile(@RequestPart("file") MultipartFile file);


    @GetMapping("/oss/downFile")
    MultipartFile downFile(@RequestParam("key") String key);


    class MultipartSupportConfig {

        @Autowired
        ObjectFactory<HttpMessageConverters> messageConverters;

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

        @Bean
        @Primary
        @Scope("prototype")
        public Decoder decoder() {
            Decoder decoder = (response, type) -> {
                if (type instanceof Class && MultipartFile.class.isAssignableFrom((Class) type)) {
                    Collection<String> contentTypes = response.headers().get("content-type");
                    String contentType = "application/octet-stream";
                    if (contentTypes.size() > 0) {
                        String[] temp = new String[contentTypes.size()];
                        contentTypes.toArray(temp);
                        contentType = temp[0];
                    }


                    byte[] bytes = StreamUtils.copyToByteArray(response.body().asInputStream());
                    InMemoryMultipartFile inMemoryMultipartFile = new InMemoryMultipartFile("file","", contentType,bytes);
                    return inMemoryMultipartFile;
                }
                return new SpringDecoder(messageConverters).decode(response, type);
            };
            return new ResponseEntityDecoder(decoder);
        }
    }
}

 

展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部