失败:retrofit.RetrofitError:307临时重定向?

时间:2015-12-16 14:33:24

标签: java android retrofit

我正在使用库com.squareup.retrofit:retrofit:1.9.0,以便从我的Android应用程序向我的服务器发送数据。

事实上,当我想向服务器发送请求时,我发现了这个错误:

failure : retrofit.RetrofitError: 307 Temporary Redirect

我尝试了许多想法,但同样的问题仍然存在。

请专家帮我解决此问题。

此致

6 个答案:

答案 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);

http://static.javadoc.io/com.squareup.retrofit/retrofit/1.9.0/retrofit/client/Response.html#getHeaders--

// 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)

解决方案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);

解决方案2

您可以使用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()