当前位置: 移动技术网 > IT编程>开发语言>Java > SpringCloud中,Feign如何传递MultipartFile

SpringCloud中,Feign如何传递MultipartFile

2020年07月12日  | 移动技术网IT编程  | 我要评论

1、引入POM

        <!-- Feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
             <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign.form</groupId>
            <artifactId>feign-form</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign.form</groupId>
            <artifactId>feign-form-spring</artifactId>
            <version>3.3.0</version>
        </dependency>

2、编写配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;

import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;

@Configuration
public class FeignMultipartSupportConfig {

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

    @Bean
    public feign.Logger.Level multipartLoggerLevel() {
        return feign.Logger.Level.FULL;
    }
}

3、使用

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

//common是eureka中的一个服务提供者 
@FeignClient(name="common", configuration=FeignMultipartSupportConfig.class)
public interface FeignUploadService {
    @RequestMapping(value="uploadImg", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE},consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public OSSFile uploadImg(@RequestPart MultipartFile file);
}

就是,大功告成。


但是,如果你一不小心,可能就会遇到这样一个坑,使用Feign上传文件,MultipartFile文件死活传不过去。

前端调用接口,通过form表单向我提交这两个参数。参数名分别叫userId和headImg。

我的controller层接受到这两个参数后,向后传递,一直到feign。然而,我通过feign调用的其他服务的接口,图片的参数名叫file。我在feign里通过注解来指定图片文件的参数名,但是没用,死活传不过去。

public class UserController{

	@Autowired
	private Feign feign;
	
	@PostMapping("/headImg")
	public Result updateHeadImg(@RequestParam("userId") String userId, @RequestParam("headImg")  MultipartFile headImg){
		//前端给我传图片使用的参数名是headImg
		return feign.updateHeadImg(userId, headImg);
	}
	}

我的feign代码大概如下

@FeignClient(name="app-user-service")
public interface Feign{
	//前端给我传递的图片叫fileImage,而我调用的接口,图片参数名叫headImage,所以此处我在@RequestPart注解中,指定图片文件的参数名叫file
	@PostMapping(value="/path", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	Result<Type> updateHeadImg(@RequestParam(value = "userId") String userId, @RequestPart(value="file") MultipartFile file);
}

我通过feign调用的远端接口代码大概如下:

public class AppUserController{

	@Autowired
	private UserService userService;
	
	@PostMapping("/upHeadPortrait")
	public Result upHeadPortrait(@RequestParam("userId") String userId, @NotNull MultipartFile file){
		//这个别的微服务的接口,接收图片使用的参数名是file
		return userService.upHeadPortrait(userId, file);
	}
	}

我发现,无论我在feign中怎么指定参数名,图片文件到了远端接口,就是null,死活传不过去。

解决办法

把远端接口接收到的HttpServletRequest拿出来,看看到底我通过feign发起的request。
于是我在远端的接口里添加参数HttpServletRequest,把request里的parts拿出来看一眼。

请看代码:

public class AppUserController{

	@Autowired
	private UserService userService;
	
	@PostMapping("/upHeadPortrait")
	public Result upHeadPortrait(@RequestParam("userId") String userId, @NotNull MultipartFile file,
	HttpServletRequest request){
		//这个别的微服务的接口,接收图片使用的参数名是file
		Collection<Part> parts = request.getParts();
		logger.info(JSONObject.toJSONString(parts, true));
		return userService.upHeadPortrait(userId, file);
	}
	}

以下是logger打印出来的,parts的内容:

[
	{
		"contentType":"image/jpeg",
		"headerNames":["content-disposition","content-type","content-transfer-encoding"],
		"inputStream":{
			"channel":{
				"open":true
			},
			"fD":{}
		},
		"name":"headImg",
		//图片的大小
		"size":3734,
		//这是我上传的图片文件的名字
		"submittedFileName":"img1.jpg"
	}
]

并不是图片没有通过feign传递。而是传递过去后,name不是file,而是叫headImg。通过feign里的注解@RequestPart的value属性指定的参数名,并不生效。最终决定参数名的,就是前端传递到我的controller的图片参数的名字。

本文地址:https://blog.csdn.net/u012352957/article/details/107285515

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网