web-dev-qa-db-ja.com

後付けパスの置換:パス全体(/を含む)を置換

私のセットアップでは、リソースのすべてのパスをREST APIからAPIへの最初の呼び出しから取得します。このパターンを使用して、既存のすべてを壊すことなくすべてのリソースパスを変更できるようにしますプロセス中のアプリのバージョン。

私はRetrofitをいじくり回していて、渡したパスを文字列として受け入れるメソッドを作成しようとしました。私の試みはこのように見えます

@GET("/{path}")
public FooBar getFooBar(@Path("path") String path);

次に、次のように呼び出します。

String path = "foo/bar";
api.getFooBar(path);

残念ながら、レトロフィットはパス置換をURLエンコードし、最終的に/foo%2Fbar の代わりに /foo/bar。パス置換のURLエンコードを無効にする方法、または複数のパスセグメントにまたがる置換を行う方法はありますか?残念ながら、パスセグメントがいくつあるかもわかりません。すべてAPIによって制御されています。

29
Thrakbad

_@EncodedPath_ を使用してください!それでおしまい。私はJavadocをコピーして、この答えがより重要になるようにします。

URLパスの名前付き置換。値はString.valueOf(Object)を使用して文字列に変換されます。値は、URLエンコードなしで文字どおりに使用されます。同等のURLエンコーディングについては、_@Path_を参照してください。

次のように使用します。

_@GET("/{path}")
void example(@EncodedPath("path") String path, ..);
_
44
Jake Wharton

@EncodedPathは現在廃止されているため

改良1.9:

@GET("/{path}")
void example(@Path(value = "path", encoded = false) String path, ..);

後付け2. *:

@GET("/{path}")
void example(@Path(value = "path", encoded = false) String path, ..);
18
Andrey

既知のバグがあり、バグレポートを見ることができます: Retrofit @Github

可能な解決策へのリンクもあります: Solution @Github

最後に、改造開発者からのメッセージは次のとおりです。

「複数のパスセグメントにまたがるパスの置換はサポートされません。パスセグメントの数が動的に変化する場合は、@ Urlを使用して完全な相対URLをプログラムで作成する必要があります。」

したがって、エンコードに問題がある場合の解決策は次のとおりです。

GETのAPI:

@GET
Call<Object> Function(@Url String path, @Query("CONTENT") String content);

POSTのAPI:

@FormUrlEncoded
@POST
Call<Object> Function(@Url String path, @Field("CONTENT") String content);

そして、これでこれを呼び出すことができます:

String thePath = "www.foo.de/foo/foo2";
Call<Object> call = api.Function(thePath,content);

したがって、これを使用すると、何かをエンコードする問題が発生しません。

しかし、バージョン2. *で通常のエンコードを探しているだけの場合、APIは次のようにする必要があります。

@GET("/{path}")
void example(@Path(value = "path", encoded = false) String path, ..);

よろしく

9
Klatschen

テスト済みで、現在動作しています。解決策は、適切なURLがヒットすることを確認するために、encoded = trueを追加することです。例えば:

@POST("{attendance_path}")
Single<Response> upLoadAttendence (@PartMap HashMap<String, RequestBody> postData,@Path(value = "attendance_path",encoded = true) String path);
1
Debasish Ghosh

私は同じ問題に直面し、コードの下でそれを解決します

 @POST(ApiKey.URL.add_edit_notice + "{id}")
    @FormUrlEncoded
    Call<GenericResponse> callAddNotice(@Path(value = "id", encoded = true)  String id,
                                        @Field("user_id") String user_id,
                                        @Field("title") String title,
                                        @Field("description") String description,
                                        @Field("school_id") String school_id,
                                        @Field("filename") String filename);
0
tej shah