关于android:Retrofit路径替换:整个路径替换(包括/)

Retrofit path replacements: replacement over whole path (including /)

在我的设置中,我从REST API的最初调用中获得了我的资源的所有路径。 我们使用此模式能够更改所有资源路径,而不会破坏该过程中所有现有的应用程序版本。

我一直在研究Retrofit,我试图创建一个方法来接受我以字符串形式传递给它的任何路径。 我的尝试看起来像这样

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

然后,我尝试将其称为如下。

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

不幸的是,URL编码经过了改造,对路径替换进行编码,最终我向/foo%2Fbar而不是/foo/bar发出了请求。 有什么方法可以禁用URL编码进行路径替换或进行跨越多个路径段的替换吗? 不幸的是,我什至不知道有多少路径段,它们全部由API控制。


使用@EncodedPath!而已。我将复制Javadoc,以便此答案更加实用:

Named replacement in the URL path. Values are converted to string using String.valueOf(Object). Values are used literally without URL encoding. See @Path for URL encoding equivalent.

像这样使用它:

1
2
@GET("/{path}")
void example(@EncodedPath("path") String path, ..);


由于@EncodedPath现在已被弃用

改良版1.9:

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

改造2. *:

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


有已知的错误,您可以在以下位置查看错误报告:
改造@Github

还有一个指向可能解决方案的链接:解决方案@Github

最后,来自改造开发人员的消息是:

"将不支持跨越多个路径段的路径替换,如果路径段的数量动态变化,则应使用@Url以编程方式构建完整的相对URL。"

因此,如果您在编码方面遇到麻烦,则解决方案可以是:

您的GET API:

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

您的POST API:

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

您可以这样称呼它:

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

因此,有了这个,您就不会有编码问题。

但是,如果您只是在寻找版本2. *中的常规编码,则API必须像这样:

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

问候


经过测试,现在可以正常工作。
解决方案是仅添加encoding = true以确保正确的url被点击。
例如:

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

我遇到同样的问题并按以下代码解决

1
2
3
4
5
6
7
8
 @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);