0

亲爱的,

我知道这个标题看起来很流行而且很容易,但我面临的事情太奇怪了。

简单地说,我在服务器上发布了一个 RESTful C# .NET 4.0 Web 服务,我想在我的 Android 应用程序中通过 Java 使用它,容易吗?

问题是:每当我调用 .NET Web 服务并获得响应时,java 都无法将返回字符串解析为 Json。

错误信息:

org.json.JSONException: Value {lhs:"1 Euro",rhs: "1.3711 U.S. dollars",error: "",icc: true} of type java.lang.String cannot be converted to JSONObject
    at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONObject.<init>(JSONObject.java:158)
at org.json.JSONObject.<init>(JSONObject.java:171)
at com.itrack21.mobileapp.LoginActivity.getUserInfo(LoginActivity.java:151)
at com.itrack21.mobileapp.LoginActivity$1$1.run(LoginActivity.java:114)
at java.lang.Thread.run(Thread.java:841)
threadid=17: thread exiting with uncaught exception (group=0x4164d700)

Java 代码:

public void getRate(String link) {

        try {
                URL url = new URL(link);
                URLConnection connection = url.openConnection();
                InputStream str = connection.getInputStream();
                InputStreamReader reader = new InputStreamReader(str);
                BufferedReader bufReader = new BufferedReader(reader);
                String line=new String();
                StringBuffer buffer = new StringBuffer();

                while( (line=bufReader.readLine()) != null) {
                    buffer.append(line);
                }

            JSONObject obj = null;
            try {
                obj = new JSONObject(buffer.toString());
            } catch (JSONException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            String rhs = "";
            try {
                rhs = obj.getString("rhs");
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.i("getRate","Converted Currency = " + rhs.toString());

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

调试:

我做了很多调试场景,但没有运气,这里我将使用最奇怪的一个来描述问题。

  1. 我使用我的 java 代码使用以下链接使用 Google 网络服务进行货币转换http://www.google.com/ig/calculator?hl=en&q=1USD=?EUR,我得到的响应如下:{lhs: "1 U.S. dollar",rhs: "0.726321906 Euros",error: "",icc: true}。在这里,我的代码运行良好。

  2. 我从 Google Web 服务复制准确的 Json 值返回,并使用我的代码正常工作,并将其作为硬编码字符串返回到我的 RESTful C# 服务中,如下所示:

C#代码:

public string GetInfo()
{
return "{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}";
}
  1. 我使用与调用 Google Web 服务相同的代码请求我的 C# .NET Web 服务,但我得到了上面列出的错误org.json.JSONException: Value {lhs:"1 Euro",rhs: "1.3711 U.S. dollars",error: "",icc: true} of type java.lang.String cannot be converted to JSONObject at org.json.JSON.typeMismatch(JSON.java:111)

  2. 当我将返回值作为硬代码复制并粘贴到我的代码中时,它工作得很好。

    JSONObject obj = null;
    try {
        obj = new JSONObject("{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}");
    } catch (JSONException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    

完成了许多“疯狂”的调试方案,包括更改服务器本身,但没有运气。

我做错了什么?

问候,

4

2 回答 2

0

在 JSON 中,您还需要将键括在引号中。所以为此:

{lhs: "1 U.S. dollar",rhs: "0.726321906 Euros",error: "",icc: true},

你必须这样做:

{"lhs": "1 U.S. dollar","rhs": "0.726321906 Euros","error": "","icc": "true"}

您可以在线查看您的 JSON:http: //jsonlint.com/

于 2013-11-03T14:07:47.907 回答
0

经过漫长的调试过程,我得到了原因,然后是解决方案。开始了:

  1. 通过 Chrome 浏览器访问Google Maps Web Service,会得到 Json 响应。出于调试目的,请右键单击页面并选择View page source. 请注意,Json 的字符串是纯 Json,没有添加。

  2. 当您通过 Chrome 浏览器对 C# .NET 响应重复相同的过程时,您会注意到响应不是纯 Json,它被以下内容包围:<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{JSON String HERE}</string>.

解决方案:

要删除响应周围的此字符串,您必须将 Json 字符串返回为System.IO.Stream. 这里所需的代码更改:

public System.IO.Stream GetInfo()
{
    OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
    context.ContentType = "text/plain";
    return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes("{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}"));
}

这个解决方案对我来说很好,但它是最佳解决方案吗?从对象转换为 Json,然后从 Json 字符串转换为字节的开销很小,你怎么看?建议?

于 2013-11-05T11:55:35.893 回答