我正在使用库com.squareup.retrofit:retrofit:1.9.0
,以便从我的Android应用程序向我的服务器发送数据。
事实上,当我想向服务器发送请求时,我发现了这个错误:
failure : retrofit.RetrofitError: 307 Temporary Redirect
我尝试了许多想法,但同样的问题仍然存在。
请专家帮我解决此问题。
此致
答案 0 :(得分:5)
编辑:如果您不能使用Retrofit 1.9,切换到更新版本(即2.0+)应自动处理下面介绍的解决方案。
看起来你的HTTP客户端(在Android端)应该通过读取发生这种情况时收到的响应头中的Location
值来处理这种重定向,这应该包含你应该从中发现的目标重定向URL客户再次。
查看他们的评论here。
所以现在你需要在应用程序级别实现它(这个 对于Retrofit 1来说很难,对于即将推出的Retrofit 2或者更容易 等到OkHttp 3.1(ish),当我们实施最新规范时。
另请参阅307的含义。
修复307错误 - 一般来自Web服务器的307响应 应始终包含重定向应该的备用URL 发生。如果是这样,Web浏览器将立即重试 替代URL。所以你永远不会在Web上看到307错误 浏览器,除非您有一个损坏的重定向链,例如网址 重定向到URL B,后者又重定向回URL A.如果你的 客户端不是Web浏览器,它应该以与Web相同的方式运行 浏览器即立即重试备用URL。
如果Web服务器未返回307的备用URL 响应,然后Web服务器软件本身是有缺陷的或 网站管理员尚未正确设置网址重定向。
请参阅Retrofit 1.9.0的javadoc以从响应中获取Location头值(URL);
// omitting null check for brevity
for (Header header : response.getHeaders())
{
if (header.getName().equals("Location")) {
redirectURL = header.getValue();
}
}
// do a redirect to redirectURL
答案 1 :(得分:4)
您正在使用旧依赖
更改您的依赖关系 “com.squareup.retrofit:改型:1.9.0”
到
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
还添加此依赖项以获取完整日志
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'.
在您的Retrofit客户端类
中添加此方法HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout("Your_Time", TimeUnit.SECONDS);
httpClient.readTimeout("Your_Time", TimeUnit.SECONDS);
httpClient.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("BASE URL")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
下面的代码是处理Http协议异常
public Response post(String url, String content) throws IOException {
RequestBody body = RequestBody.create(PROTOCOL, content);
Request.Builder requestBuilder = new Request.Builder().url(url).post(body);
Request request = requestBuilder.build();
Response response = this.client.newCall(request).execute();
if(response.code() == 307) {
String location = response.header("Location");
return post(location, content);
}
return response;
}
答案 2 :(得分:3)
经过多方努力,我得到了解决方案。可能这会对你有所帮助。如果您收到此错误“203 HTTP 307临时重定向”,那么此技巧将对您有所帮助。 最后将'/'附加到您的网络服务,然后检查此错误消失。我不知道背后的原因,但它对我有用。
对我来说,我的旧请求网络服务:https://mydomain/rest/Search。 使用此URL我得到“203 HTTP 307临时重定向”,我可以在POSTMAN和Web浏览器中获得响应。
我的新请求网络服务有诀窍:https://mydomain/rest/Search/。 '/'解决了这个问题。
答案 3 :(得分:1)
尝试放置HttpLoggingInterceptor
并检查日志。如果您的服务器返回正确的响应或者没有提供输入以及参数,还要与Rest Client进行交叉检查。
对于HttpLoggingInterceptor
,这是以下配置方式
public RestClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("BASEURL")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
//APIInterface initiation
service = retrofit.create(APIInterface.class);
}
以下是相同
的依赖关系compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
如果您正在关注启动其他客户端的其他可能性,请浏览此Sample tutorial Retrofit
答案 4 :(得分:1)
您可以创建一个额外的拦截器来处理307
private static class RedirectInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(chain.request());
if (response.code() == 307) {
request = request.newBuilder()
.url(response.header("Location"))
.build();
response = chain.proceed(request);
}
return response;
}
}
并将RedirectInterceptor添加到您的okHttpClient(例如,okhttp2)
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(new RedirectInterceptor());
okHttpClient.setFollowRedirects(false);
您可以使用LaxRedirectStrategy创建一个ApacheClient
private ApacheClient createRedirectClient(){
return new ApacheClient(HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy()).build());
}
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint("http://yourendpoint")
.setClient(createRedirectClient());
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
答案 5 :(得分:0)
如果要处理所有307个响应,则可以创建并添加Interceptor
来完成此工作;该拦截器仅使用响应头“ location”中指示的新路径创建一个新请求。
val client = OkHttpClient.Builder()
.addInterceptor {
val request = it.request()
val response = it.proceed(request)
if (response.code() == 307) {
val url = HttpUrl.Builder()
.scheme(request.url().scheme())
.host(request.url().host())
.addPathSegment(response.header("location", request.url().url().path)?: "")
.build()
val newRequest = Request.Builder()
.method(request.method(), request.body())
.url(url)
.headers(request.headers())
.build()
return@addInterceptor it.proceed(newRequest)
}
response
}
.build()
Retrofit.Builder().client(client).build()