Maison > Java > javaDidacticiel > Comment résoudre les pièges de l'intégration d'OpenFeign avec SpringBoot

Comment résoudre les pièges de l'intégration d'OpenFeign avec SpringBoot

PHPz
Libérer: 2023-05-22 18:19:06
avant
957 Les gens l'ont consulté

Le projet intègre OpenFegin

Intégrer les dépendances OpenFegin

Tout d'abord, permettez-moi de vous parler de la configuration du projet. La version SpringBoot utilisée par l'ensemble du projet est la 2.2.6, et la version native d'OpenFegin utilise la 11.0. La méthode suivante dans le pom OpenFegin est introduite dans .xml.

<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>
Copier après la connexion

Ici, j'ai omis quelques autres éléments de configuration.

Ensuite, j'ai commencé à utiliser OpenFegin pour appeler des services distants dans mon projet. Les étapes spécifiques sont les suivantes.

Implémentez les appels à distance

Tout d'abord, créez la classe OpenFeignConfig et configurez le contrat utilisé par OpenFegin par défaut.

@Configuration
public class OpenFeignConfig {
 @Bean
 public Contract useFeignAnnotations() {
  return new Contract.Default();
 }
}
Copier après la connexion

Ensuite, nous écrivons une classe d'usine générale pour obtenir des clients OpenFeign. Cette classe est également relativement simple. Elle utilise essentiellement un HashMap pour mettre en cache tous les FeginClients. Ce FeginClient est essentiellement notre interface Fegin personnalisée, la clé est l'URL de base. de la connexion demandée, et la valeur mise en cache est l'interface FeginClient que nous avons définie.

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);
 }
}
Copier après la connexion

Ensuite, nous définissons une interface FeginClient.

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

Ensuite, nous créons la classe de test 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));
 }
}
Copier après la connexion

Tout est prêt, lancez le test. Bon sang, quelque chose s'est mal passé. Le principal problème est qu'une exception se produira lorsque le champ LocalDateTime renvoie la valeur via la requête OpenFeign ! ! !

Remarque : Lorsqu'une exception se produit à ce moment-là, l'annotation que nous ajoutons au champ LocalDateTime est la suivante.

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;
Copier après la connexion

Résoudre le problème

Description du problème

SpringBoot appelle l'interface HTTP via le client natif OpenFeign Si la valeur de retour contient le type LocalDateTime (y compris d'autres classes d'heure du package java.time dans JSR-310), cela peut être possible sur le client. Une erreur d'échec de désérialisation se produira. Le message d'erreur est le suivant :

Causé par : com.fasterxml.jackson.databind.exc.InvalidDefinitionException : Impossible de construire une instance de `java.time.LocalDateTime` (aucun créateur, comme la construction par défaut, n'existe) : aucune chaîne- constructeur d'arguments/méthode d'usine pour désérialiser à partir de la valeur de chaîne ("2020-10-07T11:04:32")

Analyse du problème

Appeler fegin depuis le client équivaut également à transmettre des paramètres d'URL, ce qui équivaut à un Conversion JSON, base de données Supprimez les données '2020-10-07T11:04:32". C'est un type d'heure à ce moment. Après avoir entré JSON, il devient un type String. T devient un caractère et n'est plus un caractère spécial . Par conséquent, la désérialisation de la chaîne "2020 -10-07T11:04:32" échouera

Problème résolu

Ajoutez des dépendances dans le projet.

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.9</version>
</dependency>
Copier après la connexion

Remarque : si vous utilisez SpringBoot et que la version SpringBoot est clairement. spécifié, introduisez jackson -datatype-jsr310, vous n'avez pas besoin de spécifier le numéro de version

Ensuite, ajoutez l'annotation suivante au champ de type LocalDateTime de la classe POJO

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
Copier après la connexion

L'effet après l'ajout est le suivant

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

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


@TableField(value = "CREATE_TIME", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime createTime;
Copier après la connexion
.

À ce moment, appelez à nouveau l'interface distante. Problème résolu

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal