Retrofit has an abstract Converter.Factory class that you can use to create a custom HTTP view. You can create a converter to build okhttp.RequestBody if the method has a specific annotation.
The end result will look like this:
@POST("/") Call<Void> postBar(@Body @Root("bar") String foo)
and converting: postBar("Hello World") to { "bar" : "Hello World" } .
Let's start.
Step 1 - create an annotation for the root key (Root.java)
@Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Root { String value(); }
Step 2 - Define your Converter.Factory that detects the annotation (JSONConverterFactory.java). I use Gson to parse JSON, but you can use whatever framework you want.
class JSONConverterFactory extends Converter.Factory { private final Gson gson; private static final MediaType CONTENT_TYPE = MediaType.parse("application/json"); JSONConverterFactory(Gson gson) { this.gson = gson; } @Override public Converter<?, RequestBody> requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { for (Annotation annotation : parameterAnnotations) { if (annotation instanceof Root) { Root rootAnnotation = (Root) annotation; return new JSONRootConverter<>(gson, rootAnnotation.value()); } } return null; } private final class JSONRootConverter<T> implements Converter<T, RequestBody> { private Gson gson; private String rootKey; private JSONRootConverter(Gson gson, String rootKey) { this.gson = gson; this.rootKey = rootKey; } @Override public RequestBody convert(T value) throws IOException { JsonElement element = gson.toJsonTree(value); JsonObject object = new JsonObject(); object.add(this.rootKey, element); return RequestBody.create(CONTENT_TYPE, this.gson.toJson(object)); } } }
Step 3 - set the JSONConverterFactory to the RetoFit instance
Gson gson = new GsonBuilder().create();
Step 4 - Profit
@POST("/") Call<Void> postBar(@Body @Root("bar") String foo)
Or for your case:
@POST("foo/{fooId}/bars") Observable<Void> postBar(@Body @Root("bar") String barValue, @Path("fooId") String styleId);
source share