最近、ネットワークリクエストにGoogleのVolley libを使用し始めました。私のリクエストの1つはリダイレクトでエラー301を受け取りますので、私の質問はリダイレクトをなんとか自動で処理できるか、parseNetworkError
で手動で処理する必要があるか、何らかの種類のRetryPolicy
hereを使用する必要がありますか?
ありがとう。
Httpステータス301または302をキャッチし、リダイレクトURLを読み取り、リクエストに設定し、再試行をトリガーする期待値をスローするように修正しました。
編集:これは私が変更したvolley libのメインキーです:
クラスRequest
のメソッドpublic void setUrl(final String url)
が追加されました
クラスBasicNetworkに追加されたリダイレクト後のチェック//キャッシュの検証、if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) || statusCode == HttpStatus.SC_MOVED_TEMPORARILY)
を処理し、そこでresponseHeaders.get("location")
でリダイレクトURLを読み取り、リクエストオブジェクトでsetUrl
を呼び出してスローしますエラー
エラーがキャッチされ、attemptRetryOnException
を呼び出します
RetryPolicy
にRequest
を設定する必要もあります(これについてはDefaultRetryPolicy
を参照してください)
Url.replace( "http"、 "https");のようにURLを置き換えます。
たとえば、URLが次のようになっている場合: " http://graph.facebook ......."よりも次のようになります: " https:// graph。 facebook .......」
わたしにはできる
Volleyライブラリを変更したくない場合は、301をキャッチしてリクエストを手動で再送信できます。
GsonRequestクラスで、deliverErrorを実装し、ヘッダーからの新しいLocation URLを使用して新しいRequestオブジェクトを作成し、それを要求キューに挿入します。
このようなもの:
@Override
public void deliverError(final VolleyError error) {
Log.d(TAG, "deliverError");
final int status = error.networkResponse.statusCode;
// Handle 30x
if(HttpURLConnection.HTTP_MOVED_PERM == status || status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_SEE_OTHER) {
final String location = error.networkResponse.headers.get("Location");
Log.d(TAG, "Location: " + location);
final GsonRequest<T> request = new GsonRequest<T>(method, location, jsonRequest, this.requestContentType, this.clazz, this.ttl, this.listener, this.errorListener);
// Construct a request clone and change the url to redirect location.
RequestManager.getRequestQueue().add(request);
}
}
この方法で、Volleyの更新を続けることができ、物事が壊れる心配はありません。
他の多くの人と同じように、私はボレーがリダイレクトを自動的に追跡しなかった理由について単に混乱していました。ソースコードを見ると、VolleyはリダイレクトURLを正しく設定しますが、リクエストの再試行ポリシーで少なくとも1回「再試行」を指定しない限り、実際にはリダイレクトURLを追跡しません。不可解なことに、デフォルトの再試行ポリシーはmaxNumRetries
を0に設定します。そのため、1回の再試行(デフォルトから10秒のタイムアウトと1xのバックオフをコピー)で再試行ポリシーを設定します。
request.setRetryPolicy(new DefaultRetryPolicy(10000, 1, 1.0f))
参考のために、ソースコードを次に示します。
/**
* Constructs a new retry policy.
* @param initialTimeoutMs The initial timeout for the policy.
* @param maxNumRetries The maximum number of retries.
* @param backoffMultiplier Backoff multiplier for the policy.
*/
public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
mCurrentTimeoutMs = initialTimeoutMs;
mMaxNumRetries = maxNumRetries;
mBackoffMultiplier = backoffMultiplier;
}
または、301または302のイベントでのみ「再試行」するRetryPolicy
のカスタム実装を作成できます。
これが誰かを助けることを願っています!
Volleyは、パッチなしでリダイレクトをサポートします。別のフォークは不要です
説明:Volleyは内部でHttpClient
を使用します。特に指定されない限り、デフォルトでは301/302に従います
From: http://hc.Apache.org/httpcomponents-client-4.2.x/tutorial/html/httpagent.html
ClientPNames.HANDLE_REDIRECTS = 'http.protocol.handle-redirects':リダイレクトを自動的に処理するかどうかを定義します。このパラメーターには、Java.lang.Boolean型の値が必要です。このパラメーターが設定されていない場合、HttpClientはリダイレクトを自動的に処理します。
oK、ここのゲームには少し遅れていますが、最近この同じ側面を達成しようとしているので、 https://stackoverflow.com/a/17483037/2423312 はあなたがボレーを分岐し、それを維持し、ここで答えを喜んで与えられることを考えると、最高のもの: https://stackoverflow.com/a/27566737/2423312 -私はわからないこれがどのように機能したか。これはスポットです: https://stackoverflow.com/a/28454312/2423312 。しかし、実際にはNetworkDipatcher
のキューに新しいリクエストオブジェクトを追加するため、何らかの方法で呼び出し元に通知する必要があります。one dirty wayリクエストオブジェクトを変更せずにこれを行うことができます+フィールド「mURL」を変更します。これはIS DEPENDENT VOLLEY'Sの実装についてRetryPolicy.Java
インターフェイスとクラスの拡張方法Request.Java
CLASS ARE、here you go:歓迎の反射
Class volleyRequestClass = request.getClass().getSuperclass();
Field urlField = volleyRequestClass.getDeclaredField("mUrl");
urlField.setAccessible(true);
urlField.set(request, newRedirectURL);
個人的には、ボレーのクローンを作成したいです。さらに、ボレーの例BasicNetwork
クラスはリダイレクトで失敗するように設計されているようです: https://github.com/google/volley/blob/ddfb86659df59e7293df9277da216d73c34aa800/src/test/Java/com/Android /volley/toolbox/BasicNetworkTest.Java#L156 なので、リダイレクトに頼りすぎていると思うので、気軽に提案/編集してください。常に良い方法を探しています。
ほとんどの@nikoと@slottが答えたものをマージすることになります。
// Request impl class
// ...
@Override
public void deliverError(VolleyError error) {
super.deliverError(error);
Log.e(TAG, error.getMessage(), error);
final int status = error.networkResponse.statusCode;
// Handle 30x
if (status == HttpURLConnection.HTTP_MOVED_PERM ||
status == HttpURLConnection.HTTP_MOVED_TEMP ||
status == HttpURLConnection.HTTP_SEE_OTHER) {
final String location = error.networkResponse.headers.get("Location");
if (BuildConfig.DEBUG) {
Log.d(TAG, "Location: " + location);
}
// TODO: create new request with new location
// TODO: enqueue new request
}
}
@Override
public String getUrl() {
String url = super.getUrl();
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = "http://" + url; // use http by default
}
return url;
}
StringRequest
メソッドをオーバーライドしてうまく機能しました。
それが誰にも役立つことを願っています。
リクエストに問題がありましたが、https URLでvolley:1.1.1を使用しています。さらに掘り下げると、リダイレクト(永続リダイレクト301)により、リクエストメソッドがPOSTからGETに変更されていることがわかりました。私はnginxを使用しており、問題を引き起こしていました。
つまり、ボレーの最新バージョンではすべてが順調です。私のユーティリティ機能はこちら
public void makePostRequest(String url, JSONObject body, final AjaxCallback ajaxCallback) {
try {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,
url, body, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(LOG, response.toString());
ajaxCallback.onSuccess(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(LOG, error.toString());
ajaxCallback.onError(error);
}
});
singleton.getRequestQueue().add(jsonObjectRequest);
} catch(Exception e) {
Log.d(LOG, "Exception makePostRequest");
e.printStackTrace();
}
}
// separate file
public interface AjaxCallback {
void onSuccess(JSONObject response);
void onError(VolleyError error);
}