ホームページ >Java >&#&チュートリアル >OpenFeign と SpringBoot を統合する際の落とし穴を解決する方法

OpenFeign と SpringBoot を統合する際の落とし穴を解決する方法

PHPz
PHPz転載
2023-05-22 18:19:06935ブラウズ

プロジェクトの統合 OpenFegin

統合 OpenFegin の依存関係

まずプロジェクトの構成について説明します プロジェクト全体で使用する SpringBoot のバージョンネイティブの OpenFegin は 2.2.6 です。ネイティブの OpenFegin は 11.0 を使用します。以下のように pom.xml に OpenFegin を導入します。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <skip_maven_deploy>false</skip_maven_deploy>
    <java.version>1.8</java.version>
    <openfegin.version>11.0</openfegin.version>
</properties>
<dependencies>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-core</artifactId>
        <version>${openfegin.version}</version>
    </dependency>

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-jackson</artifactId>
        <version>${openfegin.version}</version>
    </dependency>
</dependencies>

ここでは、他のいくつかの設定項目を省略しています。

次に、OpenFegin を使用してプロジェクト内でリモート サービスを呼び出し始めました。具体的な手順は以下の通りです。

リモート呼び出しを実現する

まず、OpenFeignConfig クラスを作成し、OpenFegin がデフォルトで使用する Contract を設定します。

@Configuration
public class OpenFeignConfig {
 @Bean
 public Contract useFeignAnnotations() {
  return new Contract.Default();
 }
}

次に、OpenFeign クライアントを取得するための一般的なファクトリ クラスを作成します。このクラスも比較的単純です。基本的に HashMap を使用してすべての FeginClient をキャッシュします。この FeginClient は本質的にカスタム クラスです。Fegin インターフェイス、キーキャッシュ内の は、要求された接続のベース URL であり、キャッシュされた値は、定義した FeginClient インターフェイスです。

public class FeginClientFactory {
 
 /**
  * 缓存所有的Fegin客户端
  */
 private volatile static Map<String, Object> feginClientCache = new HashMap<>();
 
 /**
  * 从Map中获取数据
  * @return 
  */
 @SuppressWarnings("unchecked")
 public static <T> T getFeginClient(Class<T> clazz, String baseUrl){
  if(!feginClientCache.containsKey(baseUrl)) {
   synchronized (FeginClientFactory.class) {
    if(!feginClientCache.containsKey(baseUrl)) {
     T feginClient = Feign.builder().decoder(new JacksonDecoder()).encoder(new JacksonEncoder()).target(clazz, baseUrl);
     feginClientCache.put(baseUrl, feginClient);
    }
   }
  }
  return (T)feginClientCache.get(baseUrl);
 }
}

次に、FeginClient インターフェイスを定義します。

public interface FeginClientProxy {
 @Headers("Content-Type:application/json;charset=UTF-8")
 @RequestLine("POST /user/login")
 UserLoginVo login(UserLoginVo loginVo);
}

次に、SpringBoot テスト クラスを作成します。

@RunWith(SpringRunner.class)
@SpringBootTest
public class IcpsWeightStarterTest {
 @Test
 public void testUserLogin() {
  ResponseMessage result = FeginClientFactory.getFeginClient(FeginClientProxy.class, "http://127.0.0.1").login(new UserLoginVo("zhangsan", "123456", 1));
  System.out.println(JsonUtils.bean2Json(result));
 }
}

すべての準備が整ったので、テストを実行します。くそー、何か問題が起きた。主な問題は、OpenFeign リクエストを通じて LocalDateTime フィールドが値を返すときに例外が発生することです。 ! !

注: この時点で例外が発生した場合、LocalDateTime フィールドに追加する注釈は次のとおりです。

import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;


@TableField(value = "CREATE_TIME", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime createTime;

解決策

問題の説明

SpringBoot は、ネイティブ OpenFeign クライアントを介して HTTP インターフェイスを呼び出します。戻り値に LocalDateTime 型が含まれる場合 (他のものを含む) JSR -310 の java.time パッケージの Time クラス)、クライアントで逆シリアル化失敗エラーが発生する可能性があります。エラー メッセージは次のとおりです。

原因: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: `java.time.LocalDateTime` のインスタンスを構築できません (デフォルトの構築のように Creator がありません)。存在します): 文字列値 ("2020-10-07T11:04:32") から逆シリアル化するための文字列引数コンストラクター/ファクトリ メソッドがありません

#問題分析


From クライアントが fegin を呼び出すと、URL でパラメータを渡すことと同じになり、JSON 変換と同等になります。データベースは '2020-10-07T11:04:32' データを取り出します。これは時刻型です. JSONを入力するとString型になり、Tは文字となり特殊文字ではなくなるため、String文字列「2020-10-07T11:04:32」の逆シリアル化は失敗します。 #問題の解決策

依存関係をプロジェクトに追加します。
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.9</version>
</dependency>

注: SpringBoot を使用していて、SpringBoot のバージョンが明示的に指定されている場合は、バージョン番号を指定する必要はありません。 jackson-datatype-jsr310 の導入.

次に、POJO クラスの LocalDateTime 型フィールドに次のアノテーションを追加します。

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

追加後の効果は次のとおりです。 #この時点で、リモート インターフェイスを再度呼び出すと、問題は解決します。

以上がOpenFeign と SpringBoot を統合する際の落とし穴を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。