与改造一起使用时,OkHttp 不会重定向 POST 请求

Posted

技术标签:

【中文标题】与改造一起使用时,OkHttp 不会重定向 POST 请求【英文标题】:OkHttp doesn't redirect POST requests when used with retrofit 【发布时间】:2016-08-06 03:06:56 【问题描述】:

使用retrofit 我想向http://milzinas.lt/oauthsilent/authorize 发出POST 请求。这个 URL 很特别,因为它将您重定向到 http://milzinas.e-bros.lt/oauthsilent/authorize。我的改造设置使用OkHttpClient。如果我只使用 OkHttpClient 发出请求,则重定向工作正常,即收到 401 状态代码。但是,当我使用带有改造的相同 OkHttpClient 时,响应是状态码 307。我认为这与包装 OkHttpClient 的OkClient 实现有关,但我不确定。下面是我用来测试这个场景的代码。我正在使用这些库:

com.squareup.retrofit:retrofit:1.9.0
com.squareup.okhttp:okhttp:2.2.0

我了解当 URL 将您重定向到另一个 URL 时,http 客户端必须发出两个请求。在我的情况下,第一个请求返回 307(临时重定向),第二个请求返回 401(未授权)。但是,改造总是返回第一个请求的响应。您知道如何通过改造使重定向正常工作吗?也许我可以通过使用其他一些 HTTP 客户端来实现这一点?任何建议将不胜感激。

所以当我在控制台打印下面执行代码时

Retrofit failure. Status: 307
OkHttp. Status: 401

我希望它是

Retrofit failure. Status: 401
OkHttp. Status: 401

public class MainActivity extends AppCompatActivity 

interface Api 

    @POST(URL)
    @Headers("Accept: application/json")
    void test(@Body Object dummy, Callback<Object> callback);



static final String BASE_URL = "http://milzinas.lt";
static final String URL = "/oauthsilent/authorize";

final OkHttpClient okHttpClient = new OkHttpClient();
Api api;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    RestAdapter retrofit = new RestAdapter.Builder()
            .setEndpoint(BASE_URL)
            .setClient(new OkClient(okHttpClient))
            .setConverter(new Converter() 
                @Override
                public Object fromBody(TypedInput body, Type type) throws ConversionException 
                    return null;
                

                @Override
                public TypedOutput toBody(Object object) 
                    return null;
                
            )
            .build();

    api = retrofit.create(Api.class);

    makeRequestOkHttp();
    makeRequestRetrofit();


void makeRequestOkHttp() 
    new AsyncTask<Object, Object, Object>() 
        @Override
        protected Object doInBackground(Object... objects) 
            try 
                Request request = new Request.Builder().url(BASE_URL + URL).build();
                com.squareup.okhttp.Response response = okHttpClient.newCall(request).execute();
                android.util.Log.d("matka", "OkHttp. Status: " + response.code());
             catch (IOException e) 
                throw new RuntimeException(e);
            

            return null;
        
    .execute();


void makeRequestRetrofit() 
    api.test("", new Callback<Object>() 
        @Override
        public void success(Object o, Response response) 
            android.util.Log.d("matka", "Retrofit success. Status: " + response.getStatus());
        

        @Override
        public void failure(RetrofitError error) 
            android.util.Log.d("matka", "Retrofit failure. Status: " + error.getResponse().getStatus());
        
    );

【问题讨论】:

请升级到更新的 OkHttp。 2.7.5 修复了很多问题。 OkHttp 3.x 更好! 即使使用最新的改造 (2.0.0-beta2) 和 OkHttp (3.2.0) 版本,问题仍然存在。 【参考方案1】:

即使在最新的 v3.5.0 中问题仍然存在 唯一有效的解决方法是 https://github.com/square/okhttp/issues/936#issuecomment-266430151

【讨论】:

以上是关于与改造一起使用时,OkHttp 不会重定向 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章

将 PrimeFaces 与 JSF 一起使用时 Shiro 重定向到错误的位置

改造:如何从 okhttp 拦截器再次重试请求?

当我将 Ajax 与 spring 控制器一起使用时,它会被重定向 [重复]

使用改造 2 将图像从画廊/相机上传到服务器(okhttp 问题)

离线时使用 OKHttp 进行改造如何使用缓存数据

重定向与请求转发