レトロフィットは、あなたが使用することができますConverter.Factory
抽象クラスを持って助けることを願っています -
public class PostParams extends HashMap<String, String> {
public static PostParams init() {
return new PostParams();
}
public PostParams add(String param, String value) {
put(param, value);
return this;
}
public PostParams add(String param, String[] values) {
put(param, new Gson().toJson(values));
return this;
}
public PostParams add(String param, int[] values) {
put(param, new Gson().toJson(values));
return this;
}
public PostParams add(String param, int value) {
put(param, value + "");
return this;
}
public PostParams addPlatform() {
put("Platform", Constants.ANDROID);
return this;
}
public PostParams add(String param, double value) {
put(param, new Gson().toJson(value));
return this;
}
@Override
public String toString() {
return new Gson().toJson(this);
}
}
使い方は以下のようになりますカスタムHTTP表現を行います。メソッドに特定のアノテーションがある場合は、コンバータを作成してokhttp.RequestBody
を作成できます。
最終的な結果は次のようになります。
@POST("/")
Call<Void> postBar(@Body @Root("bar") String foo)
と変換:postBar("Hello World")
{ "bar" : "Hello World" }
に 。
今すぐ始めましょう。
ステップ1 - 注釈(JSONConverterFactory.java)を検出し、あなたのConverter.Factoryを定義する - ルートキー(Root.java)
/**
* Denotes the root key of a JSON request.
* <p>
* Simple Example:
* <pre><code>
* @POST("/")
* Call<ResponseBody> example(
* @Root("name") String yourName);
* </code></pre>
* Calling with {@code foo.example("Bob")} yields a request body of
* <code>{name=>"Bob"}</code>.
* @see JSONConverterFactory
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Root {
/**
* The value of the JSON root.
* Results in {"value" : object}
*/
String value();
}
ステップ2のための注釈を作成します。 JSONの解析にGsonを使用していますが、どのようなフレームワークを使用しても構いません。
/**
* Converts @Root("key") Value to {"key":json value} using the provided Gson converter.
*/
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));
}
}
}
ステップ3 - あなたのレトロフィットインスタンスにJSONConverterFactoryをインストール
Gson gson = new GsonBuilder().create(); // Or your customized version
Retrofit.Builder builder = ...;
builder.addConverterFactory(new JSONConverterFactory(gson))
ステップ4 - 利益
@POST("/")
Call<Void> postBar(@Body @Root("bar") String foo)
またはあなたのケースのために:
私は次のように使用
@POST("foo/{fooId}/bars")
Observable<Void> postBar(@Body @Root("bar") String barValue, @Path("fooId") String styleId);
参照してください。この[メタ議論](http://meta.stackoverflow.com/q/327487/230513)に地図を変更します。 – trashgod