简体   繁体   中英

Consuming RESTful C# Web Service through Java Android

Dears,

I know that the title seems popular and easy but what I'm facing is too strange.

Simply, I have a RESTful C# .NET 4.0 web service published on the server, and I want to consume it through Java in my Android application, easy?

The problem is: whenever I call the .NET web service and get the response, java could not parse the return string into Json.

Error message:

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 Code:

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();
        }
    }

Debugging:

I did many debugging scenarios but with no luck, here I will use strangest one to describe the problem.

  1. I use my java code to consume Google web service for currency converting using the following link http://www.google.com/ig/calculator?hl=en&q=1USD=?EUR and I got the response as follows: {lhs: "1 US dollar",rhs: "0.726321906 Euros",error: "",icc: true} . And here my code is working perfectly.

  2. I copy exact Json value return from Google web service and working fine with my code, and return it as a HARD CODED String in my RESTful C# service as follows:

C# Code:

public string GetInfo()
{
return "{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}";
}
  1. I request my C# .NET web service using the same code used to invoke Google web service bu I got error listed above org.json.JSONException: Value {lhs:"1 Euro",rhs: "1.3711 US dollars",error: "",icc: true} of type java.lang.String cannot be converted to JSONObject at org.json.JSON.typeMismatch(JSON.java:111) .

  2. When I copy and paste the return value into my code as a HARD CODE, it works just fine.

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

Many "Crazy" debugging scenario done including changing the server itself, but with no luck.

What I'm doing wrong?

Regards,

In JSON, you need to wrap the keys in quotation marks too. So for this:

{lhs: "1 US dollar",rhs: "0.726321906 Euros",error: "",icc: true} ,

you will have to do this:

{"lhs": "1 US dollar","rhs": "0.726321906 Euros","error": "","icc": "true"}

You can check your JSON online at : http://jsonlint.com/

After long debugging process, I got the cause, and then the solution. Here we go:

  1. Visit Google Maps Web Service through Chrome browser, and you will get Json response. For debugging purpose, right click on page and select View page source . Note that the string of Json is pure Json with no additions.

  2. When you repeat same procedure with the C# .NET response through Chrome browser, you will notice that the response is NOT pure Json, it is surrounded by this: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{JSON String HERE}</string> .

Solution:

To remove this string surrounding the response, you have to return Json string as System.IO.Stream . Here the required code changes:

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}"));
}

This solution works fine with me, but is it optimal solution? converting from object to Json, and then from Json string to bytes is little overhead, what do think? suggestions?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM