I have a HATEOAS (HAL) REST service and managed to talk to it with the code below (using halarious as a conversion engine) but when I try to merge the converters (stal
I did almost the same as @jake-wharton said in https://stackoverflow.com/a/33459073/2055854 but added some changes:
public class GenericConverterFactory extends Converter.Factory {
private final Class clazz;
public static GenericConverterFactory create(Class clazz) {
return new GenericConverterFactory(clazz);
}
private GenericConverterFactory(Class clazz) {
this.clazz = clazz;
}
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (!isNeededType(type)) {
return null;
}
// some converter that knows how to return your specific type T
return new GenericConverter(clazz);
}
private boolean isNeededType(Type type) {
if(type instanceof GenericArrayType) {
// if type is array we should check if it has the same component as our factory clazz
// if our factory clazz is not array getComponentType will return null
return ((GenericArrayType) type).getGenericComponentType().equals(clazz.getComponentType());
} else if(clazz.getComponentType() == null) {
// if factory clazz is not array and type is not array too
// type is just a Class> and we should check if they are equal
return clazz.equals(type);
} else {
// otherwise our clazz is array and type is not
return false;
}
}
}
Type is coming from retrofit interface for example if you have:
public interface SomeApi{
@GET("customelement")
CustomElement[] getCustomElements();
@GET("customelement/{id}")
CustomElement getCustomElement(@Path("id") int id);
}
For method getCustomElements() type will be GenericArrayType with GenericComponentType as CustomElement.class and for second method type will be just CustomElement.class
Not sure whether it is the best solution but for me it works. Hope it helps.