8

我在一个项目中使用 Volley 框架,我总是需要自己处理重定向来处理标头。

如何处理重定向现在取决于方法和传输层。我想使用 Volley 的默认值(自动选择传输层)而不更改任何 Volley 代码。

一个有效的解决方案是始终使用 OkHttp 作为传输层(如问题和 Volley 的贡献中所述),但我想知道是否有没有额外框架的方法。

因此,我正在寻找一种“干净”的方式来禁用自动重定向处理。

编辑:

我更喜欢使用 OkHttp,这样我就不必自己管理在什么 Android 上使用什么版本,但是当想要更改传输层行为时,Itai Hanski 提供的解决方案非常好。

4

4 回答 4

17

如果您不关心旧 API (< 9),并且您只想 volley 停止跟随重定向,您可以这样做

RequestQueue requestQueue = Volley.newRequestQueue(context, new HurlStack() {
    @Override
    protected HttpURLConnection createConnection(URL url) throws IOException {
        HttpURLConnection connection = super.createConnection(url);
        connection.setInstanceFollowRedirects(false);

        return connection;
    }
});
于 2014-09-17T09:42:41.960 回答
7

我认为使用 OkHttp作为其传输的VolleyHttpStack实现是最好的解决方案

RequestQueue queue = Volley.newRequestQueue(this);

Network network = new BasicNetwork(new OkHttpStack());
RequestQueue queue = new RequestQueue(new DiskBasedCache(new File(getCacheDir(), "volley")), network);
queue.start();

OkHttpStack 类:

public class OkHttpStack extends HurlStack {
private final OkHttpClient client;

public OkHttpStack() {
this(new OkHttpClient());
}

public OkHttpStack(OkHttpClient client) {
if (client == null) {
throw new NullPointerException("Client must not be null.");
}
this.client = client;
}

@Override protected HttpURLConnection createConnection(URL url) throws IOException {
return client.open(url);
}
}

更新: 如果您使用的是新版本的 okhttp 堆栈,请使用

public class OkHttpStack extends HurlStack {
    private final OkUrlFactory mFactory;

    public OkHttpStack() {
        this(new OkHttpClient());
    }

    public OkHttpStack(OkHttpClient client) {
        if (client == null) {
            throw new NullPointerException("Client must not be null.");
        }
        mFactory = new OkUrlFactory(client);
    }

    @Override
    protected HttpURLConnection createConnection(URL url) throws IOException {
       return mFactory.open(url);
    }
}
于 2013-09-17T06:19:18.630 回答
3

此解决方案不需要其他框架:

Volley 默认使用 AndroidHTTPClient 或 Apache(如果 SDK 级别为 8 及以下)。您可以覆盖/继承您想要在这些类中重定向的更改,并HttpStack使用它们创建自定义,将其提供给Volley.newRequestQueue().

编辑:

假设很长的命名自定义HttpStack实现是你的:

HttpStack stack;
if (Build.VERSION.SDK_INT >= 9) {
    stack = new RedirectionHurlStack();
} else {
    stack = new RedirectionHttpClientStack();
}

sRequestQueue = Volley.newRequestQueue(context, stack);
于 2013-09-16T09:21:23.967 回答
1

尝试使用网络响应标头中的 Location 值进行更多呼叫

Kotlin 实现

fun fetchRemoteList(
    url: String,
    context: Context,
    callback: OnFetchListCompleted,
    firstTry: Boolean = true
) {
    val queue = Volley.newRequestQueue(context)
    val stringRequest = StringRequest(
        Request.Method.GET, url,
        Response.Listener { response ->
            GlobalScope.launch {
                callback.fetchListSucceed()
            }
        },
        Response.ErrorListener { error ->
            val locationRedirectUrl: String? = error?.networkResponse?.headers?.get("Location")

            if (firstTry && !locationRedirectUrl.isNullOrEmpty()) {
                fetchRemoteList(locationRedirectUrl, context, callback, false)
            } else {
                callback.fetchListFailed(error?.message ?: "")
            }
        })

    queue.add(stringRequest)
}
于 2020-12-11T02:12:46.250 回答