/* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import com.google.gson.GsonBuilder; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.reflect.Type; import java.util.LinkedHashMap; import java.util.Map; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Default; import org.simpleframework.xml.DefaultType; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.moshi.MoshiConverterFactory; import retrofit2.converter.simplexml.SimpleXmlConverterFactory; import retrofit2.http.GET; import static java.lang.annotation.RetentionPolicy.RUNTIME; final class AnnotatedConverters { public static final class AnnotatedConverterFactory extends Converter.Factory { private final Map<Class<? extends Annotation>, Converter.Factory> factories; public static final class Builder { private final Map<Class<? extends Annotation>, Converter.Factory> factories = new LinkedHashMap<>(); public Builder add(Class<? extends Annotation> cls, Converter.Factory factory) { if (cls == null) { throw new NullPointerException("cls == null"); } if (factory == null) { throw new NullPointerException("factory == null"); } factories.put(cls, factory); return this; } public AnnotatedConverterFactory build() { return new AnnotatedConverterFactory(factories); } } AnnotatedConverterFactory(Map<Class<? extends Annotation>, Converter.Factory> factories) { this.factories = new LinkedHashMap<>(factories); } @Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { for (Annotation annotation : annotations) { Converter.Factory factory = factories.get(annotation.annotationType()); if (factory != null) { return factory.responseBodyConverter(type, annotations, retrofit); } } return null; } @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { for (Annotation annotation : parameterAnnotations) { Converter.Factory factory = factories.get(annotation.annotationType()); if (factory != null) { return factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit); } } return null; } } @Retention(RUNTIME) public @interface Moshi { } @Retention(RUNTIME) public @interface Gson { } @Retention(RUNTIME) public @interface SimpleXml { } @Default(value = DefaultType.FIELD) static final class Library { @Attribute String name; } interface Service { @GET("/") @Moshi Call<Library> exampleMoshi(); @GET("/") @Gson Call<Library> exampleGson(); @GET("/") @SimpleXml Call<Library> exampleSimpleXml(); @GET("/") Call<Library> exampleDefault(); } public static void main(String... args) throws IOException { MockWebServer server = new MockWebServer(); server.start(); server.enqueue(new MockResponse().setBody("{\"name\": \"Moshi\"}")); server.enqueue(new MockResponse().setBody("{\"name\": \"Gson\"}")); server.enqueue(new MockResponse().setBody("<user name=\"SimpleXML\"/>")); server.enqueue(new MockResponse().setBody("{\"name\": \"Gson\"}")); com.squareup.moshi.Moshi moshi = new com.squareup.moshi.Moshi.Builder().build(); com.google.gson.Gson gson = new GsonBuilder().create(); MoshiConverterFactory moshiConverterFactory = MoshiConverterFactory.create(moshi); GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(gson); SimpleXmlConverterFactory simpleXmlConverterFactory = SimpleXmlConverterFactory.create(); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")) .addConverterFactory( new AnnotatedConverterFactory.Builder().add(Moshi.class, moshiConverterFactory) .add(Gson.class, gsonConverterFactory) .add(SimpleXml.class, simpleXmlConverterFactory) .build()) .addConverterFactory(gsonConverterFactory) .build(); Service service = retrofit.create(Service.class); Library library1 = service.exampleMoshi().execute().body(); System.out.println("Library 1: " + library1.name); Library library2 = service.exampleGson().execute().body(); System.out.println("Library 2: " + library2.name); Library library3 = service.exampleSimpleXml().execute().body(); System.out.println("Library 3: " + library3.name); Library library4 = service.exampleDefault().execute().body(); System.out.println("Library 4: " + library4.name); server.shutdown(); } }