Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the callback and response mode of Java

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "how to understand the callback and response mode of Java". In daily operation, I believe many people have doubts about how to understand the callback and response mode of Java. The editor consulted all kinds of materials and sorted out simple and useful methods of operation. I hope it will be helpful for you to answer the doubts of "how to understand the callback and response mode of Java"! Next, please follow the editor to study!

1. Target service

The client invokes the target service that represents the city details has two ports. When using a URI call of type-- / cityids, a list of city id is returned, and the example result is as follows:

[1, 2, 3, 4, 5, 6, 7]

A port returns the details of the city for which its ID is given, for example, when using ID for a call to 1mura-"/ cities/1":

{"country": "USA", "id": 1, "name": "Portland", "pop": 1600000}

It is the responsibility of the client to get the list of city ID, and then for each city, obtain the details of the city according to the ID and combine them into the city list.

two。 Synchronous call

I'm using Spring Framework's RestTemplate to make remote calls. The Kotlin function to get the cityId list is as follows:

Private fun getCityIds (): List {val cityIdsEntity: ResponseEntity = restTemplate .exchange ("http://localhost:$localServerPort/cityids", HttpMethod.GET, null, object: ParameterizedTypeReference () {}) return cityIdsEntity.bodyhands!}

Get city details:

Private fun getCityForId (id: String): City {return restTemplate.getForObject ("http://localhost:$localServerPort/cities/$id", City::class.java)!!}

Given these two functions, they can be easily combined to easily return to the city list:

Val cityIds: List = getCityIds () val cities: List = cityIds .stream () .map {cityId-> getCityForId (cityId)} .cityId (Collectors.toList ()) cities.forEach {city-> LOGGER.info (city.toString ())}

The code is easy to understand; however, eight blocking calls are involved:

Get a list of 7 city ID, and then get the details of each city

Get detailed information for 7 cities

Each call will be on a different thread.

3. Non-blocking IO callback

I'll use the AsyncHttpClient library to make non-blocking IO calls.

When making a remote call, AyncHttpClient returns the ListenableFuture type.

Val responseListenableFuture: ListenableFuture = asyncHttpClient. PrepareGet ("http://localhost:$localServerPort/cityids"). Execute ())

You can attach a callback to the ListenableFuture to manipulate the response when available.

ResponseListenableFuture.addListener (Runnable {val response: Response = responseListenableFuture.get () val responseBody: String = response.responseBody val cityIds: List = objectMapper.readValue (responseBody, object: TypeReference () {})....}

Given the list of cityIds, I want to get city details, so from the response, I need to make more remote calls and attach callbacks for each call to get city details:

Val responseListenableFuture: ListenableFuture = asyncHttpClient .prepareGet ("http://localhost:$localServerPort/cityids"). Execute () responseListenableFuture.addListener (Runnable {val response: Response = responseListenableFuture.get () val responseBody: String = response.responseBody val cityIds: List = objectMapper.readValue (responseBody) Object: TypeReference () {}) cityIds.stream (). Map {cityId-> val cityListenableFuture = asyncHttpClient .prepareGet ("http://localhost:$localServerPort/cities/$cityId"). Execute () cityListenableFuture.addListener (Runnable {val cityDescResp = cityListenableFuture.get () val cityDesc = cityDescResp.responseBody val city = objectMapper.readValue (cityDesc) City::class.java) LOGGER.info ("Got city: $city")}, executor)} .clients (Collectors.toList ())}, executor)

This is a rough piece of code; the callback contains a set of callbacks that are difficult to reason and understand-so it is called "callback hell".

4. Using non-blocking IO in Java CompletableFuture

This code can be slightly improved by returning the CompletableFuture of Java as a return type instead of ListenableFuture. CompletableFuture provides operators that allow you to modify and return types.

For example, consider the ability to get a city ID list:

Private fun getCityIds (): CompletableFuture {return asyncHttpClient .prepareGet ("http://localhost:$localServerPort/cityids") .execute () .toCompletableFuture () .thenApply {response-> val s = response.responseBody val l: List = objectMapper.readValue (s, object: TypeReference () {}) l}}

Here, I use the thenApply operator to convert CompletableFuture to CompletableFuture.

Similarly, get city details:

Private fun getCityDetail (cityId: Long): CompletableFuture {return asyncHttpClient.prepareGet ("http://localhost:$localServerPort/cities/$cityId"). Execute () .toCompletableFuture () .thenApply {response-> val s = response.responseBody LOGGER.info (" Got {} ", s) val city = objectMaper.readValue (s) City::class.java) city}}

This is an improvement on the callback-based approach. However, in this particular case, CompletableFuture lacks useful operators, for example, all city details need to be put together:

Val cityIdsFuture: CompletableFuture = getCityIds () val citiesCompletableFuture: CompletableFuture = cityIdsFuture .thenCompose {l-> val citiesCompletable: List = l.stream () .map {cityId-> getCityDetail (cityId) } .upload (toList ()) val citiesCompletableFutureOfList: CompletableFuture = CompletableFuture.allOf (* citiesCompletable.toTypedArray ()) .thenApply {_: Void?-> citiesCompletable .stream () .map {it.join ()} .cake (toList ())} citiesCompletableFutureOfList}

An operator named CompletableFuture.allOf is used, which returns a type of "Void" and must be forced to return a CompletableFuture of the desired type.

5. Working with Reactor projects

Project Reactor is an implementation of the Reactive Streams specification. It has two special types of streams that can return 0 to 1 items and 0 to 2 items-the former is Mono and the latter is Flux.

Project Reactor provides a rich set of operators that allow you to convert data streams in a variety of ways. First consider the function that returns the city ID list:

Private fun getCityIds (): Flux {return webClient.get () .uri ("/ cityids") .exchange () .flatMapMany {response-> LOGGER.info ("Received cities..") Response.bodyToFlux ()}}

I'm using Spring's excellent WebClient library to make remote calls and get a response of type Project Reactor Mono, which can be modified to type Flux using the flatMapMany operator.

According to the city ID, follow the same route to get the city details:

Private fun getCityDetail (cityId: Long?): Mono {return webClient.get () .uri ("/ cities/ {id}", cityIdbath!) .exchange () .flatMap {response-> val city: Mono = response.bodyToMono () LOGGER.info ("Received city..") City}}

Here, the Project Reactor Mono type is being converted to the Mono type using the flatMap operator.

And get the cityIds from it, which is the code for City:

Val cityIdsFlux: Flux = getCityIds () val citiesFlux: Flux = cityIdsFlux .flatMap {this.getCityDetail (it)} return citiesFlux

This is very expressive-comparing the confusion of the callback-based approach to the simplicity of the Reactive Streams-based approach.

At this point, the study on "how to understand the callback and response mode of Java" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report