将 String 转换为 Android JSONObject 丢失 utf-8
Converting String to Android JSONObject loses utf-8
我正在尝试从 URL 获取(JSON 格式的)字符串并将其作为 Json 对象使用。当我将字符串转换为 JSONObject.
时,我丢失了 UTF-8 编码
这是我用来连接到 url 并获取字符串的函数:
private static String getUrlContents(String theUrl) {
StringBuilder content = new StringBuilder();
try {
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line + "\n");
}
bufferedReader.close();
} catch(Exception e) {
e.printStackTrace();
}
return content.toString();
}
当我从服务器获取数据时,以下代码显示正确的字符:
String output = getUrlContents(url);
Log.i("message1", output);
但是当我将输出字符串转换为 JSONObject 时,波斯字符变成了这样的问号 ??????。 (messages是JSON中的数组名)
JSONObject reader = new JSONObject(output);
String messages = new String(reader.getString("messages").getBytes("ISO-8859-1"), "UTF-8");
Log.i("message2", messages);
你告诉 Java 使用 ISO-8859-1 将字符串(使用键 message
)转换为字节,而不是从这些字节创建一个新的字符串,解释为 UTF- 8.
new String(reader.getString("messages").getBytes("ISO-8859-1"), "UTF-8");
您可以简单地使用:
String messages = reader.getString("messages");
不确定这是否有帮助,但您可以这样做:
JSONObject result = null;
String str = null;
try
{
str = new String(output, "UTF-8");
result = (JSONObject) new JSONTokener(str).nextValue();
}
catch (Exception e) {}
String messages = result.getString("messages");
您可以按如下方式更新您的代码:
private static String getUrlContents(String theUrl) {
StringBuilder content = new StringBuilder();
try {
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line).append("\n");
}
bufferedReader.close();
} catch(Exception e) {
e.printStackTrace();
}
return content.toString().trim();
}
您有两个编码问题:
服务器发送以字符集编码的文本。设置 InputStreamReader 时,需要传递服务器使用的编码,以便正确解码。字符编码通常在 Content-type
HTTP 响应中的 charset
字段中给出。 JSON 通常是 UTF-8 编码,但也可以是合法的 UTF-16 和 UTF-32,因此您需要检查。如果没有指定的编码,您的系统环境将在将字节编组为字符串时使用,反之亦然。基本上,您应该始终指定字符集。
String messages = new String(reader.getString("messages").getBytes("ISO-8859-1"), "UTF-8");
显然会引起问题(如果你有 non-ascii 个字符)——它将字符串编码为 ISO-8995-1,然后尝试将其解码为UTF-8。
在读取输入流之前,可以使用一个简单的正则表达式模式从 Content-type header 中提取 charset
值。我还包含了一个简洁的 InputStream -> String 转换器。
private static String getUrlContents(String theUrl) {
try {
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
InputStream is = urlConnection.getInputStream();
// Get charset field from Content-Type header
String contentType = urlConnection.getContentType();
// matches value in key / value pair
Pattern encodingPattern = Pattern.compile(".*charset\s*=\s*([\w-]+).*");
Matcher encodingMatcher = encodingPattern.matcher(contentType);
// set charsetString to match value if charset is given, else default to UTF-8
String charsetString = encodingMatcher.matches() ? encodingMatcher.group(1) : "UTF-8";
// Quick way to read from InputStream.
// \A is a boundary match for beginning of the input
return new Scanner(is, charsetString).useDelimiter("\A").next();
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
我正在尝试从 URL 获取(JSON 格式的)字符串并将其作为 Json 对象使用。当我将字符串转换为 JSONObject.
时,我丢失了 UTF-8 编码这是我用来连接到 url 并获取字符串的函数:
private static String getUrlContents(String theUrl) {
StringBuilder content = new StringBuilder();
try {
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line + "\n");
}
bufferedReader.close();
} catch(Exception e) {
e.printStackTrace();
}
return content.toString();
}
当我从服务器获取数据时,以下代码显示正确的字符:
String output = getUrlContents(url);
Log.i("message1", output);
但是当我将输出字符串转换为 JSONObject 时,波斯字符变成了这样的问号 ??????。 (messages是JSON中的数组名)
JSONObject reader = new JSONObject(output);
String messages = new String(reader.getString("messages").getBytes("ISO-8859-1"), "UTF-8");
Log.i("message2", messages);
你告诉 Java 使用 ISO-8859-1 将字符串(使用键 message
)转换为字节,而不是从这些字节创建一个新的字符串,解释为 UTF- 8.
new String(reader.getString("messages").getBytes("ISO-8859-1"), "UTF-8");
您可以简单地使用:
String messages = reader.getString("messages");
不确定这是否有帮助,但您可以这样做:
JSONObject result = null;
String str = null;
try
{
str = new String(output, "UTF-8");
result = (JSONObject) new JSONTokener(str).nextValue();
}
catch (Exception e) {}
String messages = result.getString("messages");
您可以按如下方式更新您的代码:
private static String getUrlContents(String theUrl) {
StringBuilder content = new StringBuilder();
try {
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line).append("\n");
}
bufferedReader.close();
} catch(Exception e) {
e.printStackTrace();
}
return content.toString().trim();
}
您有两个编码问题:
服务器发送以字符集编码的文本。设置 InputStreamReader 时,需要传递服务器使用的编码,以便正确解码。字符编码通常在
Content-type
HTTP 响应中的charset
字段中给出。 JSON 通常是 UTF-8 编码,但也可以是合法的 UTF-16 和 UTF-32,因此您需要检查。如果没有指定的编码,您的系统环境将在将字节编组为字符串时使用,反之亦然。基本上,您应该始终指定字符集。String messages = new String(reader.getString("messages").getBytes("ISO-8859-1"), "UTF-8");
显然会引起问题(如果你有 non-ascii 个字符)——它将字符串编码为 ISO-8995-1,然后尝试将其解码为UTF-8。
在读取输入流之前,可以使用一个简单的正则表达式模式从 Content-type header 中提取 charset
值。我还包含了一个简洁的 InputStream -> String 转换器。
private static String getUrlContents(String theUrl) {
try {
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
InputStream is = urlConnection.getInputStream();
// Get charset field from Content-Type header
String contentType = urlConnection.getContentType();
// matches value in key / value pair
Pattern encodingPattern = Pattern.compile(".*charset\s*=\s*([\w-]+).*");
Matcher encodingMatcher = encodingPattern.matcher(contentType);
// set charsetString to match value if charset is given, else default to UTF-8
String charsetString = encodingMatcher.matches() ? encodingMatcher.group(1) : "UTF-8";
// Quick way to read from InputStream.
// \A is a boundary match for beginning of the input
return new Scanner(is, charsetString).useDelimiter("\A").next();
} catch(Exception e) {
e.printStackTrace();
}
return null;
}