首頁 > 軟體

使用feign傳遞引數型別為MultipartFile的問題

2022-03-16 16:00:21

feign傳遞引數型別為MultipartFile

feign預設是不支援多媒體檔案型別的檔案傳輸的,但是可以通過引入第三方jar包解決這個問題,步驟可以分為三步。

引入maven依賴

        <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>

加入設定類

@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;
    }
}

在feign使用者端進行設定

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import config.FeignMultipartSupportConfig;
import feign.Response;
@FeignClient(value = "", fallback = FileServiceFallback.class,configuration=FeignMultipartSupportConfig.class)
public interface IFileService {
    //上傳檔案
    @RequestMapping(value = "/rmi/fileService/mediaImgUpload",  produces = {MediaType.APPLICATION_JSON_UTF8_VALUE},consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String mediaImgUpload(@RequestPart MultipartFile file);
    //下載檔案
    @RequestMapping(value = "/rmi/fileService/mediaDownload",method = RequestMethod.GET,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Response mediaDownload(@RequestParam(required = true) String mediaId);

feign傳參MultipartFile問題解決

首先,feign服務之間的呼叫,傳參預設的格式為:ContentType=application/x-www-form-urlencoded

以表單的形式傳參的,而檔案流的傳參,需要form-data的ContentType,否則會報錯的

首先引入依賴

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

注意spring boot版本是2.x以上的,上面兩個依賴的版本不低於3.5.0,否則還是無效的

新建feign的設定

package com.wm.blog_config.config; 
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; 
 
/**
 * @author :半卷流年
 * @description : 解決feign傳遞流資料的異常
 * @createTime :2020/6/14
 */
@Configuration
public class FeignSupportConfig {
 
    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;
 
    @Bean
    public Encoder feignFormEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    } 
}

在feign介面中設定

package com.wm.blog_admin.feign; 
import com.wm.blog_admin.feign.factory.PictureClientFallbackFactory;
import com.wm.blog_common.constatnt.CommonConstant;
import com.wm.blog_common.domain.TFileDO;
import com.wm.blog_common.entity.TFile;
import com.wm.blog_common.req.TFileQuery;
import com.wm.blog_common.result.Result;
import com.wm.blog_config.config.CustomFeignConfig;
import com.wm.blog_config.config.FeignSupportConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; 
import java.util.List;
 
/***
 * @ClassName: PictureFeignClient
 * @Description: picture feign呼叫  todo feign使用get有坑啊,是否考慮使用HttpClient替換feign的HttpURLConnection,採用apache的HttpClient
 * @Author: wm_yu
 * @Create_time: 16:39 2020-3-26
 */
@FeignClient(value = CommonConstant.PICTURE_MODULE_NAME, configuration = {CustomFeignConfig.class, FeignSupportConfig.class}, fallbackFactory = PictureClientFallbackFactory.class)
public interface PictureFeignClient {
 
    /**
     * id查詢圖片資訊
     * @param id
     * @return
     */
    @GetMapping("/web/picture/{id}")
    Result<TFileDO> get(@PathVariable("id") Long id); 
 
    /**
     * id批次查詢圖片資訊
     * @param idList
     * @return
     */
    @PostMapping("/web/picture/getByIdList")
    Result<List<TFile>> getByIdList(@RequestBody List<Long> idList); 
 
    /**
     * 檔案上傳
     * @param file
     * @return
     */
    @PostMapping(value = "/web/picture/uploadFile",produces = {MediaType.APPLICATION_JSON_UTF8_VALUE},consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
     Result<String> uploadFile(@RequestPart("file") MultipartFile file); 
}

注意加上這個,表示傳參格式:

就可以傳參了的

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com