springcloud服务间文件传输解决方法

1,maven依赖


		<dependency>
			<groupId>io.github.openfeign.formgroupId>
			<artifactId>feign-formartifactId>
			<version>3.3.0version>
		dependency>
		<dependency>
			<groupId>io.github.openfeign.formgroupId>
			<artifactId>feign-form-springartifactId>
			<version>3.3.0version>
		dependency>

2,自定义处理方式

package com.huwei.modules.base.config;

 

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.form.ContentType;
import feign.form.FormEncoder;
import feign.form.MultipartFormContentProcessor;
import feign.form.spring.SpringManyMultipartFilesWriter;
import feign.form.spring.SpringSingleMultipartFileWriter;

import org.springframework.web.multipart.MultipartFile;
 
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Map;
 
public class SpringMultipartEncoder extends FormEncoder {
 
    /**
     * Constructor with the default Feign's encoder as a delegate.
     */
    public SpringMultipartEncoder() {
        this(new Default());
    }
 
 
    /**
     * Constructor with specified delegate encoder.
     * @param delegate delegate encoder, if this encoder couldn't encode object.
     */
    public SpringMultipartEncoder(Encoder delegate) {
        super(delegate);
 
        MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(ContentType.MULTIPART);
        processor.addWriter(new SpringSingleMultipartFileWriter());
        processor.addWriter(new SpringManyMultipartFilesWriter());
    }
 
 
    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
        // 单MultipartFile判断
        if (bodyType.equals(MultipartFile.class)) {
            MultipartFile file = (MultipartFile) object;
            @SuppressWarnings("rawtypes")
			Map data = Collections.singletonMap(file.getName(), object);
            super.encode(data, MAP_STRING_WILDCARD, template);
            return;
        } else if (bodyType.equals(MultipartFile[].class)) {
            // MultipartFile数组处理
            MultipartFile[] file = (MultipartFile[]) object;
            if(file != null) {
                Map<String, Object> data = Collections.singletonMap(file.length == 0 ? "" : file[0].getName(), object);
                super.encode(data, MAP_STRING_WILDCARD, template);
                return;
            }
        }
        // 其他类型调用父类默认处理方法
        super.encode(object, bodyType, template);
    }
}

3,配置

package com.huwei.modules.base.config;

import feign.codec.Encoder;

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;
 

/**
 * 	服务之间文件传输配置
 * @author Administrator
 *
 */
@Configuration
public class MultipartSupportConfig {
 
   @Autowired
   private ObjectFactory<HttpMessageConverters> messageConverters;
 
   @Bean
   public Encoder feignFormEncoder() {
      return new SpringMultipartEncoder(new SpringEncoder(messageConverters));
   }
}

4,使用

package com.huwei.modules.base.rpc;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
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;

import com.huwei.modules.base.config.MultipartSupportConfig;
import com.huwei.modules.base.rpc.impl.TestServiceRpcImpl;


@FeignClient(value="CallServiceApplicationName" , fallback=TestServiceRpcImpl.class , configuration = MultipartSupportConfig.class)
public interface TestServiceRpc {
	
	@PostMapping(value="/api/resource/uploadOrUpdate" ,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	public String updload(@RequestParam("sign")String sign , @RequestParam("key")String key ,@RequestParam("token")String token
			,@RequestPart("file") MultipartFile file);
	
}

说明:

  • 在@FeignClient 注解中必须使用configuration = MultipartSupportConfig.class 来指定文件传输使用方式
  • 在定义的需要文件传输的请求接口中,如:@PostMapping、@RequestMapping 、@GetMapping 等,需要指定consumes = MediaType.MULTIPART_FORM_DATA_VALUE
  • 在方法参数传递时,文件参数需要使用@RequestPart注解标注,如:@RequestPart(“file”) MultipartFile file

注意/提示:文件传输的接口,如果文件对象为空,如上述:@RequestPart(“file”) MultipartFile file 为空时,请求将不会被正确的发送出去;(预计是底层做了限制,暂时不知道在哪里修改,如有了解的大神,还请指导)

你可能感兴趣的:(spring,cloud)