1

I am new to Android development. Here, I am making a GET call like this -

    protected String doInBackground(String... params) {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        nameValuePairs.add(new BasicNameValuePair("email", "guest@example.com"));

        JSONHttpClient jsonHttpClient = new JSONHttpClient();
        ProductDetail[] products  = jsonHttpClient.Get(ServiceUrl.PRODUCT, nameValuePairs, ProductDetail[].class);

        return null;
    }

This is the GET call in JSONHttpClient file -

 public <T> T Get(String url, List<NameValuePair> params, final Class<T> objectClass) {
    DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
    String paramString = URLEncodedUtils.format(params, "utf-8");
    url += "?" + paramString;
    HttpGet httpGet = new HttpGet(url);


        httpGet.setHeader("Accept", "application/json");
        httpGet.setHeader("Accept-Encoding", "gzip");
        httpGet.setHeader("Authorization", "Bearer <code>");

        HttpResponse httpResponse = defaultHttpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            InputStream inputStream = httpEntity.getContent();
            Header contentEncoding = httpResponse.getFirstHeader("Content-Encoding");
            if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
                inputStream = new GZIPInputStream(inputStream);
            }

            String resultString = convertStreamToString(inputStream);
            inputStream.close();
            return new GsonBuilder().create().fromJson(resultString, objectClass);

        }

    return null;
}

And this is my ProductDetail class -

public class ProductDetail {

    public int Id;
    public String Name;

}

On running this, I am getting below error -

No-args constructor for class com.compa.ProductDetail does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

This is thrown on this line in JSONHttpClient file -

return new GsonBuilder().create().fromJson(resultString, objectClass);

Can anyone help on this?

In my web api, I am creating json like this (proddetails is a C# IEnumerable object) -

json = JsonConvert.SerializeObject(proddetails);
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;

The structure of response json is -

[
   {
       "Id": 1,
       "Name": "First"
   },
   {
       "Id": 2,
       "Name": "Second"
   }          
] 
Sam
  • 4,302
  • 12
  • 40
  • 74
  • 1
    Is your `ProductDetail` class an inner class? – Sotirios Delimanolis Apr 09 '15 at 21:05
  • No, it's not. It is actually the only class in the system as of now. – Sam Apr 09 '15 at 21:05
  • Then I ask that you provide a [mcve](http://stackoverflow.com/help/mcve). – Sotirios Delimanolis Apr 09 '15 at 21:07
  • Can u try adding a constructor with the id and name as parameters like the error says and see if that helps. – ngoa Apr 09 '15 at 21:10
  • @ngoa It is complaining about lack of a constructor *without* arguments. – Don Roby Apr 09 '15 at 21:13
  • then did u try add a constructor manually? – ngoa Apr 09 '15 at 21:24
  • @Sam is there a reason for you to use new GsonBuilder().create().fromJson(resultString, objectClass); instead of new Gson().fromJson(resultString, objectClass); ? as the [documentation](https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/GsonBuilder.html#create()) implies "Returns an instance of Gson configured with the options currently set in this builder" i think that could be an issue as you don't have options in your builder... anyway is the only thing that i can think of without seeing the whole code piece – mmark Apr 09 '15 at 21:24
  • @urudroid Actually I am following this tutorial - http://hintdesk.com/how-to-call-asp-net-web-api-service-from-android/comment-page-1/ I am not too sure about what you are implying. Can you tell what other piece of code is required. I will provide it. – Sam Apr 09 '15 at 21:25
  • @Sam can you add the actual json response String representation? – mmark Apr 09 '15 at 21:34
  • @ngoa Yes, I tried and the same exception again. – Sam Apr 09 '15 at 21:36
  • @urudroid I added more details in the end. – Sam Apr 09 '15 at 22:07
  • In this case you can't map the response directly into ProductDetail class, as the response is a JSONArray and you're trying to map it into an object. You should tell that to Gson by passing a ProductDetail[].class to your Get method, i believe that might be an issue – mmark Apr 09 '15 at 22:18
  • @urudroid I am already doing it above. – Sam Apr 09 '15 at 22:26
  • Can the reason be that I am returning HttpResponseMessage instead of the object itself from api? – Sam Apr 09 '15 at 23:42

1 Answers1

1

The Gson user guide (https://sites.google.com/site/gson/gson-user-guide) tells you that a well behaved class (meant for serialization and deserialization) should have a no argument constructor. If this is not there, it advises you to use InstanceCreator.

Even if you do not have a constructor, Gson will create an ObjectConstructor for your class. But this is not safe always and has it's own limitations. This question on SO goes more into the details: Is default no-args constructor mandatory for Gson?

NOTE: Please see that if this is an inner class, then it MUST have a constructor as explained in the documentation.

EDIT: Your json is an array. So you need to have the specified number of array objects in the containing class. So you can do the following and then cast:

public class ProductDetailArray {

    public ProductDetailArray[] array;

    public static ProductDetail {
        public ProductDetail() {} // You can also make the constructor private if you don't want anyone to instantiate this

        public int Id;
        public String Name; 
    }
}

Once you cast your json similarly as before:

ProductDetailArray obj = GsonBuilder.create().fromJson(response, ProductDetailArray.class);

ProductDetail one = obj.array[0];
ProductDetail two = obj.array[1];

And then you can do your manipulation.. also you should probably be using Gson.fromJson() rather than the GsonBuilder

Community
  • 1
  • 1
ucsunil
  • 7,378
  • 1
  • 27
  • 32
  • So, how to fix it in my situation. It is not a inner class. – Sam Apr 09 '15 at 23:10
  • Please see my edit. You simply have to add a no argument constructor – ucsunil Apr 09 '15 at 23:19
  • Ok.. I just suddenly realized your json is an array - not a simple direct object from which a class can be initialized. So let me edit my answer and update it to how the class you are casting your response to should look like – ucsunil Apr 09 '15 at 23:39
  • Can the reason be that I am returning HttpResponseMessage instead of the object itself from api? – Sam Apr 09 '15 at 23:41
  • Ok.. I edited the code. Hmm.. I get the feeling it may still work because you certainly had an error with the json to class casting and that step happens separately which is where you are receiving the error. If the HttpResponseMessage being returned is causing the problem, then that is something else – ucsunil Apr 09 '15 at 23:49