Изменить политику перенаправления Volley Framework
Я использую платформу Volley в проекте, где мне всегда нужно обрабатывать перенаправления самостоятельно для обработки заголовков.
Как перенаправления обрабатываются, прямо сейчас зависит от метода и транспортного уровня. Я хотел бы использовать значения по умолчанию для Volley (автоматический выбор транспортного уровня) без изменения какого-либо кода залпа.
Правильное решение - всегда использовать OkHttp в качестве транспортного уровня (как упомянуто в " Проблемы и вклады в Volley"), но я хотел бы знать, есть ли способ без дополнительной структуры.
Поэтому я ищу "чистый" способ отключить автоматическую обработку перенаправления.
Редактировать:
Я предпочитаю использовать OkHttp, чтобы мне не приходилось самим определять, какую версию использовать на каком Android, но решение, предоставленное Itai Hanski, очень хорошо, когда нужно изменить поведение транспортного уровня.
4 ответа
Я думаю HttpStack
реализация Volley, которая использует OkHttp в качестве своего транспорта, является лучшим решением
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);
}
}
Если вас не интересуют старые API (< 9), и вы просто хотите остановить залп после перенаправления, вы можете сделать
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;
}
});
Это решение не требует другой структуры:
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);
Попробуйте еще раз позвонить со значением Location из заголовков сетевых ответов.
Котлин Реализация
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)
}