JavaRush /Блоги Java /Random-TG /Таъсиси системаи мониторинги нархи чиптаҳои ҳавопаймо: да...
Roman Beekeeper
Сатҳи

Таъсиси системаи мониторинги нархи чиптаҳои ҳавопаймо: дастури қадам ба қадам [Қисми 1]

Дар гурӯҳ нашр шудааст

Мундариҷа:

Таъсиси системаи мониторинги нархи чиптаҳои ҳавопаймо: дастури қадам ба қадам [Қисми 1] - 1Салом ба ҳама, ҷомеаи JavaRush! Имрӯз мо дар бораи чӣ гуна навиштани замимаи Spring Boot барои мониторинги нархи чиптаҳои ҳавопаймо қадам ба қадам сӯҳбат хоҳем кард. Мақола барои одамоне пешбинӣ шудааст, ки дар бораи:
  • REST ва чӣ гуна нуқтаҳои ниҳоии REST сохта мешаванд;
  • пойгоҳи додаҳои релятсионӣ;
  • кори мавен (аз ҷумла, вобастагӣ чист);
  • an objectи JSON;
  • принсипҳои бақайдгирӣ.
Рафтори интизорӣ:
  1. Шумо метавонед парвозро барои санаи мушаххас интихоб кунед ва нархи онро пайгирӣ кунед. Истифодабаранда бо суроғаи почтаи электронӣ муайян карда мешавад. Ҳамин ки обуна ба тағирёбии нарх сурат мегирад, корбар тавассути почтаи электронӣ огоҳинома мегирад.
  2. Ҳар 30 дақиқа (ин фосила тавассути application.properties танзим карда мешавад) нархи ҳадди ақали парвоз барои ҳама обунаҳо аз нав ҳисоб карда мешавад. Агар яке аз арзишҳо паст шавад, корбар тавассути почтаи электронӣ огоҳинома мегирад.
  3. Ҳама обунаҳое, ки санаи парвози кӯҳна доранд, нест карда мешаванд.
  4. Тавассути REST API шумо метавонед:
    • эҷод кардани обуна;
    • таҳрир;
    • ҳама обунаҳоро тавассути почтаи электронӣ қабул кунед;
    • нест кардани обуна.

Нақшаи амал барои ноил шудан ба ҳадаф

Шумо бояд аз он оғоз кунед, ки маълумот дар бораи парвозҳо бояд аз ҷое гирифта шавад. Одатан, вебсайтҳо API-и кушодаи REST-ро пешниҳод мекунанд, ки тавассути он маълумотро гирифтан мумкин аст.

API (интерфейси барномасозии барнома) интерфейсест, ки тавассути он шумо метавонед бо барнома ҳамкорӣ кунед. Аз ин мо метавонем пуле созем, ки REST API чист.

REST API интерфейси дархостҳои REST мебошад, ки метавонад барои муошират бо барномаи веб истифода шавад.

Барои ин, мо Skyscanner , ё на, API-ро истифода хоҳем бурд (дар вебсайти Rakuten API ). Баъдан, шумо бояд чаҳорчӯбаи дурустро ҳамчун таҳкурсии асосӣ интихоб кунед. Маъмултарин ва серталаб экосистемаи баҳорӣ ва тоҷи офариниши онҳо - Spring Boot мебошад. Шумо метавонед ба вебсайти расмии онҳо равед, ё шумо метавонед мақоларо дар Habré хонед . Барои нигоҳ доштани обунаҳои корбар, мо базаи дохorи H2 -ро истифода мебарем . Барои хондан аз JSON то дарсҳо ва бозгашт, мо лоиҳаи Ҷексонро истифода хоҳем бурд ( инҷо истиноди манбаи мост ). Мо барои ирсоли паёмҳо ба корбарон spring-boot-starter-mail-ро истифода хоҳем бурд .. Барои он ки барнома нархи ҳадди ақалро дар басомади додашуда дубора ҳисоб кунад, мо баҳори Scheduler -ро истифода мебарем . Барои сохтани REST API мо spring-boot-starter-web -ро истифода хоҳем бурд . Барои навиштани рамзи қарзӣ (гирандагон, танзимкунандаҳо, override equals ва hashcode, toString() барои an objectҳо), мо Project Lombok -ро истифода мебарем . Барои эҳсос ва дидани REST API, мо Swagger 2 ва фавран Swagger UI (интерфейси корбар) -ро барои пайгирии вақти воқеӣ истифода хоҳем кард. Ҳоло он чӣ гуна аст: Таъсиси системаи мониторинги нархи чиптаҳои ҳавопаймо: дастури қадам ба қадам [Қисми 1] - 2дар он ҷо 4 дархости боқимонда мавҷуданд, ки ба эҷод, таҳрир, гирифтан ва нест кардани обунаҳо мувофиқанд.

Омӯзиши API Skyscanner

Биёед ба истиноди api rakuten пайравӣ кунем . Аввал шумо бояд сабти ном шавед.Ҳамаи Таъсиси системаи мониторинги нархи чиптаҳои ҳавопаймо: дастури қадам ба қадам [Қисми 1] - 3ин барои гирифтани калиди нодир барои истифодаи сайти онҳо ва дархост ба API-ҳои ҷамъиятӣ, ки дар он ҷойгир шудаанд, лозим аст. Яке аз ин APIҳо ҷустуҷӯи парвози Skyscanner мебошад, ки ба мо лозим аст . Акнун биёед бифаҳмем, ки он чӣ гуна кор мекунад. Биёед дархости GET List Places-ро пайдо кунем. Тасвир нишон медиҳад, ки шумо бояд маълумотро пур кунед ва Test Endpoint -ро оғоз кунед , ки дар натиҷа мо дар шакли an objectи 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пас аз бақайдгирӣ дода мешавад. Барои пайгирии коҳиши нарх, ба мо нуқтаи ниҳоии Browse Quotes лозим аст . Худатон пайдо кунед :)

Эҷоди чаҳорчӯбаи барномаҳо дар асоси Spring Boot

Барои зуд ва осон сохтани лоиҳа бо Spring Boot, шумо метавонед Spring Initializr -ро истифода баред . Имконоти зеринро интихоб кунед:
  1. Лоиҳаи Maven
  2. Java
  3. 2.1.10
  4. гурӯҳ - ҳар кадоме, ки ба назари шумо лозим аст, масалан ru.javarush
  5. артефакт - маҳз ҳамин тавр, масалан парвозҳо-мониторинг
  6. дар ҷустуҷӯи вобастагӣ мо инҳоро меҷӯем:
    • Веб баҳор
    • Ирсолкунандаи почтаи Java
    • Маълумоти баҳори Jpa
    • Пойгоҳи додаҳои H2
Ва он гоҳ клик кунед Эҷод кунед . Ин аст: лоиҳаи анҷомёфта ҳамчун бойгонӣ зеркашӣ карда мешавад. Агар чизе кор накунад, шумо метавонед истинодро истифода баред, ки ман лоиҳаи дилхоҳро захира кардам . Албатта, беҳтар аст, ки ин корро худатон кунед ва фаҳмед, ки он чӣ гуна кор мекунад. Ариза аз се қабат иборат хоҳад буд:
  • CONTROLLER - ворид шудан ба барнома. REST API дар ин ҷо тавсиф карда мешавад
  • ХИЗМАТРАСОН як қабати мантиқии тиҷорат аст. Тамоми мантиқи барнома дар ин ҷо тавсиф карда мешавад.
  • РЕПОЗИТОРИЯ - қабат барои кор бо пойгоҳи додаҳо.
Инчунин, дарсҳои марбут ба муштарӣ барои Skyscanner Flight Search API бастаи алоҳида хоҳанд буд.

Мо барои дархостҳо ба API Skyscanner Flight Search дар лоиҳа муштарӣ менависем

Skyscanner бо меҳрубонӣ мақолаеро дар бораи чӣ гуна истифода бурдани API-и онҳо пешкаш кардааст (мо сессияро бо дархости фаъол эҷод намекунем). "Навиштани муштарӣ" чӣ маъно дорад? Мо бояд дархостро ба URL-и мушаххас бо параметрҳои муайян эҷод кунем ва барои маълумоте, ки ба мо баргардонида мешавад, DTO (an objectи интиқоли маълумот) омода кунем. Дар сайт чаҳор гурӯҳи дархостҳо мавҷуданд:
  1. Ҷустуҷӯи парвози мустақим - мо онро дар айни замон нолозим намешуморем.
  2. Ҷойҳо - биёед нависед.
  3. Аз назар гузаронии нархҳои парвоз - мо як дархостро истифода хоҳем бурд, ки дар он шумо тамоми маълумотро дастрас карда метавонед.
  4. Маҳаллисозӣ - биёед онро илова кунем, то бидонем, ки кадом маълумот дастгирӣ мешавад.

Барои дархости маҳаллисозӣ хидмати муштарӣ эҷод кунед:

Нақша мисли шалғам пухташуда оддӣ аст: дархост эҷод кунед, ба параметрҳо нигаред, ба ҷавоб нигаред. Ду дархост вуҷуд дорад: Нишондиҳандаҳои рӯйхат ва асъор. Биёед бо асъорҳо оғоз кунем. Дар расм нишон медиҳад, ки ин дархост бидуни майдонҳои иловагӣ аст: он барои гирифтани маълумот дар бораи асъорҳои дастгиришаванда лозим аст: Таъсиси системаи мониторинги нархи чиптаҳои ҳавопаймо: дастури қадам ба қадам [Қисми 1] - 6Ҷавоб дар шакли an objectи JSON мебошад, ки маҷмӯи ҳамон an objectҳоро дар бар мегирад, масалан:
{
"Code":"LYD"
"Symbol":"د.ل.‏"
"ThousandsSeparator":","
"DecimalSeparator":"."
"SymbolOnLeft":true
"SpaceBetweenAmountAndSymbol":false
"RoundingCoefficient":0
"DecimalDigits":3
}
Биёед барои ин an object CurrencyDto эҷод кунем:
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 тавзеҳи лоиҳаи Lombok аст ва ҳамаи усулҳои қабулкунанда, танзимкунанда, бекоркунии toString(), equals() ва hashCode()-ро тавлид мекунад. Чӣ хониши codeро беҳтар мекунад ва вақти навиштани an objectҳои POJO -ро метезонад ;
  • @JsonProperty("Код") эзоҳ аз Лоиҳаи Ҷексон аст, ки мегӯяд, ки кадом соҳа ба ин тағирёбанда таъин карда мешавад. Яъне, майдони дар JSON баробар ба Кодекс ба тағирёбандаи code таъин карда мешавад .
Мақолаи расмии Skyscanner пешниҳод мекунад, ки китобхонаи UniRest барои дархостҳои REST истифода шавад . Аз ин рӯ, мо хидмати дигаре хоҳем навишт, ки дархостҳоро тавассути 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 хоҳад буд, ки бояд ба ин тағирёбанда ворид карда шавад. Мо аз арзишҳои сахт codeшуда халос мешавем ва таърифи ин тағирёбандаро аз рамзи барнома мегирем. Ғайр аз он, вақте ки ман ин барномаро дар 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();

}
ва татбиқи LocalisationClientImpl
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 шарҳест, ки мегӯяд, ки шумо бояд an objectро ба ин синф ворид кунед ва онро бидуни эҷоди он, яъне бидуни амалиёти нави Object истифода баред;
  • @Component эзоҳест, ки мегӯяд, ки ин an object бояд ба Контексти Ариза илова карда шавад, то он баъдтар бо истифода аз шарҳи @Autowired ворид карда шавад;
  • ObjectMapper objectMapper an objectи лоиҳаи Ҷексон мебошад, ки ҳамаи инро ба an objectҳои Java тарҷума мекунад.
  • CurrencyDTO ва CountryDto:
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. Мо танҳо як дархостро иҷро хоҳем кард, browseQuotes. FlightPriceClient:
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