我使用Feign上传文件踩的坑,MultipartFile文件死活传不过去

2022-07-29 09:36:12

我使用Feign上传文件踩的坑,MultipartFile文件死活传不过去

Feign上传文件

基本信息:通过后台管理,更改APP端的头像。我是用feign来调用app端的修改头像接口。两个参数,string类型的userId和图片文件headImg.

什么样的坑

前端调用我的接口,通过form表单向我提交这两个参数。参数名分别叫userId和headImg。我的controller层接受到这两个参数后,向后传递,一直到feign。然而,我通过feign调用的app端的接口,图片的参数名叫headPortrait。我在feign里通过注解来指定图片文件的参数名,但是没用,死活传不过去。
我的controller层代码大概如下:

public class UserController{

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

我的feign代码大概如下:

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

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

public class AppUserController{

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

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

解决办法

我找不到问题所在,我觉得我在feign中已经指定了远端接口需要的图片的参数名。但是传不过去,我就很蛋疼。于是,我有了一个大胆的想法,把远端接口接收到的HttpServletRequest拿出来瞅瞅,瞅瞅到底我通过feign发起的request长什么样。
于是我在远端的接口里添加参数HttpServletRequest,把request里的parts拿出来瞅瞅。请看代码:

public class AppUserController{

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

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

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

至此,破案了。并不是图片没有通过feign传递到远端接口,而是传递过去后,name不是headPortrait,而是叫headImg。也就是说,我通过feign里的注解@RequestPart的value属性指定的参数名,并不生效。最终决定参数名的,就是前端传递到我的controller的图片参数的名字。
这个坑,困扰了我一整天。我是实在想不到,在feign里指定参数名蛋用没有。如果你碰到相同问题,在我这里找到了答案,请给我点赞,我同你抱起来哭。

  • 作者:HairyCoder
  • 原文链接:https://blog.csdn.net/HairyCoder/article/details/105012176
    更新时间:2022-07-29 09:36:12