Hai semua! Topik mencipta bot untuk Telegram agak digodam, dan banyak panduan telah ditulis (contohnya, yang ini ) . Oleh itu, lebih baik kita melihat dengan lebih dekat bekerja dengan beberapa API pihak ketiga, kerana ini adalah kemahiran kritikal untuk mana-mana pembangun web. Saya akan mengatakan dengan segera bahawa aplikasi itu tidak ditetapkan untuk menyediakan ramalan yang paling berfungsi dan berguna; tidak ada gunanya bersaing dengan tapak cuaca; adalah penting untuk belajar cara bekerja dengan sambungan jauh dan penghuraian data menggunakan Java. Jadi, mari kita ketahui apa yang kita perlukan dahulu. Aplikasi kami pada dasarnya terdiri daripada tiga bahagian logik:
- terima mesej daripada pengguna
- memproses mesej, dan, jika ia adalah perintah yang sah, sediakan data untuk respons. Dalam kes kami, sediakan ramalan cuaca jika pengguna memasuki bandar yang betul
- menghantar maklumat sedia kepada pengguna dalam sembang
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Anda boleh melihat bagaimana tindak balas kepada permintaan sedemikian kelihatan dalam penyemak imbas. Kami telah mengetahui bahawa, sebenarnya, anda hanya perlu mengikuti pautan yang betul dan pelayan akan memberikan data yang diperlukan. Yang tinggal hanyalah mempelajari cara melakukan ini menggunakan Java. Permintaan GET mudah dalam Java kelihatan seperti ini:
//создаём строку со ссылкой на нужную 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();
Jika permintaan itu betul dan pelayan tersedia, kami akan menerima helaian data di mana maklumat berguna dicampur dengan maklumat yang tidak diperlukan sekarang. Untuk mengekstrak data yang diperlukan dengan mudah daripada JSON dan XML, banyak perpustakaan telah ditulis untuk Java untuk memenuhi setiap citarasa. Memandangkan saya lebih suka JSON, saya memilih perpustakaan yang sangat popular yang dipanggil Jackson untuk memprosesnya. Dengan cara ini, ia dikaji sedikit dalam JavaRush pada beberapa tahap tinggi. Untuk memproses sejumlah besar data JSON, adalah penting untuk memahami struktur dokumen. Tapak berguna seperti ini datang untuk menyelamatkan . Di sebelah kiri kami mempunyai JSON asal, di sebelah kanan - yang berstruktur: Dapat dilihat bahawa respons terdiri daripada 5 objek JSON peringkat atas, 2 daripadanya kompleks dan merupakan nod untuk cawangan berikut. Data yang kami minati disimpan dalam nod senarai . Senarai dalam ialah tatasusunan 38 baris JSON, setiap satu menerangkan cuaca pada masa tertentu. Iaitu, ia adalah sejenis struktur seperti pokok, di mana terdapat akar, dahan, ranting dan juga daun :) Dan pada nod cawangan berlaku. Nasib baik, Jackson boleh mewakili mana-mana JSON yang sah sebagai pokok. Oleh itu, mengetahui nama atribut yang kita perlukan (contohnya, suhu udara), dan pada tahap mana pokok itu terletak, mendapatkannya tidak akan menjadi masalah. Mula-mula, saya mengekstrak semua baris dari tatasusunan "senarai" dan menambahkannya ke senarai berasingan. Secara kasarnya, saya memotong helaian dengan data menjadi kepingan, setiap satunya adalah ramalan yang berasingan. Bahagian kecil lebih mudah diingat dan dikendalikan.
//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());
}
}
}
Jadi kami mendapat senarai rentetan, di mana setiap baris mewakili laporan cuaca JSON pada masa tertentu. Yang tinggal hanyalah mengekstrak apa yang anda mahu dan memformatnya. Jika kita mempunyai baris seperti ini:
"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}
maka ini adalah nod yang dipanggil "utama". Untuk mendapatkan sebarang data daripadanya, contohnya paras laut, kod berikut sudah memadai:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson membenarkan anda untuk segera mewakili data dalam format angka:
double seaLevel = mainNode.get("sea_level").asDouble();
Kini kami boleh mengekstrak sebarang data daripada ramalan, dan yang tinggal hanyalah melekatkannya bersama-sama seperti yang dikehendaki dan menghantarnya kepada pengguna dalam Telegram. Kod sumber penuh ada pada github saya , tetapi anda boleh mencuba bot dalam tindakan menggunakan pautan , atau dengan mencari @denifoBot dalam carian Telegram. Nama bandar mesti ditulis dalam transliterasi Latin, contohnya "Kyiv" atau "Moscow". Terima kasih, jika anda berjaya sehingga tamat, saya menerima kritikan yang munasabah, kerana saya baru belajar dan membangunkan projek mudah di GitHub untuk bersaing dengan bakat lapar dari bandar saya :) Selamat tinggal semua! PS Saya percaya bahawa mungkin terdapat kesilapan menaip di sini, jadi anda boleh menghantar segala-galanya dalam mesej peribadi, atau dalam komen jika anda benar-benar marah :)
GO TO FULL VERSION