J'ai un projet springboot qui utilise Springboot Resttemplate. Nous sommes passés à springboot 2.0.1 de 1.5.3 et nous essayons de faire des appels de repos de ce asynchrone en utilisant WebClient. Nous avons utilisé pour traiter la chaîne reçue en utilisant Resttemplate comme indiqué ci-dessous. Mais WebClient renvoie uniquement les données en mono ou flux. Comment puis-je obtenir les données sous forme de chaîne. Déjà méthode de bloc () essayé, mais il fait des appels asynchrones.
@Retryable(maxAttempts = 4, value = java.net.ConnectException.class,
backoff = @Backoff(delay = 3000, multiplier = 2))
public Mono<String> getResponse(String url) {
return webClient.get().uri(urlForCurrent).accept(APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class);
}
Présent flux de données avec RestTemplate
- Contrôleur reçoit l'appel client
- fournisseur obtient les données au format chaîne
- Fournisseur traite la chaîne
- Les données sont donné au contrôleur
Controller.java
@RequestMapping(value = traffic/, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public String getTraffic(@RequestParam("place") String location) throws InterruptedException, ExecutionException {
String trafficJSON = Provider.getTrafficJSON(location)
return trafficJSON;
}
Provider.java
public String getTrafficJSON(String location) {
String url = ----;
ResponseEntity<String> response = dataFetcher.getResponse(url);
/// RESPONSEBODY IS READ AS STRING AND IT NEEDS TO BE PROCESSED
if (null != response {
return parser.transformJSON(response.getBody(), params);
}
return null;
}
DataFetcher.java
@Retryable(maxAttempts = 4,
value = java.net.ConnectException.class,
backoff = @Backoff(delay = 3000, multiplier = 2))
public ResponseEntity<String> getResponse(String url) {
/* ----------------------- */
return getRestTemplate().getForEntity(urlForCurrent, String.class);
}
En raison du fait qu'il ya beaucoup d'idées fausses, donc ici, je vais éclaircir certaines choses.
Le printemps est officiellement déclaré qu'ils désapprouver RestTemplate
à l'avenir , donc si vous pouvez, utilisez WebClient
si vous voulez être comme preuve d'avenir possible.
comme indiqué dans l' API RestTemplate
NOTE: A partir de 5,0, le non-bloquant, réactives
org.springframework.web.reactive.client.WebClient
offre une alternative moderne à l'RestTemplate
un soutien efficace à la fois pour la synchronisation et async, ainsi que des scénarios en streaming. LeRestTemplate
sera dépréciée dans une version future et n'avoir des nouvelles fonctionnalités ajoutées à l' avenir. Voir laWebClient
section de la documentation de référence Spring Framework pour plus de détails et des exemples de code.
Application non réactive
Si votre application est une application non réactif (non retour des flux ou monos aux clients appelant) ce que vous avez à faire est d'utiliser block()
si vous avez besoin de la valeur. Vous pouvez l' utilisation des cours Mono
ou en Flux
interne dans votre application , mais à la fin vous devez appeler block()
pour obtenir la valeur concrète que vous devez retourner au client appelant.
Applications non réactives utilisent tomcat
comme la mise en œuvre du serveur sous - jacent, qui est un serveur de servlet qui attribuera 1 thread par demande afin que vous ne gagnerez pas les gains de performance que vous obtenez avec une application réactive.
La dernière version de Tomcat prend en charge la dernière servlet spec +3,0 qui soutient à son tour I non bloquante / O mais comment ce soutien est destiné aux applications WebFlux est de cette écriture pas clair au printemps docs.
l'application réactive
Si vous d'autre part , vous avez une application réactive vous ne devriez jamais en aucun cas jamais appeler block()
ou subscribe()
dans votre application. Le blocage est exactement ce qu'il dit, il va bloquer un fil et le bloc que les fils d' exécution jusqu'à ce qu'il puisse passer à autre chose, cela est mauvais dans un monde réactif.
Sous - jacente mise en œuvre du serveur est un ici netty
serveur qui est un servlet non, événement serveur basé qui va pas assignera un fil à chaque demande, le serveur lui - même est agnostique de fil et tout fil disponible sera quelque chose de poignée à tout moment pendant toute demande.
Comment puis-je savoir quelle application j'ai?
États de printemps que si vous avez à la fois spring-web
et spring-webflux
sur le chemin de classe, l'application favorisera spring-web
et par défaut le démarrage d' une application non-réactif avec un serveur tomcat sous - jacent.
Ce comportement peut manuellement être surchargée si nécessaire comme des états de printemps.
Ajout à la fois
spring-boot-starter-web
et desspring-boot-starter-webflux
modules dans vos résultats d'application au printemps de configuration automatique de démarrage Spring MVC, pas WebFlux. Ce comportement a été choisi parce que de nombreux développeurs de printemps ajoutentspring-boot-starter-webflux
à leur application Spring MVC utiliser le WebClient réactif. Vous pouvez toujours appliquer votre choix en définissant le type d'application choisiSpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)
.
Le « printemps cadre WebFlux »
Alors, comment mettre en œuvre WebClient
@Retryable(maxAttempts = 4,
value = java.net.ConnectException.class,
backoff = @Backoff(delay = 3000, multiplier = 2))
public ResponseEntity<String> getResponse(String url) {
return webClient.get()
.uri(url)
.exchange()
.flatMap(response -> response.toEntity(String.class))
.block();
}
Ceci est la plus simple et la mise en œuvre plus moins intrusive. Vous Ofcourse besoin de construire un webclient approprié dans peut - être @Bean
et dans sa lier automatiquement la classe.