Hamıya salam! Teleqramlar üçün botların yaradılması mövzusu bir qədər sındırılıb və bir çox bələdçi yazılıb (məsələn, bu ) . Buna görə də, bəzi üçüncü tərəf API ilə işləməyə daha yaxından nəzər salmaq daha yaxşıdır, çünki bu, hər hansı bir veb tərtibatçı üçün kritik bir bacarıqdır. Dərhal deyim ki, proqram ən funksional və faydalı proqnozu təmin etmək məqsədi daşımamışdır; hava saytları ilə rəqabət aparmağın mənası yoxdur; Java istifadə edərək uzaq bağlantılarla və məlumat təhlili ilə necə işləməyi öyrənmək vacib idi. Beləliklə, əvvəlcə bizə nə lazım olduğunu öyrənək. Tətbiqimiz əsasən üç məntiqi hissədən ibarətdir:
- istifadəçidən mesaj qəbul edin
- mesajı emal edin və əgər bu düzgün əmrdirsə, cavab üçün məlumat hazırlayın. Bizim vəziyyətimizdə, istifadəçi düzgün şəhərə giribsə, hava proqnozu hazırlayın
- chatda istifadəçiyə hazır məlumat göndərin
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Belə bir sorğuya cavabın brauzerdə necə göründüyünü görə bilərsiniz.Biz artıq müəyyən etdik ki, əslində, sadəcə olaraq düzgün linki izləmək lazımdır və server lazımi məlumatları təqdim edəcəkdir. Yalnız Java istifadə edərək bunu necə edəcəyinizi öyrənməkdir. Java-da sadə GET sorğusu belə görünür:
//создаём строку со ссылкой на нужную page,
//я тут её склеиваю из заранее определённых констант, меняя только сам город
String urlString = API_CALL_TEMPLATE + city + API_KEY_TEMPLATE;
//создаём an object который будет содержать ссылку
URL urlObject = new URL(urlString);
//создаём соединение, используя an object
HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
//выбираем тип requestа (GET)
connection.setRequestMethod("GET");
//тут мы указываем, данные о себе, что мы можем принять всё то,
//что примет и любой современный браузер
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
//В начало ответа server всегда вставляет число, по которому можно судить, прошло ли всё хорошо.
//200 - значит OK
int responseCode = connection.getResponseCode();
//на несуществующий город or город с опечаткой, server выдаст code ответа 404,
//бросаем на него исключение, чтобы обработать на уровне повыше и предложить
//пользователю ввести город заново
if (responseCode == 404) {
throw new IllegalArgumentException();
}
// создаём поток, вычитываем все строки, и склеиваем в одну большую строку,
//которую будем потом обрабатывать в других методах
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
Əgər sorğu düzgün olsaydı və server mövcud olsaydı, biz faydalı məlumatın indi lazım olmayan məlumatlarla qarışdığı məlumat vərəqini alacağıq. JSON və XML-dən lazımi məlumatları rahat şəkildə çıxarmaq üçün Java üçün hər zövqə uyğun tonlarla kitabxanalar yazılmışdır. JSON-a üstünlük verdiyim üçün onu emal etmək üçün Jackson adlı çox məşhur bir kitabxana seçdim. Yeri gəlmişkən, JavaRush-da bəzi yüksək səviyyədə bir az öyrənilir. Böyük həcmdə JSON məlumatlarını emal etmək üçün sənədin strukturunu başa düşmək vacibdir. Bu kimi faydalı saytlar köməyə gəlir . Solda orijinal JSON, sağda - strukturlaşdırılmışdır: Görünür ki, cavab 5 yüksək səviyyəli JSON obyektindən ibarətdir, onlardan 2-si mürəkkəbdir və aşağıdakı filiallar üçün qovşaqdır. Bizi maraqlandıran məlumatlar siyahı qovşağında saxlanılır . Daxili siyahı hər biri müəyyən vaxtda havanı təsvir edən 38 JSON xəttindən ibarətdir. Yəni bir növ ağaca bənzər quruluşdur, burada kök, budaqlar, budaqlar və hətta yarpaqlar var :) Və düyünlərdə budaqlanma baş verir. Xoşbəxtlikdən, Cekson istənilən etibarlı JSON-u ağac kimi təmsil edə bilər. Beləliklə, bizə lazım olan atributun adını (məsələn, havanın temperaturu) və ağacın hansı səviyyəsində yerləşdiyini bilmək, onu əldə etmək çox problem olmayacaq. Əvvəlcə "list" massivindən bütün sətirləri çıxardım və onları ayrıca siyahıya əlavə etdim. Kobud desək, məlumatların olduğu vərəqi parçalara ayırdım, hər biri ayrıca proqnozdur. Kiçik hissələri yadda saxlamaq və onlarla işləmək daha asandır.
//JsonNode - это один из узлов в древовидной иерархии, от которого идут ветви
//получаем узел, который называется "list"
JsonNode arrNode = new ObjectMapper().readTree(data).get("list");
//если это действительно массив узлов
if (arrNode.isArray()) {
//выполняем для каждого узла, который содержится в массиве
for (final JsonNode objNode : arrNode) {
//в атрибуте "dt_txt" каждого маленького узла хранилось время прогноза, я отобрал данные за 9 утра и 6 вечера
String forecastTime = objNode.get("dt_txt").toString();
if (forecastTime.contains("09:00") || forecastTime.contains("18:00")) {
weatherList.add(objNode.toString());
}
}
}
Beləliklə, hər bir sətir müəyyən bir zamanda JSON hava hesabatını əks etdirən sətirlərin siyahısını əldə etdik. Qalan şey istədiyinizi çıxarmaq və formatlaşdırmaqdır. Əgər belə bir xəttimiz varsa:
"main":{"temp":261.45,"temp_min":259.086,"temp_max":261.45,"pressure":1023.48,"sea_level":1045.39,"grnd_level":1023.48,"humidity":79,"temp_kf":2.37}
onda bu "əsas" adlı bir qovşaqdır. Ondan istənilən məlumatı, məsələn, dəniz səviyyəsini əldə etmək üçün aşağıdakı kod kifayətdir:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson məlumatları dərhal rəqəmsal formatda təqdim etməyə imkan verir:
double seaLevel = mainNode.get("sea_level").asDouble();
İndi biz proqnozdan istənilən məlumatı çıxara bilərik və qalan yalnız onu istədiyiniz kimi yapışdırıb Telegram-da istifadəçiyə göndərməkdir. Tam mənbə kodu mənim githubumdadır , lakin siz linkdən istifadə edərək və ya Telegram axtarışında @denifoBot taparaq botu işlədə sınaya bilərsiniz . Şəhərin adı latın transliterasiyası ilə yazılmalıdır, məsələn, "Kiyev" və ya "Moskva". Təşəkkür edirəm, əgər bunu sona çatdırsanız, məntiqli tənqidi qəbul edirəm, çünki mən şəhərimdən ac istedadlarla rəqabət aparmaq üçün GitHub-da sadə layihələr öyrənirəm və inkişaf etdirirəm :) Hamıya əlvida! P.S. İnanıram ki, burada hərf səhvləri ola bilər, ona görə də hər şeyi şəxsi mesajda və ya həqiqətən qəzəblisinizsə şərhdə göndərə bilərsiniz :)
GO TO FULL VERSION