我目前正在开发Android应用程序,该应用程序使用Retrofit和OkHttpClient从服务器获取/发送数据。 这在调用我自己的服务器时很棒,而在尝试调用谷歌地图 API 时遇到 404 错误。
下面表示有错误的响应。
Response{protocol=h2, code=404, message=, url=https://maps.googleapis.com/maps%2Fapi%2Fgeocode%2Fjson%3Fkey=defesdvmdkeidm&latlng=11.586215,104.893197}
这显然是因为"/"和"?"被编码为"%2F"和"%3F"。 解决方案可能是阻止这些特殊字符的urlencode,但无法做到。
我尝试的是添加自定义标题"内容类型:应用程序/x-www-form-urlencoded;charset=utf-8"通过拦截器到OkHttpClient,但这不起作用。
最好的详细回复将不胜感激。
问候。
private Retrofit createRetrofit(OkHttpClient client, String _baseUrl) {
return new Retrofit.Builder()
.baseUrl(_baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
}
private Retrofit createGoogleRetrofit() {
return createRetrofit(createGoogleClient(), baseUrl);
}
public DenningService getGoogleService() {
_baseUrl = "https://maps.googleapis.com/";
final Retrofit retrofit = createGoogleRetrofit();
return retrofit.create(DenningService.class);
}
public interface DenningService {
@GET("{url}")
@Headers("Content-Type:application/x-www-form-urlencoded; charset=utf-8")
Single getEncodedRequest(@Path("url") String url);
}
private void sendRequest(final CompositeCompletion completion, final ErrorHandler errorHandler) {
mCompositeDisposable.add(mSingle.
subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function() {
@Override
public JsonElement apply(JsonElement jsonElement) throws Exception {
return jsonElement;
}
})
.subscribeWith(new DisposableSingleObserver() {
@Override
public void onSuccess(JsonElement jsonElement) {
completion.parseResponse(jsonElement);
}
@Override
public void onError(Throwable e) {
if (e instanceof HttpException && ((HttpException) e).code() == 410) {
errorHandler.handleError("Session expired. Please log in again.");
} else {
errorHandler.handleError(e.getMessage());
}
e.printStackTrace();
}
})
);
}
public void sendGoogleGet(String url, final CompositeCompletion completion) {
mSingle = getGoogleService().getEncodedRequest(url);
sendRequest(completion, new ErrorHandler() {
@Override
public void handleError(String error) {
ErrorUtils.showError(context, error);
}
});
}
The problem is in the definition of your Retrofit service interface and the values you pass to it.
public interface DenningService { @GET("{url}") @Headers("Content-Type:application/x-www-form-urlencoded; charset=utf-8") Single getEncodedRequest(@Path("url") String url); }
根据您发布的内容,我将假设
url
的值为:maps/api/geocode/json?key=defesdvmdkeidm&latlng=11.586215,104.893197
它应该如下所示:
public interface DenningService { @FormUrlEncoded @GET("/maps/api/geocode/json") Single getEncodedRequest(@Field("key") String key, @Field("latlng") String latlng); }
然后你会这样称呼它:
mSingle = getGoogleService().getEncodedRequest(key, latlng);
当然,您必须弄清楚如何将
key
和latlng
参数从当前url
字符串中分离出来。编辑
对我来说,您是否真的希望您的请求被
application/x-www-form-urlencoded
,或者您是否只是在尝试看看它是否解决了您的问题,这对我来说并不明显。如果您不想要它,那么您的界面将如下所示:public interface DenningService { @GET("/maps/api/geocode/json") Single getEncodedRequest(@Query("key") String key, @Query("latlng") String latlng); }