I am using Retrofit with Jackson. For some reasons I cannot parse the following JSON:
[
{
"ProfileImage": null,
"UserName": "joe"
},
{
"ProfileImage": "http://www.example.com/profiles/fileName1.jpg",
"UserName": "jane"
},
{
"ProfileImage": null,
"UserName": "john"
}
]
I get the this exception:
Exception in thread "main" retrofit.RetrofitError: java.lang.ClassCastException:
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
cannot be cast to java.lang.Class
at retrofit.RetrofitError.unexpectedError(RetrofitError.java:41)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:294)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:182)
at com.sun.proxy.$Proxy5.getReplies(Unknown Source)
at Test.main(Test.java:25)
Caused by: java.lang.ClassCastException:
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
cannot be cast to java.lang.Class
at JacksonConverter.fromBody(JacksonConverter.java:27)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:274)
My code is as follow:
//File: Test.java:
public class Test {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy
.PascalCaseStrategy());
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://www.example.com")
.setConverter(new JacksonConverter(mapper))
.build();
ListingService listingService = restAdapter.create(ListingService.class);
ArrayList<ListingReplyExt> replies = listingService.getReplies(123, 1, 10);
//More code...
}
}
//File: ListingService.java
public interface ListingService {
@GET("/api/ListingRepliesService.svc/Get")
public ArrayList<ListingReplyExt> getReplies(
@Query("listingId") long listingId,
@Query("start") int start,
@Query("count") int count);
}
//File: ListingReplyExt.java:
@JsonIgnoreProperties(ignoreUnknown = true)
public class ListingReplyExt {
private String profileImage;
private String username;
@JsonProperty(value = "ProfileImage")
public String getProfileImage() {
return profileImage;
}
@JsonProperty(value = "ProfileImage")
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
@JsonProperty(value = "UserName")
public String getUsername() {
return username;
}
@JsonProperty(value = "UserName")
public void setUsername(String username) {
this.username = username;
}
}
Any help is appriciated.
UPDATE
Sotirios Delimanolis' comment gave me some hints to resolve this issue.
My JacksonConverter was originally this:
public class JacksonConverter implements Converter {
private final ObjectMapper objectMapper;
public JacksonConverter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override public Object fromBody(TypedInput body, Type type) {
return objectMapper.readValue(body.in(), (Class<Object>) type);
}
//More code
}
I changed it to this:
public class JacksonConverter implements Converter {
private final ObjectMapper objectMapper;
public JacksonConverter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override public Object fromBody(TypedInput body, Type type) {
JavaType javaType = objectMapper.getTypeFactory().constructType(type);
return objectMapper.readValue(body.in(), javaType);
}
//More code
}
Now it works for me.
Jackson JSON Parser API provides easy way to convert JSON to POJO Object and supports easy conversion to Map from JSON data. Jackson supports generics too and directly converts them from JSON to object.
Jackson allows you to read JSON into a tree model: Java objects that represent JSON objects, arrays and values. These objects are called things like JsonNode or JsonArray and are provided by Jackson.
ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.
Use Square's converter by adding this to your build.gradle:
compile 'com.squareup.retrofit:converter-jackson:1.9.0'
Afterwards you can activate it by adding .setConverter(new JacksonConverter())
to your RestAdapter
builder.
with new versions of OkHTTP it seems its done with:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(JacksonConverterFactory.create())
.build();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With