Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit and Jackson and parsing JSON

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.

like image 619
thd Avatar asked Sep 06 '13 20:09

thd


People also ask

What is Jackson parser?

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.

Is JSON A Jackson?

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.

What is Jackson Mapper used for?

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.


2 Answers

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.

like image 173
Thorre Avatar answered Sep 24 '22 10:09

Thorre


with new versions of OkHTTP it seems its done with:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_URL)
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
like image 35
RicardoDuarte Avatar answered Sep 24 '22 10:09

RicardoDuarte