Проблема с кодировкой UTF-8 в Windows

Я разработал небольшое Java-приложение Swing для поиска статистики персонажей в World of Warcraft с их API-интерфейсом разработчика с использованием Netbeans в Ubuntu Gnome 14.04. Все работает так, как я задумал, за исключением кнопки, которая вызывает метод, открывающий ссылку в браузере по умолчанию на профиль указанного персонажа. В Ubuntu строка, которую я использую в URL-адресе, отображается правильно, а в Windows — нет. Если я запускаю приложение (в Windows) с помощью пакетного файла, который указывает кодировку UTF-8 для JVM, у меня нет этой проблемы. При запуске его непосредственно из файла .jar такие символы, как «â», регистрируются как «Ã¢» в URL-адресе в Windows, несмотря на мою попытку закодировать все мои строки как UTF-8. Как я могу получить URL-адрес в правильном формате? Я предполагаю, что я что-то упускаю. Если вам нужно увидеть больше кода, дайте мне знать. Заранее спасибо.

ArmoryScanner_UI.java

private void openArmoryLink() {

    ArmoryScanner_Backend armory = new ArmoryScanner_Backend();       
    String name;
    String realm;
    String locale;

    try {
        name = new String(jTextField_Name.getText().getBytes("UTF-8"));

        realm = jComboBox_Realm.getSelectedItem().toString();
        locale = jComboBox_Locale.getSelectedItem().toString();

        if (!name.trim().isEmpty()) {

            name = formatName(name);
            realm = formatRealm(realm);
            locale = formatLocale(locale);

            armory.setPlayerInfo(name, realm, locale);

            if (armory.isCharacterFound()) {
                armory.setArmoryLink();
            } else {
                showErrorMessage("Character not found.");
                jTextField_Name.setText("");
                jTextField_Name.setCaretPosition(0);
                jTextField_Name.requestFocus();
            }

        } else {
            showErrorMessage("Please enter a character name.");
            jTextField_Name.setText("");
            jTextField_Name.setCaretPosition(0);
            jTextField_Name.requestFocus();
        }
    } catch (UnsupportedEncodingException e) {
        showErrorMessage("Error converting name to UTF-8\n"
                + e.getMessage());
    }
}

private String formatName(String name) {

    String result;
    try {
        result = new String(name.getBytes("UTF-8"), "UTF-8");

    } catch (UnsupportedEncodingException e) {
        showErrorMessage("Error converting name to UTF-8\n"
                + e.getMessage());
        result = "";
    }

    return result;
}

ArmoryScanner_Backend.java

public void setArmoryLink () {

    try {

        String baseURL = "https://us.battle.net/wow/en/character/";
        String fullURL = (baseURL + realm + "/" + name + "/simple");
        System.out.println("Full URL: " + fullURL);

        if (Desktop.isDesktopSupported()) {
            Desktop.getDesktop().browse(new URL(fullURL).toURI());
        } else {
            Runtime runtime = Runtime.getRuntime();
            try {
                runtime.exec("xdg-open " + fullURL);
            } catch (IOException e) {
                System.out.println("I/O exception (non-Windows system)");
            }
        }
    } catch (UnsupportedOperationException e) {
        System.out.println("Unsupported OS");
    } catch (MalformedURLException e) {
        System.out.println("Bad URL");
    } catch (IOException e) {
        System.out.println("I/O exception.");
    } catch (URISyntaxException e) {
        System.out.println("Bad URI syntax");
    }

}

Этот метод отлично работает:

private void submit() {

    this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

    ArmoryScanner_Backend armory = new ArmoryScanner_Backend();       
    String name;
    String realm;
    String locale;

    try {

        name = new String(jTextField_Name.getText().getBytes("UTF-8"));

        realm = jComboBox_Realm.getSelectedItem().toString();
        locale = jComboBox_Locale.getSelectedItem().toString();

        if (!name.trim().isEmpty()) {

            name = formatName(name);
            realm = formatRealm(realm);
            locale = formatLocale(locale);

            armory.setPlayerInfo(name, realm, locale);

            if (armory.isCharacterFound()) {

                setStatistics(armory);
                setProgression(armory);

            } else {
                showErrorMessage("Character not found.");
                jTextField_Name.setText("");
                jTextField_Name.setCaretPosition(0);
                jTextField_Name.requestFocus();
            }

        } else {
            showErrorMessage("Please enter a character name.");
            jTextField_Name.setText("");
            jTextField_Name.setCaretPosition(0);
            jTextField_Name.requestFocus();
        }

    } catch (UnsupportedEncodingException e) {
        showErrorMessage("Error converting name to UTF-8\n"
                + e.getMessage());
    }

   this.setCursor(Cursor.getDefaultCursor());
}

person Mithrandir1210    schedule 19.02.2016    source источник
comment
â является кодировкой UTF-8. Проблема в том, что все, что преобразует это в глиф, не установлено в кодировке UTF-8 и пытается отобразить его, как если бы это был ASCII.   -  person Jim Garrison    schedule 19.02.2016
comment
Чтобы быстрее получить помощь, опубликуйте минимально воспроизводимый пример или Короткий, автономный, правильный пример.   -  person Andrew Thompson    schedule 19.02.2016
comment
url - единственная часть, где вам нужно использовать явную кодировку UTF-8, а здесь этого делать нельзя :) URLEncoder.encode(stringToBeEncoded, "UTF-8")   -  person RobAu    schedule 19.02.2016


Ответы (1)


Java использует Unicode внутри, поэтому вам обычно не нужно устанавливать кодировку, ЗА ИСКЛЮЧЕНИЕМ, когда вы читаете/записываете внешние ресурсы.

Там вам нужно иметь это явно.

В вашем случае вам нужно кодировать элементы URL-адреса с помощью класса URLEncoder.

Ознакомьтесь с документацией.

person Angelo Fuchs    schedule 19.02.2016
comment
Это не могло бы работать более совершенно. Большое спасибо. - person Mithrandir1210; 21.02.2016