#java #json #telegram #telegram-bot
#java #json #telegram #telegram-бот
Вопрос:
Я создаю бота для словаря Google, используя этот APIhttps://dictionaryapi.dev /. Предполагается, что он показывает определения слов на разных языках. И бот отлично работает для английского и испанского языков. Но каждый раз, когда я вставляю русские слова, возникает исключение IOException. Что может быть причиной этого?
Вот мой класс Bot. Bot.java:
public void onUpdateReceived(Update update) {
//Model model = new Model();
WordModel wordModel = new WordModel();
Message message = update.getMessage();
if (message != null amp;amp; message.hasText())
{
switch (message.getText()) {
case "/english":
DictionaryEntry.setLanguage("en");
sendMsg(message, DictionaryEntry.getLanguage());
break;
case "/russian":
DictionaryEntry.setLanguage("ru");
sendMsg(message, DictionaryEntry.getLanguage());
break;
case "/spanish":
DictionaryEntry.setLanguage("es");
sendMsg(message, DictionaryEntry.getLanguage());
break;
default:
if (!message.getText().contains("/")) {
try {
sendMsgs(message, DictionaryEntry.getWords(message.getText(), wordModel));
} catch (IOException e) {
sendMsg(message, "Не найдено");
sendMsg(message, DictionaryEntry.getUrl().toString());
}
}
break;
}
}
}
public void sendMsg(Message message, String text) {
SendMessage sendMessage = new SendMessage();
sendMessage.setChatId(message.getChatId());
sendMessage.setReplyToMessageId(message.getMessageId());
sendMessage.setText(text);
try {
//setButtons(sendMessage);
execute(sendMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
public void sendMsgs(Message message, List<String> words) {
for (int i = 0; i < words.size(); i ) {
SendMessage sendMessage = new SendMessage();
sendMessage.setChatId(message.getChatId());
sendMessage.setReplyToMessageId(message.getMessageId());
sendMessage.setText(words.get(i));
try {
//setButtons(sendMessage);
execute(sendMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
И вот мой класс DictionaryEntry, в котором я обрабатываю строку JSON, которую я получаю из URL.
DictionaryEntry.java:
private static String language = "ru";
public static String getLanguage() {
return language;
}
public static void setLanguage(String language) {
DictionaryEntry.language = language;
}
public static URL getUrl() {
return url;
}
private static URL url;
public static List<String> getWords(String message, WordModel wordModel) throws IOException {
url = new URL("https://api.dictionaryapi.dev/api/v2/entries/"
DictionaryEntry.getLanguage() "/" message);
Scanner in = new Scanner((InputStream) url.getContent());
String result = "";
while (in.hasNext())
{
result = in.nextLine();
}
String result2 = result.replaceAll(""", "\"");
List<WordModel> models = new ArrayList<>();
List<String> results = new ArrayList<>();
int count = 0;
try {
JSONArray mainArray = new JSONArray(result2);
for (int i = 0; i < mainArray.length(); i ) {
JSONObject wordEntry = mainArray.getJSONObject(i);
String wordName = wordEntry.getString("word");
wordModel.setWord(wordName);
JSONArray meaningsArray = wordEntry.getJSONArray("meanings");
for (int j = 0; j < meaningsArray.length(); j ) {
JSONObject meaningEntry = meaningsArray.getJSONObject(j);
JSONArray definitionsArray = meaningEntry.getJSONArray("definitions");
for (int k = 0; k < definitionsArray.length(); k ) {
//count ;
JSONObject definitionEntry = definitionsArray.getJSONObject(k);
String definition = definitionEntry.getString("definition");
wordModel.setDefinition(definition);
if (definitionEntry.has("example")) {
count ;
String example = definitionEntry.getString("example");
wordModel.setExample(example);
}
else {
wordModel.setExample("No examples found");
}
models.add(wordModel);
results.add("Word: " wordModel.getWord() "nn"
"Definition: " wordModel.getDefinition() "nn"
"Example: " wordModel.getExample());
}
}
}
/*result = "Word: " wordModel.getWord() "nn"
"Definition: " wordModel.getDefinition() "nn"
"Example: " wordModel.getExample();*/
} catch (JSONException e) {
count = 50;
}
results.add(url.toString());
return results;
}
Вот трассировка стека:
java.io.IOException: Server returned HTTP response code: 400 for URL: https://api.dictionaryapi.dev/api/v2/entries/ru/мышь
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1932)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1528)
at java.base/java.net.URLConnection.getContent(URLConnection.java:749)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getContent(HttpsURLConnectionImpl.java:404)
at java.base/java.net.URL.getContent(URL.java:1181)
at DictionaryEntry.getWords(DictionaryEntry.java:73)
at Bot.onUpdateReceived(Bot.java:91)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.telegram.telegrambots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:321)
Комментарии:
1. Вы проверили сообщение внутри исключения? Он может содержать некоторую полезную информацию.
2. Что говорит исключение IOException? Показать сообщение и трассировку стека.
3. Добавлена трассировка стека
4. Что ж, похоже, что вызываемому вами серверу не нравятся символы кириллицы в URL
5. @BiT4000 может быть нормально кодировать только
message
значение переменной.
Ответ №1:
URLEncoder.encode(message, "UTF-8")
Вы отправляете HTTP-запрос. URL-адрес должен соответствовать используемой кодировке.
Есть и другие аспекты использования правильной кодировки, но этого может быть уже достаточно. Сайт, вероятно, использует UTF-8, поскольку он может обрабатывать полный диапазон Unicode.
400 — НЕВЕРНЫЙ ЗАПРОС.
url = new URL("https://api.dictionaryapi.dev/api/v2/entries/"
DictionaryEntry.getLanguage() "/"
URLEncoder.encode(message, "UTF-8"));
И
Scanner in = new Scanner((InputStream) url.getContent(),
StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
while (in.hasNextLine())
{
sb.append(in.nextLine()).append('n');
}
String result = sb.toString();
Комментарии:
1. Что именно я должен кодировать? Каким здесь должно быть «сообщение»? Мой URL?
2. Хорошо, проверил код. StringBuilder вместо цикла со строкой
=
, даже если здесь можно ожидать не так много строк.result = "rn";
забыто.3. Я закодировал слово на русском, которое я отправляю. Теперь это работает. Спасибо, что нашли время.
Ответ №2:
Проверьте в своей среде, что файл был в формате utf-8u, поскольку кириллица может не поддерживаться
Комментарии:
1. Как это сделать?
2. Пожалуйста, добавьте такого рода уточняющие идеи в качестве комментариев. Это не является ответом, решающим проблему, с которой сталкивается OP.
3. @BiT4000 Если вы работаете в Intellij: Файл -> Настройки -> Редактор -> Кодировки файлов