Кодировка Java UTF-8 не установлена ​​в URLConnection - PullRequest
11 голосов
/ 20 января 2012

Я пытаюсь получить данные из http://api.freebase.com/api/trans/raw/m/0h47

Как вы можете видеть в тексте, поет так: /ælˈdʒɪəriə/.

Когда я пытаюсь получить источник изНа странице я получаю текст с такими словами, как ú и т. д.

До сих пор я пробовал использовать следующий код:

urlConnection.setRequestProperty("Accept-Charset", "UTF-8");
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

Что я делаю неправильно?

Весь мой код:

URL url = null;
URLConnection urlConn = null;
DataInputStream input = null;
try {
url = new URL("http://api.freebase.com/api/trans/raw/m/0h47");
} catch (MalformedURLException e) {e.printStackTrace();}

try {
    urlConn = url.openConnection(); 
} catch (IOException e) { e.printStackTrace(); }
urlConn.setRequestProperty("Accept-Charset", "UTF-8");
urlConn.setRequestProperty("Content-Type", "text/plain; charset=utf-8");

urlConn.setDoInput(true);
urlConn.setUseCaches(false);

StringBuffer strBseznam = new StringBuffer();
if (strBseznam.length() > 0)
    strBseznam.deleteCharAt(strBseznam.length() - 1);

try {
    input = new DataInputStream(urlConn.getInputStream()); 
} catch (IOException e) { e.printStackTrace(); }
String str = "";
StringBuffer strB = new StringBuffer();
strB.setLength(0);
try {
    while (null != ((str = input.readLine()))) 
    {
        strB.append(str); 
    }
    input.close();
} catch (IOException e) { e.printStackTrace(); }

Ответы [ 3 ]

13 голосов
/ 20 января 2012

HTML-страница имеет формат UTF-8 и может использовать арабские символы и тому подобное.Но эти символы выше Unicode 127 все еще закодированы как числовые объекты, такие как ú.Accept-Encoding не будет помогать и загружаться, так как UTF-8 совершенно прав.

Вы должны декодировать объекты самостоятельно.Что-то вроде:

String decodeNumericEntities(String s) {
    StringBuffer sb = new StringBuffer();
    Matcher m = Pattern.compile("\\&#(\\d+);").matcher(s);
    while (m.find()) {
        int uc = Integer.parseInt(m.group(1));
        m.appendReplacement(sb, "");
        sb.appendCodepoint(uc);
    }
    m.appendTail(sb);
    return sb.toString();
}

Кстати, эти сущности могут происходить из обработанных HTML-форм, поэтому на стороне редактирования веб-приложения.


Послерассматриваемый код:

Я заменил DataInputStream на (Buffered) Reader для текста.InputStreams читает двоичные данные, байты;Читатели текстовые, струнные.InputStreamReader имеет в качестве параметра InputStream и кодировку и возвращает Reader.

try {
    BufferedReader input = new BufferedReader(
            new InputStreamReader(urlConn.getInputStream(), "UTF-8")); 
    StringBuilder strB = new StringBuilder();
    String str;
    while (null != (str = input.readLine())) {
        strB.append(str).append("\r\n"); 
    }
    input.close();
} catch (IOException e) {
    e.printStackTrace();
}
5 голосов
/ 17 августа 2015

Попробуйте добавить также пользовательский агент к вашему URLConnection:

urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36");

Это решило мою проблему с декодированием, как талисман.

2 голосов
/ 20 января 2012

Ну, я думаю, проблема в том, что вы читаете из потока. Вы должны либо вызвать метод readUTF на DataInputStream вместо вызова readLine, либо, что я бы сделал, создать InputStreamReader и установить кодировку, после чего вы можете прочитать из строки BufferedReader построчно (это будет внутри вашего существующего try / catch):

Charset charset = Charset.forName("UTF8");
InputStreamReader stream = new InputStreamReader(urlConn.getInputStream(), charset);
BufferedReader reader = new BufferedReader(stream);
StringBuffer responseBuffer = new StringBuffer();

String read = "";
while ((read = reader.readLine()) != null) {
    responseBuffer.append(read);
}
...