Java 无法分析和显示从http请求读取的非utf8字符
我正在使用Java解析这个请求 因此,它有一个JSON文件(为了简洁起见被截断):Java 无法分析和显示从http请求读取的非utf8字符,java,json,parsing,encoding,Java,Json,Parsing,Encoding,我正在使用Java解析这个请求 因此,它有一个JSON文件(为了简洁起见被截断): {"responseData":{"results": <...> "visibleUrl":"www.coolcook.net", "cacheUrl":"http://www.google.com/search?q\u003dcache:p4Ke5q6zpnUJ:www.coolcook.net", "title":"مطبخ مطايب - كباب الدجاج والخضار بصلصة
{"responseData":{"results":
<...>
"visibleUrl":"www.coolcook.net",
"cacheUrl":"http://www.google.com/search?q\u003dcache:p4Ke5q6zpnUJ:www.coolcook.net",
"title":"مطبخ مطايب - كباب الدجاج والخضار بصلصة الروب",
"titleNoFormatting":"مطبخ مطايب - كباب الدجاج والخضار بصلصة الروب","\u003drz+img+news+recordid+border"}},
<...>
"responseDetails": null, "responseStatus": 200}
但是,“before”和“after”结果都是相同的:一组???,不管我是在服务器日志文件中还是在HTML页面中输出它们。有没有其他方法可以取回阿拉伯字符并将其输出到网页中
JSON是否有任何支持这类问题的功能,也许是为了直接从JSONObject读取非utf字符?首先尝试以下方法:
str = j.getString("titleNoFormatting");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:/test.txt"), "UTF-8"));
writer.write(str);
writer.close();
然后在记事本中打开文件。如果这看起来不错,那么问题在于记录器或控制台没有配置为使用UTF-8
。否则,问题很可能在于您使用的JSON API没有配置为使用UTF-8
编辑:如果问题实际上存在于所使用的JSON API中,而您不知道该选择哪个,那么我建议您使用。它确实简化了将Json字符串转换为易于使用的javabean的过程。以下是一个基本示例:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.List;
import com.google.gson.Gson;
public class Test {
public static void main(String[] args) throws Exception {
URL url = new URL("http://ajax.googleapis.com/ajax/services/search/web"
+ "?start=0&rsz=large&v=1.0&q=rz+img+news+recordid+border");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
GoogleResults results = new Gson().fromJson(reader, GoogleResults.class);
// Show all results.
System.out.println(results);
// Show title of 1st result (is arabic).
System.out.println(results.getResponseData().getResults().get(0).getTitle());
}
}
class GoogleResults {
ResponseData responseData;
public ResponseData getResponseData() { return responseData; }
public void setResponseData(ResponseData responseData) { this.responseData = responseData; }
public String toString() { return "ResponseData[" + responseData + "]"; }
static class ResponseData {
List<Result> results;
public List<Result> getResults() { return results; }
public void setResults(List<Result> results) { this.results = results; }
public String toString() { return "Results[" + results + "]"; }
}
static class Result {
private String url;
private String title;
public String getUrl() { return url; }
public String getTitle() { return title; }
public void setUrl(String url) { this.url = url; }
public void setTitle(String title) { this.title = title; }
public String toString() { return "Result[url:" + url +",title:" + title + "]"; }
}
}
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.net.URL;
导入java.util.List;
导入com.google.gson.gson;
公开课考试{
公共静态void main(字符串[]args)引发异常{
URL=新URL(“http://ajax.googleapis.com/ajax/services/search/web"
+“?start=0&rsz=large&v=1.0&q=rz+img+news+recordid+border”);
BufferedReader=新的BufferedReader(新的InputStreamReader(url.openStream(),“UTF-8”);
GoogleResults=new Gson().fromJson(reader,GoogleResults.class);
//显示所有结果。
系统输出打印项次(结果);
//显示第一个结果的标题(阿拉伯语)。
System.out.println(results.getResponseData().getResults().get(0.getTitle());
}
}
GoogleResults类{
响应数据响应数据;
public ResponseData getResponseData(){return ResponseData;}
public void setResponseData(ResponseData ResponseData){this.ResponseData=ResponseData;}
公共字符串toString(){return“ResponseData[“+ResponseData+”]”;}
静态类响应数据{
列出结果;
public List getResults(){return results;}
public void setResults(列出结果){this.results=results;}
公共字符串toString(){return“Results[“+Results+”]”;}
}
静态类结果{
私有字符串url;
私有字符串标题;
公共字符串getUrl(){return url;}
公共字符串getTitle(){return title;}
public void setUrl(字符串url){this.url=url;}
public void setTitle(字符串标题){this.title=title;}
公共字符串toString(){return“Result[url:+url+,title:+title+”];}
}
}
它可以很好地输出结果。希望这有帮助。问题的重要部分是如何处理HTTP响应的内容。也就是说,如何创建
json
对象?当您看到原始帖子中的代码时,内容已经损坏
请求产生UTF-8编码数据。如何将其解析为JSON对象?是否为解码器指定了正确的编码?或者正在使用您平台的默认字符编码?谷歌API正确发送UTF-8。我认为问题在于您的默认编码不能输出阿拉伯语。检查您的
文件.encoding
属性或获得如下编码
public static String getDefaultCharSet() throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(new ByteArrayOutputStream());
return writer.getEncoding();
}
如果默认编码是ASCII或Latin-1,则会得到“?”s。你需要把它改成UTF-8 您遇到的问题很可能是由于在您从google读取http响应时,字符编码设置不正确造成的。您可以发布实际获取URL并将其解析为JSON对象的代码吗 例如,运行以下命令:
public class Test1 {
public static void main(String [] args) throws Exception {
// just testing that the console can output the correct chars
System.out.println("\"title\":\"مطبخ مطايب - كباب الدجاج والخضار بصلصة الروب");
URL url = new URL("http://ajax.googleapis.com/ajax/services/search/web?start=0&rsz=large&v=1.0&q=rz+img+news+recordid+border");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
// the important bit is here..........................\/\/\/
InputStreamReader reader = new InputStreamReader(is, "utf-8");
StringWriter sw = new StringWriter();
char [] buffer = new char[1024 * 8];
int count ;
while( (count = reader.read(buffer)) != -1){
sw.write(buffer, 0, count);
}
System.out.println(sw.toString());
}
}
这是使用了一个非常丑陋的标准URL.openConnection()
,这个标准从时间的黎明就开始了。如果你正在使用类似的东西,那么你可以很容易地做到这一点
了解一些关于编码的背景知识,并解释为什么
新字符串(str.getBytes(),“UTF8”)
永远不会工作读取我认为JSON.org Java JSON包无法处理UTF8,无论它是作为UTF8字符传入还是实际传入\uxxx
代码。我试了两种方法如下:
import org.json.
public class JsonTest extends TestCase {
public void testParseText() {
try {
JSONObject json1 = new JSONObject("{\"a\":\"\u05dd\"}"); // \u05dd is a Hebrew character
JSONObject json2 = new JSONObject("{\"a\":\"\\u05dd\"}"); // \u05dd is a Hebrew character
System.out.println(json1.toString());
System.out.println(json2.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
我得到:
{"a":"?"}
{"a":"?"}
有什么想法吗 有一个使用JSon消息保留http响应(捷克语表达式)编码的方法,如下所示:
private static String inputStreamToString(final InputStream inputStream) throws Exception {
final StringBuilder outputBuilder = new StringBuilder();
try {
String string;
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while (null != (string = reader.readLine())) {
outputBuilder.append(string).append('\n');
}
}
} catch (Exception ex) {
throw new Exception("[google-api-translate-java] Error reading translation stream.", ex);
}
return outputBuilder.toString();
}
答案很棘手,有几点必须注意,主要是平台编码:
afaik影响打印输出到控制台,从inputstream创建文件,甚至影响DB客户端和服务器之间的通信,即使它们都设置为使用utf-8字符集进行编码-无论我是显式创建utf-8字符串、inputstreamReader还是为utf-8设置JDBC驱动程序,在linux系统上仍要将$LANG属性设置为xx_xx.UTF-8,并将append=“vt.default_utf8=1”添加到LILO引导加载程序(在使用它的系统上),至少对于运行数据库和使用UTF-8编码文件的java应用程序的系统,必须这样做
即使我附加了这个JVM参数-Dfile.encoding=UTF-8,如果没有平台编码,我也无法在正确编码的流中成功。正确设置JDBC连接器是必要的:“JDBC:mysql://localhost/DBname?useUnicode=true&characterEncoding=UTF8,如果要将字符串持久化到数据库,该数据库应处于以下状态:
mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
+--------------------------+--------+
谷歌的回应应该是UTF-8。您确定正在使用的终端支持UTF-8吗?您描述的阿拉伯字符是Unicode,可以用UTF-8表示。您可能在输出上有编码问题,而不是在输入上。
System.out.println(Charset.defaultCharset())代码>在我们的服务器中,som
mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
+--------------------------+--------+