1

I have figured out that my GSON problems are all about the fact that, while my return type is not a parameterized object, it should have been. Now I need to use the Gson.fromJson method with the type of parameter to specify the return type so that GSON will take care of it for me.

I have created a generic class called RestResponse such:

public class RestResponse<T> {
  private   String      errorMessage;
  private   int         errorReason;
  private   T           result;

  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return "RestResponse [errorMessage=" + errorMessage + ", result=" + result + "]";
  }

  /**
   * Does this response contain an error?
   * @return true if in error
   */
  public boolean isInError(){
    return getErrorMessage()!=null;
  }

  /**
   * @return the errorMessage
   */
  public String getErrorMessage() {
    return errorMessage;
  }

  /**
   * @param errorMessage the errorMessage to set
   */
  public void setErrorMessage(String errorMessage) {
    this.errorMessage = errorMessage;
  }

  /**
   * The error reason code
   * @return the errorReason
   */
  public int getErrorReason() {
    return errorReason;
  }

  /**
   * The error reason code
   * @param errorReason the errorReason to set
   */
  public void setErrorReason(int errorReason) {
    this.errorReason = errorReason;
  }

  /**
   * The result of the method call
   * @return the result or null if nothing was returned
   */
  public final T getResult() {
    return result;
  }

  /**
   * The result of the method call
   * @param result the result to set or null if nothing was returned
   */
  public final void setResult(T result) {
    this.result = result;
  }
}

Now I want to create the resulting type on the other side. I have a generic method that I use to decode these things and either throw the exception or return the result.

So my method is like this:

public Object submitUrl(String url, Class<?> clazz) throws AjApiException {

Where clazz is the type that will be specified on RestResponse.

I then go to create the RestResponse before passing to GSON:

Type typeOfT = new TypeToken<RestResponse<clazz>>(){}.getType(); //1-->What goes here?
RestResponse<clazz> restResponse; //2-->and here?

And it errors. Can someone tell me what goes in these to places in place of clazz?

Perception
  • 79,279
  • 19
  • 185
  • 195
Thom
  • 14,013
  • 25
  • 105
  • 185

3 Answers3

1

Instead of passing in the class you want to wrap in the response, specify it as a method level generic parameter.

public <T> T submitUrl(String url) throws AjApiException {
    Type typeOfT = new TypeToken<RestResponse<T>>(){}.getType();
}
Perception
  • 79,279
  • 19
  • 185
  • 195
  • Don't want to do this because I want to have one instance that maintains cookies, etc. This would require new instances for each method using it. – Thom Dec 10 '12 at 13:28
  • What does maintaining cookies have to do with deserializing JSON? This method solves the problem you were having with specifying the target class, without imposing any additional restrictions. You might want to clarify what you are trying to do exactly. – Perception Dec 10 '12 at 16:41
  • No, `typeOfT` would represent the type `RestResponse`. Yes, literally "T", not whatever his class is. – newacct Dec 10 '12 at 19:29
  • @newacct - did you read the question and the included code sample before downvoting? Please do so. – Perception Dec 10 '12 at 20:14
  • 1
    @Perception: I did read the question, but that is not relevant. Regardless of what the question is, giving `new TypeToken>(){}.getType()` to Gson is categorically wrong. – newacct Dec 10 '12 at 20:29
0

I ended up passing in the type instead of the class. This solved the problem.

I believe you can create the type by doing something like:

Type typeOfT = new TypeToken<RestResponse<T>>(){}.getType();
Benoit Duffez
  • 11,839
  • 12
  • 77
  • 125
Thom
  • 14,013
  • 25
  • 105
  • 185
  • Could you provide more information on how you implemented this? Thanks! – Benoit Duffez Apr 22 '14 at 07:05
  • @BenoitDuffez I added some code I think will help. It's been a while, so I'm not sure about it's syntax. Please upvote if useful. – Thom Apr 22 '14 at 12:57
  • OK thanks a lot. It's not the solution I wanted, but still, it may be useful to someone. Also, the `` is useless here because of type erasure. The only way I found how to describe generics to Gson was through `ParameterizedType`. See http://stackoverflow.com/a/14139700/334493 – Benoit Duffez Apr 22 '14 at 12:59
-1

The easiest way would be for the caller of the method, instead of passing in a Class object, to pass in a Type corresponding to the RestResponse<Whatever>; they would probably do this using the TypeToken thing.

Otherwise, it is possible for you to construct the Type (specifically a ParameterizedType) yourself. You would either need to make your own class that implements ParameterizedType, or copy the ParameterizedTypeImpl private class used in some projects.

newacct
  • 119,665
  • 29
  • 163
  • 224