ボレー-POST / GETパラメーター


81

ボレーに関するGoogleIO 2013セッションを見たので、ボレーへの切り替えを検討しています。VolleyはPOST / GETパラメーターをリクエストに追加することをサポートしていますか?はいの場合、どうすればよいですか?


2
基調講演全体を見たわけではありませんが、URLにパラメーターを追加するだけでGETを実行できるはずです(例http://example.com?param1=val1&param2=val2
JJJollyjim 2013年

そこまだドキュメントもないようですが、あなたはここにソースを確認することができますandroid.googlesource.com/platform/frameworks/volley/+/master
MMを。

@ JJ56-そうですが、POSTパラメーターはどうですか?ソースコードを見ましたが、POSTパラメータに関連するものは見つかりませんでした。
Ziem 2013年

1
これを言うのは恥ずかしいです。ただし、リクエストのサーバーに本文がない理由を尋ねられた場合は、POST / PUTメソッドを使用していることを確認してください。私はただ疲れていると思います。このコメントが誰かに役立つか、気分が良くなることを願っています
Alwin Kesler 2018年

回答:


64

(Requestを拡張する)Requestクラスで、getParams()メソッドをオーバーライドします。ヘッダーについても同じことを行い、getHeaders()をオーバーライドするだけです。

VolleyテストでTestRequest.javaのPostWithBodyクラスを見ると、例が見つかります。こんな感じになります

public class LoginRequest extends Request<String> {

    // ... other methods go here

    private Map<String, String> mParams;

    public LoginRequest(String param1, String param2, Listener<String> listener, ErrorListener errorListener) {
        super(Method.POST, "http://test.url", errorListener);
        mListener = listener;
        mParams = new HashMap<String, String>();
        mParams.put("paramOne", param1);
        mParams.put("paramTwo", param2);

    }

    @Override
    public Map<String, String> getParams() {
        return mParams;
    }
}

Evan Charltonは親切にも、ボレーの使い方を示す簡単なサンプルプロジェクトを作成してくれました。 https://github.com/evancharlton/folly/


71
ことに注意してくださいgetParamsだけPOSTまたはPUTリクエストで、(デフォルトでは)と呼ばれているではなく、 GETリクエストで。Ogre_BGRの回答を参照してください
Itai Hanski

2
今まで気づかなかったなんて信じられない
Afzal N

@AfzalivE、上記のコードを使用するときにOAuthでAPIリクエストに署名する方法について何かアイデアはありますか?
Bipin Vayalu 2013年

2
@BipinVayalu Google APIに接続している場合は、com.android.volley.AndroidAuthenticator
Pierre-Antoine

mParamsをインスタンス化するのを忘れました。
モリッツ

86

GETパラメータには、次の2つの選択肢があります

最初:質問の下のコメントで示唆されているように、Stringを使用して、パラメーターのプレースホルダーを次のような値に置き換えることができます。

String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s&param2=%2$s",
                           num1,
                           num2);

StringRequest myReq = new StringRequest(Method.GET,
                                        uri,
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener());
queue.add(myReq);

ここで、num1とnum2は、値を含む文字列変数です。

2番目新しい外部HttpClient(4.2.xなど)を使用している場合は、URIBuilderを使用してUriを構築できます。利点は、URI文字列にすでにパラメータが含まれている場合、それをに渡してから、URIBuilderを使用ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8"));してパラメータを追加する方が簡単なことです。そうすれば、「?」かどうかをわざわざチェックする必要がなくなります。はすでにURIに追加されているか、一部を見逃しているため、潜在的なエラーの原因を排除しています。

POSTパラメータの場合、次のように、受け入れられた回答よりも簡単な場合があります。

StringRequest myReq = new StringRequest(Method.POST,
                                        "http://somesite.com/some_endpoint.php",
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener()) {

    protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
        Map<String, String> params = new HashMap<String, String>();
        params.put("param1", num1);
        params.put("param2", num2);
        return params;
    };
};
queue.add(myReq);

たとえば、getParams()メソッドをオーバーライドするだけです。

Andorid Volley Examplesプロジェクトで、(他の多くの基本的なVolleyの例とともに)実用的な例を見つけることができます。


ボレーの例に従いました。これまでのところ、これは最も役立つVollyコードですが、JsonObjectRequestに問題があります。再インストールするまで、createMyReqSuccessListenerで古い応答を受け取りました。ボレーはデータをキャッシュに保存しますか?これを行う方法を提案してください。
SkyWalker 2014年

2
画像のみがキャッシュされます。プロキシがリクエストを傍受していないか確認してください。リクエストのURLがまったく同じで、プロキシが最初の結果を返している可能性がある場合。
Ognyan 2014年

2
「HTTPリソーステスト」と呼ばれるFirefox用のプラグインがあり、Webサーバーに対してリクエストを送信できます。このようなケースをテストするのに非常に役立ちます。URL(および存在する場合はPOSTパラメーター)を入力するだけで、複数の連続した要求に対するサーバーの応答を確認できます。再度同じ応答が得られた場合、結果はおそらくキャッシュされます。その場合、返されたヘッダーを調べて、プロキシヘッダーがあるかどうかを確認できます。「キャッシュなし」について-はい、動作するはずです。
Ognyan 2014年

2
他の人が参加して支援できるように、別の質問を開くことをお勧めします。HURLまたはHttpClientを使用しているスタック、およびテスト対象のAndroidバージョンについて情報を提供してください。新しい質問へのリンクをここに置いて、人々がディスカッションをフォローできるようにしてください。
Ognyan 2014年

3
@Yousifおそらく、これを新しい質問として尋ねると、はるかに良い答えが得られますが、要するに、POSTリクエストを使用すると、GETリクエストに収まらないファイルやその他の大きなデータを送信できます。また、URLサーバーに記録されて機密データが公開される可能性があるため、GETリクエストを使用する場合はセキュリティリスクがあります。
Ognyan 2015

23

CustomRequestは、VolleyのJSONObjectRequestが次のようなパラメータを投稿できないことを解決する方法です。 StringRequest

paramsを追加できるヘルパークラスは次のとおりです。

    import java.io.UnsupportedEncodingException;
    import java.util.Map;    
    import org.json.JSONException;
    import org.json.JSONObject;    
    import com.android.volley.NetworkResponse;
    import com.android.volley.ParseError;
    import com.android.volley.Request;
    import com.android.volley.Response;
    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.toolbox.HttpHeaderParser;

    public class CustomRequest extends Request<JSONObject> {

    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomRequest(String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }

}

Greenchiuに感謝します


@WarrenFaith指摘してくれてありがとう、私は答えを更新しました!
LOG_TAG 2013

3
どうもありがとう、私はこの解決策を得る前に何時間も探していました、それはとても奇妙なので、JSONObjectReuqestgetParams()関数のオーバーライドが機能していません。
Walid Ammar 2014

@MohammadWalid参考 までに、このstackoverflow.com/questions/16902716/を読んで、レトロフィットを使用してみてください。ボレーとレトロフィットの両方をokhttpで使用できます!
LOG_TAG 2014

私はこの解決策を試しましたが、うまくいきませんでした。getParams()は呼び出されません。
マハディ

10

このヘルパークラスは、GETおよびPOSTリクエストのパラメーターを管理します。

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;    

import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;

public class CustomRequest extends Request<JSONObject> {
    private int mMethod;
    private String mUrl;
    private Map<String, String> mParams;
    private Listener<JSONObject> mListener;

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mMethod = method;
        this.mUrl = url;
        this.mParams = params;
        this.mListener = reponseListener;
    }

@Override
public String getUrl() {
    if(mMethod == Request.Method.GET) {
        if(mParams != null) {
            StringBuilder stringBuilder = new StringBuilder(mUrl);
            Iterator<Map.Entry<String, String>> iterator = mParams.entrySet().iterator();
            int i = 1;
            while (iterator.hasNext()) {
                Map.Entry<String, String> entry = iterator.next();
                if (i == 1) {
                    stringBuilder.append("?" + entry.getKey() + "=" + entry.getValue());
                } else {
                    stringBuilder.append("&" + entry.getKey() + "=" + entry.getValue());
                }
                iterator.remove(); // avoids a ConcurrentModificationException
                i++;
            }
            mUrl = stringBuilder.toString();
        }
    }
    return mUrl;
}

    @Override
    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return mParams;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        mListener.onResponse(response);
    }
}

これにより、GETメソッドへのパラメーターの追加が解決されます。ありがとうございます。
pkarc 2016年

2
この場合、イテレータアプローチにより、関数に渡した元のMapparamsオブジェクトが破棄されました。ボレーは内部でGetUrl数回電話をかけているようです。別の回答に投稿されているように、最終的には古典的なforeachアプローチになりました。これが誰がここに着陸するのに役立つことを願っています。:)
Paolo Casciello 2016

3つのパラメーターを使用してリクエストを取得するためにこのヘルパークラスを呼び出す方法
kgandroid 2018

@kgandroid、キーと値を使用してMap <String、String>を作成します。例:Map <String、String> params = new HashMap <String、String>(); params.put( "param1"、 "value1"); params.put( "param2"、 "value2"); params.put( "param3"、 "value3");
アンドレアモット2018

6

対処のGETパラメータIは、アンドレアモットーのソリューションに反復しました。問題は、ボレーがGetUrl数回呼び出し、イテレータを使用した彼の解決策が元のMapオブジェクトを破壊したことでした。後続のVolley内部呼び出しには、空のparamsオブジェクトがありました。

パラメータのエンコードも追加しました。

これはインライン使用法です(サブクラスなし)。

public void GET(String url, Map<String, String> params, Response.Listener<String> response_listener, Response.ErrorListener error_listener, String API_KEY, String stringRequestTag) {
    final Map<String, String> mParams = params;
    final String mAPI_KEY = API_KEY;
    final String mUrl = url;

    StringRequest stringRequest = new StringRequest(
            Request.Method.GET,
            mUrl,
            response_listener,
            error_listener
    ) {
        @Override
        protected Map<String, String> getParams() {
            return mParams;
        }

        @Override
        public String getUrl() {
            StringBuilder stringBuilder = new StringBuilder(mUrl);
            int i = 1;
            for (Map.Entry<String,String> entry: mParams.entrySet()) {
                String key;
                String value;
                try {
                    key = URLEncoder.encode(entry.getKey(), "UTF-8");
                    value = URLEncoder.encode(entry.getValue(), "UTF-8");
                    if(i == 1) {
                        stringBuilder.append("?" + key + "=" + value);
                    } else {
                        stringBuilder.append("&" + key + "=" + value);
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                i++;

            }
            String url = stringBuilder.toString();

            return url;
        }

        @Override
        public Map<String, String> getHeaders() {
            Map<String, String> headers = new HashMap<>();
            if (!(mAPI_KEY.equals(""))) {
                headers.put("X-API-KEY", mAPI_KEY);
            }
            return headers;
        }
    };

    if (stringRequestTag != null) {
        stringRequest.setTag(stringRequestTag);
    }

    mRequestQueue.add(stringRequest);
}

この関数は、ヘッダーを使用してAPIKEYを渡し、リクエストが完了する前にキャンセルするのに役立つTAGをリクエストに設定します。

お役に立てれば。


3

これはあなたを助けるかもしれません...

private void loggedInToMainPage(final String emailName, final String passwordName) {

    String tag_string_req = "req_login";
    StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://localhost/index", new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            Log.d(TAG, "Login Response: " + response.toString());
            try {
                JSONObject jsonObject = new JSONObject(response);
                Boolean error = jsonObject.getBoolean("error");
                if (!error) {

                    String uid = jsonObject.getString("uid");
                    JSONObject user = jsonObject.getJSONObject("user");
                    String email = user.getString("email");
                    String password = user.getString("password");


                    session.setLogin(true);
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);
                    finish();
                    Toast.makeText(getApplicationContext(), "its ok", Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
            System.out.println("volley Error .................");
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("tag", "login");
            params.put("email", emailName);
            params.put("password", passwordName);
            return params;
        }
    };


    MyApplication.getInstance().addToRequestQueue(stringRequest,tag_string_req);
}

3

将来の読者のために

ボレーと一緒に仕事をするのが大好きです。開発時間を節約するために、プロジェクトでVolleyをセットアップするための小さな便利なライブラリGloxey NetwokManagerを作成しようとしました。これには、JSONパーサーと、ネットワークの可用性を確認するのに役立つその他のさまざまなメソッドが含まれています。

使用ConnectionManager.classのためのさまざまな方法ここでバレーボールの文字列バレーボールJSONのリクエストが可能です。ヘッダーの有無にかかわらず、GET、PUT、POST、DELETEのリクエストを行うことができます。ここで完全なドキュメントを読むことができます

この行をgradleファイルに入れるだけです。

  dependencies { 

       compile 'io.gloxey.gnm:network-manager:1.0.1'
   }

ボレーStringRequest

メソッドGET(ヘッダーなし)

    ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, volleyResponseInterface);

使い方?

     Configuration                Description

     Context                      Context 
     isDialog                     If true dialog will appear, otherwise not.
     progressView                 For custom progress view supply your progress view id and make isDialog true. otherwise pass null. 
     requestURL                   Pass your API URL.  
     volleyResponseInterface      Callback for response.  

    ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
    @Override
    public void onResponse(String _response) {

        /**
         * Handle Response
         */
    }

    @Override
     public void onErrorResponse(VolleyError error) {

        /**
         * handle Volley Error
         */
    }

    @Override
    public void isNetwork(boolean connected) {

        /**
         * True if internet is connected otherwise false
         */
    }
});

ボレーStringRequest

メソッドPOST / PUT / DELETE(ヘッダーなし)

    ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, requestMethod, params, volleyResponseInterface);

Use Method : Request.Method.POST
             Request.Method.PUT
             Request.Method.DELETE

Your params : 

HashMap<String, String> params = new HashMap<>();
params.put("param 1", "value");
params.put("param 2", "value");

ConnectionManager.volleyStringRequest(this, true, null, "url", Request.Method.POST, params, new VolleyResponse() {
    @Override
    public void onResponse(String _response) {

        /**
         * Handle Response
         */
    }

    @Override
    public void onErrorResponse(VolleyError error) {

        /**
         * handle Volley Error
         */
    }

    @Override
    public void isNetwork(boolean connected) {

        /**
         * True if internet is connected otherwise false
         */
    }
});

ボーナス

GloxeyJSONパーサー

gloxeyjsonパーサーを使用してAPI応答を解析してください。

  YourModel yourModel = GloxeyJsonParser.getInstance().parse(stringResponse, YourModel.class);

ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
    @Override
    public void onResponse(String _response) {

        /**
         * Handle Response
         */

         try {

          YourModel yourModel = GloxeyJsonParser.getInstance().parse(_response, YourModel.class);

            } catch (Exception e) {
                e.printStackTrace();
            }

    }

    @Override
     public void onErrorResponse(VolleyError error) {

        /**
         * handle Volley Error
         */
         if (error instanceof TimeoutError || error instanceof NoConnectionError) {

                showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                     //handle retry button

                    }
                });

            } else if (error instanceof AuthFailureError) {
            } else if (error instanceof ServerError) {
            } else if (error instanceof NetworkError) {
            } else if (error instanceof ParseError) {
            }

    }

    @Override
    public void isNetwork(boolean connected) {

        /**
         * True if internet is connected otherwise false
         */
          if (!connected) {
                showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //Handle retry button
                    }
                });
    }
});


     public void showSnackBar(View view, String message) {
            Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
     }

     public void showSnackBar(View view, String message, String actionText, View.OnClickListener onClickListener) {
            Snackbar.make(view, message, Snackbar.LENGTH_LONG).setAction(actionText, onClickListener).show();
     }

しかし、それはMethod.Getをサポートしていない
デヴィッドKariuki

はい、あります。詳細をご覧ください。 github.com/adnanbinmustafa/Gloxey-Network-Manager
Adnan

0

POSTパラメーターを提供するJSONObject には、JsonObjectRequestコンストラクターにパラメーターを送信します。3番目のパラメーターは、JSONObjectリクエスト本文で使用されるを受け入れます。

JSONObject paramJson = new JSONObject();

paramJson.put("key1", "value1");
paramJson.put("key2", "value2");


JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,url,paramJson,
    new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {

        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });
requestQueue.add(jsonObjectRequest);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.