@FeignClient アップロード ファイル エラーの解決策

Spring Cloud の RPC ツールとして、Feign はアノテーションを使用してインターフェイスを記述し、Java HTTP クライアントの呼び出しプロセスを簡素化します。ただし、ファイルをアップロードする場合は、追加の構成を行う必要があります。そうしないと、例外が呼び出されます。

バックグラウンド

アップロードされたファイルといくつかのパラメーターを受け入れる必要があるインターフェイスを備えたサービス A があります。

 @PostMapping({
    
    "/validityPeriod/update"})
    BizResponse proofValidityPeriodUpdate(@Validated ValidityPeriodUpdateRequest request);

ValidityPeriodUpdateRequest コードは次のとおりです。

public class ValidityPeriodUpdateRequest {
    
    
    @NotEmpty(
        message = "操作名称 不能为空"
    )
    @ApiModelProperty("操作名称")
    private String operateName;
    @ApiModelProperty("延期时间,如: 2025-01-01")
    private String delayDate;
    @ApiModelProperty("延期天数")
    private Integer delayDays;
    @ApiModelProperty("延期数据, Excel 文件")
    private MultipartFile delayData;
    @ApiModelProperty("备注")
    private String remark;
    @NotEmpty(
        message = "操作人不能为空"
    )
    @ApiModelProperty("操作人")
    private String operator;

private MultipartFile delayData;ファイルは受け入れられることに注意してください。

次に、サービス B は BFF として、サービス A のこのインターフェイスを呼び出します。

デフォルトの Feign 設定を使用して呼び出す場合

@FeignClient(name = "ext-website-mkt-coupon-setting")
public interface CouponOperateTaskClient extends CouponOperateTaskService {
    
    
}

次の例外が報告されます。

org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class java.io.FileDescriptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.tuhu.mkt.coupon.api.dto.operate.request.ValidityPeriodUpdateRequest["delayData"]->org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile["inputStream"]->java.io.FileInputStream["fd"])

Google は、openfig がパラメータ内のファイルをサポートしていないことを発見しました。

解決

OpenFeign はデフォルトではファイル パラメータをサポートしませんが、feign-form拡張ツールを提供します。

公式サイトの紹介を見ると、一般的な意味は次のとおりです。

feign-form 拡張機能は、open-feign の特定のバージョンに依存します。

open-feign 9.* バージョンは、feign-from 3.5.0 より前のバージョンに対応します。

Open-feign 10.1.0 以降のバージョンは 3.5.0 以降のバージョンに対応します

feign-from 3.5.0 以降のバージョンは、open-feign 10.* より前のバージョンと互換性がありません。open-feign のバージョン 10 ではコードがリファクタリングされているため、最新バージョンを使用するのが最善の方法です。

spring-cloud-openfeign: 2.0.3.release より前では、open-feign 9.バージョンが使用され、2.0.3.release 以降では、open-feign 10.* が使用され、feign は 2.0.3 以降のバージョンにすでに含まれています.release -form 依存関係、対応するバージョンを指定する必要はありません*

spring-cloud-starter-feign は推奨されなくなりました。依然として open-feign 9.* に依存しています。

さて、github の紹介を読んだ後、プロジェクトの springcloud バージョンも確認しましたが、このバージョンには feign-form の依存関係が含まれていないため、feign-form 3.5.0 より前のバージョンを手動で導入する必要があります。

Maven 依存関係を追加します。

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

依存関係を導入した後、構成クラスを作成する必要があります。

@Configuration
public class FeignSupportConfig {
    
    
    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

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

feign-form 構成クラスを作成した後、それを @FeignClient アノテーションに導入する必要もあります

@FeignClient(name = "ext-website-mkt-coupon-setting", configuration = FeignSupportConfig.class)
public interface CouponOperateTaskClient extends CouponOperateTaskService {
    
    
}

上記の設定が完了したら、コードの記述方法も変更する必要があります。
元のインターフェイス定義は次のとおりです。

 @PostMapping({
    
    "/validityPeriod/update"})
    BizResponse proofValidityPeriodUpdate(@Validated ValidityPeriodUpdateRequest request);

Openfeign はパラメーター バインディングなどのクラスもサポートしていないため、@RequestPartアノテーションと@RequestParamアノテーションを組み合わせてパラメーター バインディングを完了する必要があります。

@PostMapping(value = "/validityPeriod/update", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    BizResponse proofValidityPeriodUpdate(@RequestPart("delayData") MultipartFile delayData,
                                           @RequestParam("operateName") String operateName,
                                           @RequestParam(name = "delayDate",required = false) String delayDate,
                                           @RequestParam(name = "delayDays",required = false) Integer delayDays,
                                           @RequestParam("remark") String remark,
                                           @RequestParam("operator") String operator
    );

忘れずにconsumes = MediaType.MULTIPART_FORM_DATA_VALUE構成を追加してください。

この構成が完了したら、もう一度テストしてみましょう。

問題を完璧に解決します。

要約する

後で、この問題を解決するために springcloud バージョンをアップグレードすることを検討できます。

おすすめ

転載: blog.csdn.net/itguangit/article/details/123187027