Interesting find out today with using default Jackson converter in Retrofit. I can not map the field in POJO model with customized field names using jackson annotation called `@JsonProperty`.

My POJO model is something simple like:

@JsonIgnoreProperties(ignoreUnknown = true)
public class PopularMovieData {
public PopularMovieData() {

}

@JsonProperty("results")
private List<Movie> mResults;


public List<Movie> getResults() {
return mResults;
}


public void setResults(List<Movie> mResults) {
this.mResults = mResults;
}

@Override
public String toString() {
return "PopularMovieData{" +
"mResults=" + mResults +
'}';
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static class Movie {

public Movie() {

}

private String id;

@JsonProperty("poster_path")
private String posterPath;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getPosterPath() {
return posterPath;
}

public void setPosterPath(String posterPath) {
this.posterPath = posterPath;
}

@Override
public String toString() {
return "Movie{" +
"id='" + id + '\'' +
", posterPath='" + posterPath + '\'' +
'}';
}
}
}

And my initializing code for the Retrofit API is:

RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.API_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setLog(new RestAdapter.Log() {
@Override
public void log(String message) {
Log.d(TAG, message);
}
})
.setClient(new OkClient(client))
.build();

The model would not be possible to parse correctly with Retrofit.

My fix, using a customized Jackson converter, with `objectMapper` being prepared with `setVisibilityChecker`:

/**
* Created by toan on 7/12/15.
*/
public class JacksonConverter implements Converter {
private static final String MIME_TYPE = "application/json; charset=UTF-8";

private final ObjectMapper objectMapper;

public JacksonConverter() {
this(new ObjectMapper());
}

public JacksonConverter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setVisibilityChecker(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
}

@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
try {
JavaType javaType = objectMapper.getTypeFactory().constructType(type);
return objectMapper.readValue(body.in(), javaType);
} catch (JsonParseException e) {
throw new ConversionException(e);
} catch (JsonMappingException e) {
throw new ConversionException(e);
} catch (IOException e) {
throw new ConversionException(e);
}
}

@Override
public TypedOutput toBody(Object object) {
try {
String json = objectMapper.writeValueAsString(object);
return new TypedByteArray(MIME_TYPE, json.getBytes("UTF-8"));
} catch (JsonProcessingException e) {
throw new AssertionError(e);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}
}

And boom! got the correct result

07–12 09:10:26.350 15970–15970/mobi.toan.popularmovies E/MainActivity﹕ ok >> PopularMovieData{mResults=[Movie{id=’135397', posterPath=’/uXZYawqUsChGSj54wcuBtEdUJbh.jpg’}, Movie{id=’87101', posterPath=’/5JU9ytZJyR3zmClGmVm9q4Geqbd.jpg’}, Movie{id=’211672', posterPath=’/s5uMY8ooGRZOL0oe4sIvnlTsYQO.jpg’}, Movie{id=’76341', posterPath=’/kqjL17yufvn9OVLyXYpvtyrFfak.jpg’}, Movie{id=’214756', posterPath=’/A7HtCxFe7Ms8H7e7o2zawppbuDT.jpg’}, Movie{id=’254128', posterPath=’/qey0tdcOp9kCDdEZuJ87yE3crSe.jpg’}, Movie{id=’262500', posterPath=’/aBBQSC8ZECGn6Wh92gKDOakSC8p.jpg’}, Movie{id=’198184', posterPath=’/saF3HtAduvrP9ytXDxSnQJP3oqx.jpg’}, Movie{id=’207703', posterPath=’/oAISjx6DvR2yUn9dxj00vP8OcJJ.jpg’}, Movie{id=’76757', posterPath=’/aMEsvTUklw0uZ3gk3Q6lAj6302a.jpg’}, Movie{id=’157336', posterPath=’/nBNZadXqJSdt05SHLqgT0HuC5Gm.jpg’}, Movie{id=’177572', posterPath=’/hGRfWcy1HRGbsjK6jF7NILmqmFT.jpg’}, Movie{id=’122917', posterPath=’/qrFwjJ5nvFnpBCmXLI4YoeHJNBH.jpg’}, Movie{id=’287424', posterPath=’/xxX0v4vyfVc3Z8DEsbLJODnMOfQ.jpg’}, Movie{id=’205596', posterPath=’/noUp0XOqIcmgefRnRZa1nhtRvWO.jpg’}, Movie{id=’99861', posterPath=’/t90Y3G8UGQp0f0DrP60wRu9gfrH.jpg’}, Movie{id=’150540', posterPath=’/rDycdoAXtBb7hoWlBpZqbwk2F44.jpg’}, Movie{id=’131631', posterPath=’/cWERd8rgbw7bCMZlwP207HUXxym.jpg’}, Movie{id=’150689', posterPath=’/2i0JH5WqYFqki7WDhUW56Sg0obh.jpg’}, Movie{id=’228161', posterPath=’/8uREeoTbutetwgjB2jGAotcehuG.jpg’}]}

Such an automagical chain :D

Happy coding!

Like what you read? Give Toan Tran a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.