简体   繁体   中英

Russian language causing IOException

I'm making the bot for Google Dictionary using this API https://dictionaryapi.dev/ . It's supposed to show word definitions in different languages. And the bot works just fine for English and Spanish. But there's an IOException every time I put in Russian words. What can be the cause of it?

Here's my Bot class. Bot.java:

public void onUpdateReceived(Update update) {
        //Model model = new Model();
        WordModel wordModel = new WordModel();
        Message message = update.getMessage();
        if (message != null && 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();
            }
        }
    }

And here's my DictionaryEntry class where I process JSON string that I get from 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() + "\n\n" +
                                "Definition: " + wordModel.getDefinition() + "\n\n" +
                                "Example: " + wordModel.getExample());
                    }
                }
            }

            /*result = "Word: " + wordModel.getWord() + "\n\n" +
                     "Definition: " + wordModel.getDefinition() + "\n\n" +
                     "Example: " + wordModel.getExample();*/
        } catch (JSONException e) {
            count = 50;
        }

        results.add(url.toString());

        return results;
    }

Here's the stack trace:

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)
+ URLEncoder.encode(message, "UTF-8")

You are sending a HTTP request. The URL should be appropriate for the used encoding.

There are more aspects of using the right charset/encoding, but this might already be sufficient. The site probably uses UTF-8, as that can handle the full Unicode range.

400 is BAD REQUEST.


url = new URL("https://api.dictionaryapi.dev/api/v2/entries/"
            + DictionaryEntry.getLanguage() + "/"
            + URLEncoder.encode(message, "UTF-8"));

And

    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();

在您的环境中检查文件是否为 utf-8u 格式 因为可能不支持西里尔文

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM