JavaRush /جاوا بلاگ /Random-SD /ايئر ٽڪيٽ جي قيمت مانيٽرنگ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [ح...

ايئر ٽڪيٽ جي قيمت مانيٽرنگ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [حصو 1]

گروپ ۾ شايع ٿيل

مواد:

ايئر ٽڪيٽ جي قيمتن جي نگراني لاءِ هڪ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [حصو 1] - 1هيلو هرڪو، JavaRush ڪميونٽي! اڄ اسين ڳالهائينداسين ته ڪيئن لکجي اسپرنگ بوٽ ايپليڪيشن کي مانيٽر ڪرڻ لاءِ ايئر ٽڪيٽ جي قيمتن جي قدم قدم تي. مضمون جو مقصد انهن ماڻهن لاءِ آهي جن جي باري ۾ خيال آهي:
  • REST ۽ ڪيئن REST آخر پوائنٽون ٺهيل آهن؛
  • تعلقي ڊيٽابيس؛
  • maven جو ڪم (خاص طور تي، انحصار ڇا آهي)؛
  • JSON اعتراض؛
  • لاگنگ جا اصول.
متوقع رويي:
  1. توهان هڪ مخصوص تاريخ لاءِ اڏام چونڊي سگهو ٿا ۽ ان جي قيمت کي ٽريڪ ڪري سگهو ٿا. استعمال ڪندڙ جي سڃاڻپ اي ميل ايڊريس ذريعي ڪئي وئي آهي. جيترو جلدي هڪ رڪنيت جي قيمت تبديل ڪئي وئي آهي، صارف کي اي ميل ذريعي هڪ نوٽيفڪيشن ملي ٿي.
  2. هر 30 منٽ (هي وقفو application.properties ذريعي ترتيب ڏنو ويو آهي) پرواز جي گھٽ ۾ گھٽ قيمت سڀني رڪنن لاءِ ٻيهر ڳڻپيو وڃي ٿي. جيڪڏهن هڪ قدر گهٽجي وئي آهي، صارف کي اي ميل ذريعي هڪ نوٽيفڪيشن ملندي.
  3. پراڻي پرواز جي تاريخ سان سڀ رڪنيتون ختم ڪيون وينديون.
  4. REST API ذريعي توهان ڪري سگهو ٿا:
    • سبسڪرپشن ٺاهيو؛
    • ترميم ڪريو
    • سڀ رڪنيت حاصل ڪريو اي ميل ذريعي؛
    • رڪنيت ختم ڪريو.

مقصد حاصل ڪرڻ لاء ايڪشن پلان

توهان کي حقيقت سان شروع ڪرڻ جي ضرورت آهي ته پروازن بابت معلومات ڪنهن هنڌ کان وٺڻ جي ضرورت آهي. عام طور تي، ويب سائيٽون هڪ کليل REST API مهيا ڪن ٿيون جنهن ذريعي معلومات حاصل ڪري سگهجي ٿي.

API (ايپليڪيشن پروگرامنگ انٽرفيس) هڪ انٽرفيس آهي جنهن جي ذريعي توهان ايپليڪيشن سان رابطو ڪري سگهو ٿا. هن مان اسان هڪ پل ٺاهي سگهون ٿا ته ڇا هڪ REST API آهي.

هڪ REST API REST درخواستن جو هڪ انٽرفيس آهي جيڪو ويب ايپليڪيشن سان رابطو ڪرڻ لاءِ استعمال ٿي سگهي ٿو.

ائين ڪرڻ لاء، اسان استعمال ڪنداسين Skyscanner ، يا بلڪه، API ( Rakuten API ويب سائيٽ تي ). اڳيون، توهان کي بنيادي بنياد طور صحيح فريم ورڪ چونڊڻ جي ضرورت آهي. سڀ کان وڌيڪ مشهور ۽ مطالبو ۾ آهي بهار جي ماحولياتي نظام ۽ انهن جي تخليق جو تاج - بهار بوٽ. توھان انھن جي سرڪاري ويب سائيٽ ڏانھن وڃو، يا توھان ھبري تي مضمون پڙھي سگھو ٿا . صارف جي رڪنن کي ذخيرو ڪرڻ لاءِ اسان استعمال ڪنداسين بلٽ ان H2 ڊيٽابيس . JSON کان ڪلاس ۽ پوئتي پڙهڻ لاءِ، اسان استعمال ڪنداسين جڪسن پروجيڪٽ ( هتي اسان جي وسيلن تي لنڪ آهي ). اسان استعمال ڪنداسين spring-boot-starter-mail صارفين کي پيغام موڪلڻ لاءِ . ايپليڪيشن لاءِ ڏنل تعدد تي گھٽ ۾ گھٽ قيمت ٻيهر ڳڻڻ لاءِ، اسان استعمال ڪنداسين اسپرنگ شيڊيولر . هڪ REST API ٺاهڻ لاءِ اسان استعمال ڪنداسين spring-boot-starter-web . قرضدار ڪوڊ نه لکڻ لاءِ (getters, setters, override equals and hashcode, toString() شين لاءِ)، اسان استعمال ڪنداسين Project Lombok . REST API کي محسوس ڪرڻ ۽ ڏسڻ لاءِ، اسان استعمال ڪنداسين Swagger 2 ۽ فوري طور تي Swagger UI (يوزر انٽرفيس) حقيقي وقت جي ٽريڪنگ لاءِ. ھتي اھو آھي جيڪو ھاڻي ڏسڻ ۾ اچي ٿو: ايئر ٽڪيٽ جي قيمت مانيٽرنگ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [حصو 1] - 2جتي 4 باقي سوال آھن جيڪي ٺاھڻ، ايڊٽ ڪرڻ، حاصل ڪرڻ ۽ سبسڪرپشن کي ختم ڪرڻ سان لاڳاپيل آھن.

Skyscanner API جي ڳولا ڪريو

اچو ته rakuten api جي لنڪ جي پيروي ڪريون . پهرين توهان کي رجسٽر ڪرڻ جي ضرورت آهي. ايئر ٽڪيٽ جي قيمت مانيٽرنگ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [حصو 1] - 3اهو سڀ ڪجهه ان جي سائيٽ کي استعمال ڪرڻ لاء هڪ منفرد چيڪ حاصل ڪرڻ جي ضرورت آهي ۽ ان تي پوسٽ ڪيل عوامي APIs کي درخواستون ڏيڻ لاء. انهن APIs مان هڪ آهي Skyscanner Flight Search جنهن جي اسان کي ضرورت آهي . هاڻي اچو ته سمجهون ته اهو ڪيئن ڪم ڪري ٿو. اچو ته ڳوليون GET List Places جي درخواست. تصوير ڏيکاري ٿي ته توهان کي ڊيٽا ڀرڻ ۽ ٽيسٽ Endpoint شروع ڪرڻ جي ضرورت آهي ، جنهن جي نتيجي ۾ اسان کي ساڄي پاسي JSON اعتراض جي صورت ۾ جواب ملي ٿو: ايئر ٽڪيٽ جي قيمتن جي نگراني لاءِ هڪ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [حصو 1] - 4۽ درخواست هن طرح ٺاهي ويندي:

https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/autosuggest/v1.0/{country}/{currency}/{locale}/?query={query}
۽ سڀئي پيٽرول هن فارمولا ۾ تبديل ڪيا ويندا، اسان حاصل ڪريون ٿا:

https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/autosuggest/v1.0/UK/GBP/en-GB/?query=Stockholm
۽ ٻه هيڊر انهن درخواستن تي منظور ڪيا ويندا:

.header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
.header("x-rapidapi-key", "sing-up-for-key"),
جتي sign-up-for-keyرجسٽريشن کان پوءِ جاري ڪيو ويندو. قيمت جي گھٽتائي کي ٽريڪ ڪرڻ لاء، اسان کي براؤز ڪوٽس جي آخري پوائنٽ جي ضرورت پوندي. پاڻ ڳوليو :)

اسپرنگ بوٽ جي بنياد تي ايپليڪيشن فريم ورڪ ٺاهڻ

اسپرنگ بوٽ سان جلدي ۽ آساني سان پروجيڪٽ ٺاهڻ لاءِ، توهان استعمال ڪري سگهو ٿا Spring Initializr . ھيٺ ڏنل اختيارن کي چونڊيو:
  1. ميون پروجيڪٽ
  2. جاوا
  3. 2.1.10
  4. گروپ - جيڪو توھان سمجھو ضروري آھي، مثال طور ru.javarush
  5. artifact - بلڪل ساڳيو، مثال طور پروازن جي نگراني
  6. انحصار جي ڳولا ۾ اسين هيٺيان ڳوليندا آهيون:
    • اسپرنگ ويب
    • جاوا ميل موڪليندڙ
    • بهار جي ڊيٽا Jpa
    • H2 ڊيٽابيس
۽ پوءِ ڪلڪ ڪريو ٺاھيو . اھو اھو آھي: ختم ٿيل پروجيڪٽ آرڪائيو طور ڊائون لوڊ ڪيو ويندو. جيڪڏهن ڪجهه ڪم نٿو ڪري، توهان لنڪ استعمال ڪري سگهو ٿا جتي مون گهربل پروجيڪٽ محفوظ ڪيو . يقينا، اهو بهتر آهي ته اهو پنهنجو پاڻ ڪريو ۽ سمجھو ته اهو ڪيئن ڪم ڪري ٿو. اپليڪيشن ٽن تہن تي مشتمل هوندي:
  • ڪنٽرولر - ايپليڪيشن ۾ لاگ ان ٿيو. REST API هتي بيان ڪيو ويندو
  • SERVICE هڪ ڪاروباري منطقي پرت آهي. اپليڪيشن جو سڄو منطق هتي بيان ڪيو ويندو.
  • ذخيرو - ڊيٽابيس سان ڪم ڪرڻ لاء پرت.
انهي سان گڏ، اسڪائ اسڪينر فلائيٽ سرچ API لاءِ ڪلائنٽ سان لاڳاپيل ڪلاس هڪ الڳ پيڪيج هوندو.

اسان پروجيڪٽ ۾ Skyscanner Flight Search API جي درخواستن لاءِ ڪلائنٽ لکي رهيا آهيون

Skyscanner مھرباني ڪري ھڪڙو مضمون مهيا ڪيو آھي انھن جي API کي ڪيئن استعمال ڪجي (اسين فعال درخواست سان سيشن نه ٺاھينداسين). ان جو مطلب ڇا آهي "هڪ ڪلائنٽ لکڻ"؟ اسان کي ضرورت آھي ھڪڙي مخصوص URL لاءِ درخواست ٺاھڻ جي ضرورت آھي خاص پيٽرولن سان ۽ ھڪ ڊي ٽي او تيار ڪرڻي آھي (ڊيٽا ٽرانسفر اعتراض) جيڪو اسان ڏانھن واپس منتقل ڪيو ويو آھي. سائيٽ تي درخواستن جا چار گروپ آھن:
  1. لائيو فلائيٽ ڳولا - اسان ان کي هن وقت غير ضروري نه سمجهنداسين.
  2. جڳهيون - اچو ته لکون.
  3. برائوز پرواز جي قيمتون - اسان ھڪڙي درخواست استعمال ڪنداسين جتي توھان حاصل ڪري سگھوٿا سڀ معلومات.
  4. Localization - اچو ته ان کي شامل ڪريون ته جيئن اسان ڄاڻون ته ڪهڙي ڊيٽا کي سپورٽ ڪيو ويو آهي.

مقامي ڪرڻ جي درخواست لاءِ ڪلائنٽ سروس ٺاهيو:

منصوبو هڪ ٻاڦ واري ٽرپ وانگر سادو آهي: هڪ درخواست ٺاهيو، پيرا ميٽرز کي ڏسو، جواب ڏسو. هتي ٻه سوال آهن: لسٽ مارڪر ۽ ڪرنسي. اچو ته ڪرنسي سان شروع ڪريون. انگ اکر ڏيکاري ٿو ته هي هڪ درخواست آهي بغير اضافي شعبن جي: ان کي گهربل ڪرنسي بابت معلومات حاصل ڪرڻ لاءِ گهربل آهي: ايئر ٽڪيٽ جي قيمت مانيٽرنگ سسٽم ٺاهڻ: هڪ قدم قدم گائيڊ [حصو 1] - 6جواب JSON اعتراض جي صورت ۾ آهي، جنهن ۾ ساڳيون شيون شامل آهن، مثال طور:
{
"Code":"LYD"
"Symbol":"د.ل.‏"
"ThousandsSeparator":","
"DecimalSeparator":"."
"SymbolOnLeft":true
"SpaceBetweenAmountAndSymbol":false
"RoundingCoefficient":0
"DecimalDigits":3
}
اچو ته هن اعتراض لاءِ هڪ ڪرنسي ڊيٽو ٺاهيو:
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
* Data transfer object for Currency.
*/
@Data
public class CurrencyDto {

   @JsonProperty("Code")
   private String code;

   @JsonProperty("Symbol")
   private String symbol;

   @JsonProperty("ThousandsSeparator")
   private String thousandsSeparator;

   @JsonProperty("DecimalSeparator")
   private String decimalSeparator;

   @JsonProperty("SymbolOnLeft")
   private boolean symbolOnLeft;

   @JsonProperty("SpaceBetweenAmountAndSymbol")
   private boolean spaceBetweenAmountAndSymbol;

   @JsonProperty("RoundingCoefficient")
   private int roundingCoefficient;

   @JsonProperty("DecimalDigits")
   private int decimalDigits;
}
ڪٿي:
  • @Data لومبوڪ پروجيڪٽ مان هڪ تشريح آهي ۽ سڀ حاصل ڪندڙ، سيٽرز، اووررائڊز toString()، equals() ۽ hashCode() طريقا ٺاهي ٿو. ڇا ڪوڊ پڙهڻ جي صلاحيت کي بهتر بڻائي ٿو ۽ POJO شيون لکڻ جي وقت کي تيز ڪري ٿو ؛
  • @JsonProperty("ڪوڊ") جڪسن پروجيڪٽ مان هڪ تشريح آهي جيڪا ٻڌائي ٿي ته هن متغير کي ڪهڙي فيلڊ تفويض ڪئي ويندي. اھو آھي، ھڪڙو فيلڊ JSON ۾ ڪوڊ جي برابر آھي ڪوڊ متغير کي تفويض ڪيو ويندو .
Skyscanner کان سرڪاري آرٽيڪل REST درخواستن لاءِ UniRest لائبريري استعمال ڪرڻ جو مشورو ڏئي ٿو . تنهن ڪري، اسان هڪ ٻي خدمت لکنداسين جيڪا درخواستن تي عمل ڪندي REST ذريعي. هي ٿيندو UniRestService . هن کي ڪرڻ لاء، maven ڏانهن هڪ نئين انحصار شامل ڪريو:
<dependency>
  <groupId>com.mashape.unirest</groupId>
  <artifactId>unirest-java</artifactId>
  <version>1.4.9</version>
</dependency>
اڳيون، اسان هڪ خدمت لکنداسين جيڪو انجام ڏيندو REST درخواستون. يقينن، هر ڪلائنٽ/سروس لاءِ اسان هڪ انٽرفيس ٺاهينداسين ۽ ان تي عمل درآمد ڪنداسين:
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;

/**
* Service, which is manipulating with Rest calls.
*/
public interface UniRestService {

   /**
   * Create GET request based on provided {@param path} with needed headers.
   *
   * @param path provided path with all the needed data
   * @return {@link HttpResponse<jsonnode>} response object.
   */
   HttpResponse<jsonnode> get(String path);

}
۽ ان تي عملدرآمد:
import com.github.romankh3.flightsmonitoring.exception.FlightClientException;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
* {@inheritDoc}
*/
@Slf4j
@Service
public class UniRestServiceImpl implements UniRestService {

   public static final String HOST = "https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com";

   public static final String PLACES_FORMAT = "/apiservices/autosuggest/v1.0/%s/%s/%s/?query=%s";
   public static final String CURRENCIES_FORMAT = "/apiservices/reference/v1.0/currencies";
   public static final String COUNTRIES_FORMAT = "/apiservices/reference/v1.0/countries/%s";

   public static final String PLACES_KEY = "Places";
   public static final String CURRENCIES_KEY = "Currencies";
   public static final String COUNTRIES_KEY = "Countries";

   @Value("${x.rapid.api.key}")
   private String xRapidApiKey;

   /**
    * {@inheritDoc}
    */
   @Override
   public HttpResponse<jsonnode> get(String path) {
       HttpResponse<jsonnode> response = null;
       try {
           response = Unirest.get(HOST + path)
                   .header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
                   .header("x-rapidapi-key", xRapidApiKey)
                   .asJson();
       } catch (UnirestException e) {
           throw new FlightClientException(String.format("Request failed, path=%s", HOST + path), e);
       }

       log.info("Response from Get request, on path={}, statusCode={}, response={}", path, response.getStatus(), response.getBody().toString());
       return response;
   }
}
ان جو خلاصو اهو آهي ته سڀئي درخواستون جن ۾ اسان دلچسپي رکون ٿا اهي GET درخواستن لاءِ ٺاهيا ويا آهن، ۽ هي خدمت تيار ڪيل درخواست قبول ڪري ٿي ۽ ضروري هيڊر شامل ڪري ٿي جهڙوڪ:
.header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
.header("x-rapidapi-key", xRapidApiKey)
ملڪيتن مان ڊيٽا وٺڻ لاءِ، @Value تشريح استعمال ڪريو جيئن ھيٺ ڏيکاريل آھي:
@Value("${x.rapid.api.key}")
private String xRapidApiKey;
اهو چوي ٿو ته application.properties ۾ x.rapid.api.key نالي هڪ ملڪيت هوندي، جنهن کي هن متغير ۾ داخل ٿيڻ جي ضرورت آهي. اسان هارڊ ڪوڊ ٿيل قدرن کان نجات حاصل ڪندا آهيون ۽ پروگرام ڪوڊ مان هن متغير جي تعريف حاصل ڪندا آهيون. ان کان علاوه، جڏهن آئون هن ايپليڪيشن کي GitHub تي شايع ڪريان ٿو ته آئون هن ملڪيت جي قيمت شامل نه ڪندس. اهو سيڪيورٽي سببن لاء ڪيو ويو آهي. اسان هڪ خدمت لکيو آهي جيڪا ڪم ڪندي REST درخواستن سان، هاڻي اهو وقت آهي لوڪلائيزيشن جي خدمت لاءِ. اسان OOP جي بنياد تي هڪ ايپليڪيشن ٺاهي رهيا آهيون، تنهنڪري اسان ٺاهي رهيا آهيون LocalizationClient انٽرفيس ۽ ان تي عمل ڪرڻ LocalisationClientImpl :
import com.github.romankh3.flightsmonitoring.client.dto.CountryDto;
import com.github.romankh3.flightsmonitoring.client.dto.CurrencyDto;
import java.io.IOException;
import java.util.List;

/**
* Client for SkyScanner localisation.
*/
public interface LocalisationClient {

   /**
    * Retrieve the market countries that SkyScanner flight search API support. Most suppliers (airlines,
    * travel agents and car hire dealers) set their fares based on the market (or country of purchase).
    * It is therefore necessary to specify the market country in every query.
    *
    * @param locale locale of the response.
    *
    * @return the collection of the {@link CountryDto} objects.
    *
    * @throws IOException
    */
   List<CountryDto> retrieveCountries(String locale);

   /**
    * Retrieve the currencies that we ScyScanner flight search API.
    *
    * @return the collection of the {@link CurrencyDto} objects.
    *
    * @throws IOException
    */
   List<CurrencyDto> retrieveCurrencies();

}
۽ LocalizationClientImpl جو نفاذ
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.COUNTRIES_FORMAT;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.COUNTRIES_KEY;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.CURRENCIES_FORMAT;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.CURRENCIES_KEY;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.romankh3.flightsmonitoring.client.dto.CountryDto;
import com.github.romankh3.flightsmonitoring.client.dto.CurrencyDto;
import com.github.romankh3.flightsmonitoring.client.service.LocalisationClient;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* {@inheritDoc}
*/
@Component
public class LocalisationClientImpl implements LocalisationClient {

   @Autowired
   private UniRestService uniRestService;

   @Autowired
   private ObjectMapper objectMapper;

   /**
    * {@inheritDoc}
    */
   @Override
   public List<CountryDto> retrieveCountries(String locale) throws IOException {
       HttpResponse<JsonNode> response = uniRestService.get(String.format(COUNTRIES_FORMAT, locale));

       if (response.getStatus() != HttpStatus.SC_OK) {
           return null;
       }

       String jsonList = response.getBody().getObject().get(COUNTRIES_KEY).toString();

       return objectMapper.readValue(jsonList, new TypeReference<List<CountryDto>>() {
       });
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public List<CurrencyDto> retrieveCurrencies() throws IOException, UnirestException {

       HttpResponse<JsonNode> response = uniRestService.get(CURRENCIES_FORMAT);
       if (response.getStatus() != HttpStatus.SC_OK) {
           return null;
       }

       String jsonList = response.getBody().getObject().get(CURRENCIES_KEY).toString();

       return objectMapper.readValue(jsonList, new TypeReference<List<CurrencyDto>>() {
       });
   }
}
ڪٿي
  • @Autowired هڪ تشريح آهي جيڪا چوي ٿي ته توهان کي ڪنهن شئي کي هن ڪلاس ۾ داخل ڪرڻ جي ضرورت آهي ۽ ان کي ٺاهڻ کان سواءِ استعمال ڪريو، اهو آهي، نئين آبجیکٹ آپريشن کان سواءِ؛
  • @Component هڪ تشريح آهي جيڪا چوي ٿي ته هن اعتراض کي اپليڪيشن جي حوالي سان شامل ڪيو وڃي ته جيئن ان کي بعد ۾ @Autowired annotation استعمال ڪندي انجيڪشن ڪري سگهجي.
  • ObjectMapper ObjectMapper جڪسن پروجيڪٽ مان ھڪڙو اعتراض آھي جيڪو ھن سڀني کي جاوا جي شين ۾ ترجمو ڪري ٿو.
  • ڪرنسي ڊي ٽي او ۽ ملڪ ڊيٽو:
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
* Data transfer object for Currency.
*/
@Data
public class CurrencyDto {

   @JsonProperty("Code")
   private String code;

   @JsonProperty("Symbol")
   private String symbol;

   @JsonProperty("ThousandsSeparator")
   private String thousandsSeparator;

   @JsonProperty("DecimalSeparator")
   private String decimalSeparator;

   @JsonProperty("SymbolOnLeft")
   private boolean symbolOnLeft;

   @JsonProperty("SpaceBetweenAmountAndSymbol")
   private boolean spaceBetweenAmountAndSymbol;

   @JsonProperty("RoundingCoefficient")
   private int roundingCoefficient;

   @JsonProperty("DecimalDigits")
   private int decimalDigits;
}
	и
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
* Data transfer object for Country.
*/
@Data
public class CountryDto {

   @JsonProperty("Code")
   private String code;

   @JsonProperty("Name")
   private String name;
}
پروجيڪٽ جي ڪنهن به حصي ۾ ObjectMapper کي انجڻ ڪرڻ لاءِ، مون ان کي ٺاھڻ ۽ شامل ڪرڻ شامل ڪيو آھي ApplicationContext ۾ ترتيب ڏيڻ واري ڪلاس ذريعي.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* {@link Configuration} class.
*/
@Configuration
public class Config {

   @Bean
   public ObjectMapper objectMapper() {
       ObjectMapper objectMapper = new ObjectMapper();
       objectMapper.registerModule(new JavaTimeModule());
       return objectMapper;
   }
}
@Configuration تشريح بهار کي ٻڌائي ٿي ته هن ڪلاس ۾ ڪجهه ترتيبون هونديون. ۽ صرف ان لاءِ مون ObjectMapper شامل ڪيو. اهڙي طرح، اسان PlacesClient ۽ PlacesClientImpl شامل ڪندا آهيون:
import com.github.romankh3.flightsmonitoring.client.dto.PlaceDto;
import com.github.romankh3.flightsmonitoring.client.dto.PlacesDto;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.IOException;
import java.util.List;

/**
* SkyScanner client.
*/
public interface PlacesClient {

   /**
    * Get a list of places that match a query string based on arguments.
    *
    * @param query the code of the city.
    * @param country the code of the country.
    * @param currency the code of the currency.
    * @param locale the code of the locale.
    * @return the collection of the {@link PlaceDto} objects.
    */
   List<PlacesDto> retrieveListPlaces(String query, String country, String currency, String locale)
           throws IOException, UnirestException;
}
۽
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.PLACES_FORMAT;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.PLACES_KEY;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.romankh3.flightsmonitoring.client.dto.PlacesDto;
import com.github.romankh3.flightsmonitoring.client.service.PlacesClient;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* {@inheritDoc}
*/
@Service
public class PlacesClientImpl implements PlacesClient {

   @Autowired
   private UniRestService uniRestService;

   @Autowired
   private ObjectMapper objectMapper;


   /**
    * {@inheritDoc}
    */
   @Override
   public List<PlacesDto> retrieveListPlaces(String query, String country, String currency, String locale)
           throws IOException, UnirestException {
       HttpResponse<JsonNode> response = uniRestService
               .get(String.format(PLACES_FORMAT, country, currency, locale, query));

       if (response.getStatus() != HttpStatus.SC_OK) {
           return null;
       }

       String jsonList = response.getBody().getObject().get(PLACES_KEY).toString();

       return objectMapper.readValue(jsonList, new TypeReference<List<PlacesDto>>() {
       });
   }
}
جتي PlacesDto فارم آهي:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.romankh3.flightsmonitoring.client.service.PlacesClient;
import lombok.Data;

/**
* Using for {@link PlacesClient}.
*/
@Data
public class PlacesDto {

   @JsonProperty("PlaceId")
   private String placeId;

   @JsonProperty("PlaceName")
   private String placeName;

   @JsonProperty("CountryId")
   private String countryId;

   @JsonProperty("RegionId")
   private String regionId;

   @JsonProperty("CityId")
   private String cityId;

   @JsonProperty("CountryName")
   private String countryName;
}
۽ آخرڪار، هڪ ڪلائنٽ سروس جيڪا، ضروري ڊيٽا جي بنياد تي، پرواز جي گھٽ ۾ گھٽ قيمت ۽ تمام ضروري معلومات واپس ڪندي: FlightPriceClient ۽ FlightPriceClientImpl. اسان صرف هڪ درخواست تي عمل ڪنداسين، برائوز ڪوٽس. پرواز جي قيمت ڪلائنٽ:
import com.github.romankh3.flightsmonitoring.client.dto.FlightPricesDto;

/**
* Browse flight prices.
*/
public interface FlightPricesClient {

   /**
    * Browse quotes for current flight based on provided arguments. One-way ticket.
    *
    * @param country the country from
    * @param currency the currency to get price
    * @param locale locale for the response
    * @param originPlace origin place
    * @param destinationPlace destination place
    * @param outboundPartialDate outbound date
    * @return {@link FlightPricesDto} object.
    */
   FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate);

   /**
    * Browse quotes for current flight based on provided arguments. Round trip ticket.
    *
    * @param country the country from
    * @param currency the currency to get price
    * @param locale locale for the response
    * @param originPlace origin place
    * @param destinationPlace destination place
    * @param outboundPartialDate outbound date
    * @param inboundPartialDate inbound date
    * @return {@link FlightPricesDto} object.
    */
   FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate, String inboundPartialDate);
}
FlightPriceClientImpl
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.CURRENCIES_KEY;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.PLACES_KEY;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.romankh3.flightsmonitoring.client.dto.CarrierDto;
import com.github.romankh3.flightsmonitoring.client.dto.CurrencyDto;
import com.github.romankh3.flightsmonitoring.client.dto.FlightPricesDto;
import com.github.romankh3.flightsmonitoring.client.dto.PlaceDto;
import com.github.romankh3.flightsmonitoring.client.dto.QuoteDto;
import com.github.romankh3.flightsmonitoring.client.dto.ValidationErrorDto;
import com.github.romankh3.flightsmonitoring.client.service.FlightPricesClient;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.github.romankh3.flightsmonitoring.exception.FlightClientException;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* {@inheritDoc}
*/
@Service
public class FlightPricesClientImpl implements FlightPricesClient {

   public static final String BROWSE_QUOTES_FORMAT = "/apiservices/browsequotes/v1.0/%s/%s/%s/%s/%s/%s";
   public static final String OPTIONAL_BROWSE_QUOTES_FORMAT = BROWSE_QUOTES_FORMAT + "?inboundpartialdate=%s";

   public static final String QUOTES_KEY = "Quotes";
   public static final String ROUTES_KEY = "Routes";
   public static final String DATES_KEY = "Dates";
   public static final String CARRIERS_KEY = "Carriers";
   public static final String VALIDATIONS_KEY = "ValidationErrors";

   @Autowired
   private UniRestService uniRestService;

   @Autowired
   private ObjectMapper objectMapper;

   /**
    * {@inheritDoc}
    */
   @Override
   public FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate) {

       HttpResponse<JsonNode> response = uniRestService.get(String
               .format(BROWSE_QUOTES_FORMAT, country, currency, locale, originPlace, destinationPlace,
                       outboundPartialDate));
       return mapToObject(response);
   }

   public FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate, String inboundPartialDate) {
       HttpResponse<JsonNode> response = uniRestService.get(String
               .format(OPTIONAL_BROWSE_QUOTES_FORMAT, country, currency, locale, originPlace, destinationPlace,
                       outboundPartialDate, inboundPartialDate));
       return mapToObject(response);
   }

   private FlightPricesDto mapToObject(HttpResponse<JsonNode> response) {
       if (response.getStatus() == HttpStatus.SC_OK) {
           FlightPricesDto flightPricesDto = new FlightPricesDto();
           flightPricesDto.setQuotas(readValue(response.getBody().getObject().get(QUOTES_KEY).toString(),
                   new TypeReference<List<QuoteDto>>() {
                   }));
           flightPricesDto.setCarriers(readValue(response.getBody().getObject().get(CARRIERS_KEY).toString(),
                   new TypeReference<List<CarrierDto>>() {
                   }));
           flightPricesDto.setCurrencies(readValue(response.getBody().getObject().get(CURRENCIES_KEY).toString(),
                   new TypeReference<List<CurrencyDto>>() {
                   }));
           flightPricesDto.setPlaces(readValue(response.getBody().getObject().get(PLACES_KEY).toString(),
                   new TypeReference<List<PlaceDto>>() {
                   }));
           return flightPricesDto;
       }
       throw new FlightClientException(String.format("There are validation errors. statusCode = %s", response.getStatus()),
               readValue(response.getBody().getObject().get(VALIDATIONS_KEY).toString(),
                       new TypeReference<List<ValidationErrorDto>>() {
                       }));
   }

   private <T> List<T> readValue(String resultAsString, TypeReference<List<T>> valueTypeRef) {
       List<T> list;
       try {
           list = objectMapper.readValue(resultAsString, valueTypeRef);
       } catch (IOException e) {
           throw new FlightClientException("Object Mapping failure.", e);
       }
       return list;
   }
}
جتي FlightClientException نظر اچي ٿو:
import com.github.romankh3.flightsmonitoring.client.dto.ValidationErrorDto;
import java.util.List;

/**
* A {@link RuntimeException} that is thrown in case of an flight monitoring failures.
*/
public final class FlightClientException extends RuntimeException {

   public FlightClientException(String message) {
       super(message);
   }

   public FlightClientException(String message, Throwable throwable) {
       super(message, throwable);
   }

   public FlightClientException(String message, List<ValidationErrorDto> errors) {
       super(message);
       this.validationErrorDtos = errors;
   }

   private List<ValidationErrorDto> validationErrorDtos;
}
نتيجي طور، PlacesCl کان ڊيٽا جي مطابق
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION