Multiple converters with Retrofit 2

后端 未结 4 1032
萌比男神i
萌比男神i 2020-12-13 10:30

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

4条回答
  •  猫巷女王i
    2020-12-13 11:09

    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.

提交回复
热议问题