【问题标题】:JSON Object Parsing ErrorJSON 对象解析错误
【发布时间】:2012-04-17 09:48:33
【问题描述】:

我有以下字符串作为 HTTPResponse。它是 JSON 格式。

  [
    {
       "From":"en",
       "OriginalTextSentenceLengths":[
          5
       ],
       "TranslatedText":"Hallo",
       "TranslatedTextSentenceLengths":[
          5
       ]
    },
    {
       "From":"en",
       "OriginalTextSentenceLengths":[
          8
       ],
       "TranslatedText":"Frage",
       "TranslatedTextSentenceLengths":[
          5
       ]
   },
   {
       "From":"en",
       "OriginalTextSentenceLengths":[
          6
       ],
       "TranslatedText":"Antwort",
       "TranslatedTextSentenceLengths":[
          7
       ]
  }
]

所以我解析这个字符串如下得到“翻译文本数组”

  String resp = "[{\"From\":\"en\",\"OriginalTextSentenceLengths\":[5],\"TranslatedText\":\"Hallo\",\"TranslatedTextSentenceLengths\":[5]},{\"From\":\"en\",\"OriginalTextSentenceLengths\":[8],\"TranslatedText\":\"Frage\",\"TranslatedTextSentenceLengths\":[5]},{\"From\":\"en\",\"OriginalTextSentenceLengths\":[6],\"TranslatedText\":\"Antwort\",\"TranslatedTextSentenceLengths\":[7]}]";

    String[] stringArray = null;
    try {
    JSONArray finalResult=null;
    JSONTokener tokener = new JSONTokener(resp); 

        finalResult = new JSONArray(tokener);
        stringArray = new String[finalResult.length()];

    for(int i=0;i<finalResult.length();i++){
        JSONObject e = finalResult.getJSONObject(i);
        Log.v("TAG",e.getString("TranslatedText"));
        stringArray[i]=e.getString("TranslatedText");
    }        

    }catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 

我正在从 JSON 对象中获取提取的“翻译文本”数组(Hallo、Frage、Antwort)...

但是当我通过将相同的字符串直接提供给 JSONTokener 的输入来执行相同的过程时,即在获得如下 HttpResponse 之后,我 在 finalResult = new JSONArray(tokener) 行处获取 JSON 异常......

org.json.JSONException:输入在字符 0 处结束

String resp = getHttpResponse(uri);
String[] stringArray = null;
    try {
    JSONArray finalResult=null;
    JSONTokener tokener = new JSONTokener(resp); 

        finalResult = new JSONArray(tokener);
        stringArray = new String[finalResult.length()];

    for(int i=0;i<finalResult.length();i++){
        JSONObject e = finalResult.getJSONObject(i);
        Log.v("TAG",e.getString("TranslatedText"));
        stringArray[i]=e.getString("TranslatedText");
    }

    }catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 

我已经努力了 2 天来解决此错误,但无法解决。所以我将其发布在这里...请帮助

编辑:

我正在添加getHttpResponse的实现

 public static String getHttpResponse(URI uri) {
    Log.d("APP_TAG", "Going to make a get request");
    StringBuilder response = new StringBuilder();
    try {
        HttpGet get = new HttpGet();
        get.setURI(uri);
        //DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpParams httpParameters = new BasicHttpParams(); 
        int timeoutConnection = 30000; 
        HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
        int timeoutSocket = 30000; 
        HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 

        DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters); 

        Log.v("TAG","1");
        HttpResponse httpResponse = httpClient.execute(get);
        Log.v("TAG","2");
        if (httpResponse.getStatusLine().getStatusCode() == 200) {
            Log.d("demo", "HTTP Get succeeded");

            HttpEntity messageEntity = httpResponse.getEntity();
            InputStream is = messageEntity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = br.readLine()) != null) {
                response.append(line);
            }
        }
    } catch (Exception e) {
        Log.e("demo", e.getMessage());
    }
    Log.d("demo", "Done with HTTP getting");
    return response.toString();
}

我给 getHttpResponse 的 uri 如下

   String[] texts = {"hello","question","answer"};
   final String params = "appId=" +   URLEncoder.encode("78280AF4DFA1CE1676AFE86340C690023A5AC139","UTF-8")                 
            + "&from=" + URLEncoder.encode("en","UTF-8")                 
            + "&to=" + URLEncoder.encode("de","UTF-8")                 
            + "&texts=" +   URLEncoder.encode(buildStringArrayParam(texts),"UTF-8");                

     final URL url = new  URL("http://api.microsofttranslator.com/V2/Ajax.svc/TranslateArray?" + params);       

     URI myURI = java.net.URI.create(url.toString()); 
     String resp = getHttpResponse(myURI);

这个响应字符串是我要解析的...

这是用于 buildStringArrayParam(texts)

StringBuilder targetString = new StringBuilder("[\""); 
    String value;
    for(Object obj : values) {
        if(obj!=null) {
            value = obj.toString();
            if(value.length()!=0) {
                if(targetString.length()>2)
                    targetString.append(",\"");
                targetString.append(value);
                targetString.append("\"");
            }
        }
    }
    targetString.append("]");
    return targetString.toString();

【问题讨论】:

  • 如果您从getHttpResponse() 记录resp 字符串,它实际上是否包含您期望的JSON 字符串?
  • 是的,它包含我期望的 JSON 字符串...
  • 你用equals()检查过,比较你的String resp = "[{\"From\":\"...常量吗?您能否将您从getHttpResponse() 获得的resp 添加到您的问题中?
  • 另外,看看你对getHttpResponse()的实现可能会有所帮助。
  • 看看我的回答,我想我找到了……疯狂的原因。

标签: android json parsing


【解决方案1】:

啊哈哈……微软。

至少在这种情况下,他们在 API 响应的开头使用(不正确?)FEFF FEFF UTF-16 byte order mark,这会破坏大多数客户端。

the PHP guys over here already found out 一样,您只需从响应中删除前两个字节。以您的代码为例:

JSONTokener tokener = new JSONTokener(resp.substring(2));

恐怕更无害的trim()不行。

真的很难找到,因为FEFF 的正式名称是“零宽度不间断空格”,所以它是完全不可见的,除非您将字符串视为 char 数组或注意到当您移动时文本光标是如何停止的使用左/右箭头键的字符串...

请注意,您不应对收到的任何其他 HTTP 响应执行此操作,这仅适用于此 Microsoft API(也可能是其他 API)。

【讨论】:

  • 嗨,现在有一个新异常....org.json.JSONException: Value {"TranslatedText":"Hallo","TranslatedTextSentenceLengths":[5],"OriginalTextSentenceLengths":[5] org.json.JSONObject 类型的 ,"From":"en"} 无法转换为 JSONArray
  • 这发生在 JSONTokener tokener = new JSONTokener(resp.substring(2));行...
  • 尝试使用substring(1)。我不确定它是否适用于我,因为 API 有时会返回不同的 BOM,或者我的测试用例有误。
  • 最坏的情况,API 随意返回不同的 BOM,你必须尝试使用​​ substring(1) 和 substring(2) 并选择 JSON 可以理解的任何内容。
  • 嗨菲利普,你真的很棒....!!!!!我将其更改为 1,它起作用了... :) 非常感谢您找到这个疯狂的原因...!! :)
【解决方案2】:

Try GSON

并尝试更改您的代码设计,希望对您有所帮助。

并从 url 检索内容 -

public static String getContent(String url) throws Exception {
    return(new Scanner(new URL(url).openConnection().getInputStream()).useDelimiter("/z").next());
}

玩得开心……

【讨论】:

  • 我可以使用 GSON,但主要困扰我的是,当 JSON 解析在第一部分工作时,为什么它在第二部分失败?
【解决方案3】:

试试这个:

HttpPost request = new HttpPost(URL);
HttpResponse response = httpClient.execute(request);

HttpEntity httpEntity = response.getEntity();
InputStream content = httpEntity.getContent();

BufferedReader reader = new BufferedReader(new InputStreamReader(content,"iso-8859-1"),8);
String resp = reader.readLine();

现在 "resp" 将保存可以解析的字符串...

【讨论】:

  • 实际上问题不在于 HttpResponse,因为我正确获取了响应字符串并将其显示在 logcat 中...我在发布的第一个代码中使用了该字符串并且它有效...
  • 你的 URL 支持 POST/GET HTTP 方法吗?再检查一次!
  • 它支持GET,因为我已经收到了我一开始发布的响应......
【解决方案4】:
After getting the HTTP Response you have to do this thing, you cant use Httpresponse directly.

HttpResponse response= null;
response = http.execute(get);
HttpEntity entity = response.getEntity();
String xmlstring = EntityUtils.toString(entity);
message = xmlstring;

【讨论】:

    猜你喜欢
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多