web-dev-qa-db-ja.com

レトロフィットとジャクソンとJSONの解析

ジャクソンとレトロフィットを使用しています。いくつかの理由で、次のJSONを解析できません。

[
    {
        "ProfileImage": null,
        "UserName": "joe"
    },
    {
        "ProfileImage": "http://www.example.com/profiles/fileName1.jpg",
        "UserName": "jane"
    },
    {
        "ProfileImage": null,
        "UserName": "john"
    }
]

私はこの例外を受け取ります:

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)

私のコードは次のとおりです。

//ファイル: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...
}

}

//ファイル: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);
}

//ファイル: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;
    }
}

どんな助けでも適用されます。

[〜#〜] update [〜#〜]

Sotirios Delimanolisのコメントは、この問題を解決するためのいくつかのヒントを与えてくれました。

私のJacksonConverterはもともとこれでした:

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
}

私はそれをこれに変更しました:

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
}

今それは私のために働きます。

15
thd

これをbuild.gradleに追加して、Squareのコンバーターを使用します。

_compile 'com.squareup.retrofit:converter-jackson:1.9.0'
_

その後、.setConverter(new JacksonConverter())RestAdapterビルダーに追加してアクティブ化できます。

21
Thorre

okHTTPの新しいバージョンでは、次のようになります。

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_URL)
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
1
RicardoDuarte