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>
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.
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(); } }
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); } }
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); }
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)); } }
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;
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")
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
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>
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;
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;
À 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!