Ok, found some nasty solution, but will share it anyway. Maybe someone can tweak it.
Step 1 - extend MappingJacksonHttpMessageConverter and overwrite canRead and readInternal methods, so that converter will be able to make use of TypeReference
Step 2 - in NkTemplate class overwrite json message converter
Step 3 - create proper instance of TypeReference
Code:
public class TypeReferenceJacksonMessageConverter extends MappingJacksonHttpMessageConverter {
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
if (TypeReference.class.isAssignableFrom(clazz)) {
// if Class<TypeReference<X>> passed, then check X
Type pt = ((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0];
return super.canRead(pt.getClass(), mediaType);
}
return super.canRead(clazz, mediaType);
}
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
try {
if (TypeReference.class.isAssignableFrom(clazz)) {
Constructor<?> c = clazz.getDeclaredConstructors()[0];
c.setAccessible(true);
@SuppressWarnings("rawtypes")
TypeReference ref = (TypeReference) c.newInstance(new Object[]{});
return this.getObjectMapper().readValue(inputMessage.getBody(), ref);
}
return this.getObjectMapper().readValue(inputMessage.getBody(), clazz);
} catch (JsonProcessingException ex) {
throw new HttpMessageNotReadableException("Could not read JSON: ", ex);
} catch (InvocationTargetException ite) {
throw new HttpMessageNotReadableException("Could not create instance of TypeReference: ", ite);
} catch (IllegalAccessException iae) {
throw new HttpMessageNotReadableException("Could not create instance of TypeReference: ", iae);
} catch (InstantiationException e) {
throw new HttpMessageNotReadableException("Could not create instance of TypeReference: ", e);
}
}
}
Code:
public class NkTemplate extends AbstractOAuth2ApiBinding implements Nk {
...
@Override
protected MappingJacksonHttpMessageConverter getJsonMessageConverter() {
return new TypeReferenceJacksonMessageConverter();
}
}
Code:
public class FetchNkProfile {
private static final TypeReference<JsonObject<NkProfile>> typeReference = new TypeReference<JsonObject<NkProfile>>() {
};
public NkProfile getUserProfile() {
Object jsonObject = getRestTemplate().getForObject(buildUri("/people/@me"), typeReference.getClass());
return ((JsonObject<NkProfile>)jsonObject).getEntry();
}
}