Volley-POST / GET 매개 변수


81

Volley에 대한 Google IO 2013 세션을 보았고 발리로 전환 할 것을 고려하고 있습니다. Volley는 요청에 POST / GET 매개 변수 추가를 지원합니까? 그렇다면 어떻게해야합니까?


2
나는 전체 기조를 보지 못했지만, 난 꽤 확실히 GET은 URL에 매개 변수를 추가하여 행할 수 있어야한다 (예. http://example.com?param1=val1&param2=val2)
JJJollyjim

아직 문서가없는 것 같지만 여기에서 소스를 확인할 수 있습니다
.

@ JJ56-맞습니다.하지만 POST 매개 변수는 어떻습니까? 소스 코드를 보았지만 POST 매개 변수와 관련된 것을 찾지 못했습니다.
Ziem

1
나는 이것을 말하는 것이 부끄럽다. 그러나 요청이 서버에 본문이없는 이유를 묻는 경우 POST / PUT 메서드를 사용하고 있는지 확인하십시오. 그냥 피곤한 것 같아요. 희망이 댓글은 누군가를 도와 주거나 나를 기분 좋게하는 데 도움이
의 Alwin 케슬러

답변:


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/


70
는 것을 알 getParams만하는 POST 나 PUT 요청에서 (기본적으로)라고 하지만 GET 요청한다. Ogre_BGR의 답변보기
Itai Hanski 2013-08-29

2
믿을 수 없어 지금까지 알아 차리지 못했습니다
Afzal N

@AfzalivE, 위 코드를 사용할 때 OAuth로 API 요청에 서명하는 방법에 대한 아이디어가 있습니까?
Bipin Vayalu 2013 년

2
당신이 구글 API에 연결하는 경우 @BipinVayalu 당신은 com.android.volley.AndroidAuthenticator 사용할 수 있어야합니다
피에르 앙투안

mParams를 인스턴스화하는 것을 잊었습니다.
Moritz

84

GET 매개 변수의 경우 두 가지 대안이 있습니다.

첫째 : 질문 아래의 주석에서 제안했듯이 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는 값을 포함하는 문자열 변수입니다.

두 번째 : 최신 외부 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 예제와 함께)를 찾을 수 있습니다 .


나는 Volley의 예를 따랐습니다. 지금까지는 가장 유용한 Volly 코드이지만 JsonObjectRequest에 문제가 있습니다. 다시 설치할 때까지 createMyReqSuccessListener에서 이전 응답을 받았습니다. 발리는 데이터를 캐시에 저장합니까? 이를 수행하는 방법을 제안하십시오.
SkyWalker 2014 년

2
이미지 만 캐시됩니다. 요청을 가로채는 프록시가 있는지 확인하십시오. 요청에 정확히 동일한 URL이 있고 프록시가 단순히 첫 번째 결과를 반환하는 것일 수 있습니다.
Ognyan 2014 년

2
웹 서버에 다시 요청을 보낼 수있는 "HTTP 리소스 테스트"라는 Firefox 용 플러그인이 있습니다. 이와 같은 경우를 테스트하는 데 매우 유용합니다. URL (및 POST 매개 변수가있는 경우)을 입력하고 여러 연속 요청에 대한 서버의 응답을 확인하십시오. 다시 동일한 응답 결과를 얻으면 대부분 캐시됩니다. 이 경우 반환 된 헤더를 검사하여 프록시 헤더가 있는지 확인할 수 있습니다. "no-cache"에 대해-네, 작동합니다.
Ognyan 2014 년

2
다른 사람들이 참여하고 도움을 줄 수 있도록 별도의 질문을 여는 것이 좋습니다. HURL 또는 HttpClient를 사용하고있는 스택이 무엇인지, 테스트 대상인 Android 버전도 알려주세요. 사람들이 토론을 따를 수 있도록 여기에 새 질문에 대한 링크를 넣으십시오.
Ognyan 2014.01.17

3
@Yousif 아마도 이것을 새로운 질문으로 물으면 훨씬 더 나은 답변을 얻을 수 있지만 간단히 말해서 POST 요청을 사용하면 GET 요청에 맞지 않는 파일 및 기타 더 큰 데이터를 보낼 수 있습니다. 또한 URL 서버에 기록되어 민감한 데이터가 노출 수 있기 때문에 GET 요청을 사용할 때 보안 위험이 있습니다 .
Ognyan 2015

23

CustomRequest는 Volley의 JSONObjectRequest가 다음과 같은 매개 변수를 게시 할 수없는 문제를 해결하는 방법입니다. StringRequest

다음은 매개 변수를 추가 할 수있는 도우미 클래스입니다.

    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

3
감사합니다.이 솔루션을 얻기 전에 몇 시간 동안 검색 getParams()했습니다. JSONObjectReuqest 함수 재정의가 작동하지 않는 것이 너무 이상합니다 .
Walid Ammar 2014

@MohammadWalid 참고로이 stackoverflow.com/questions/16902716/…을 읽고 개조를 사용해보십시오! 발리와 개장 모두 okhttp와 함께 사용할 수 있습니다!
LOG_TAG

이 솔루션을 시도했지만 저에게 효과적이지 않았습니다. getParams ()가 호출되지 않습니다.
Mahdi

10

이 도우미 클래스는 GETPOST 요청에 대한 매개 변수를 관리 합니다.

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

2
우리의 경우 반복자 접근 방식은 함수에 전달한 원래 Map 매개 변수 객체를 파괴했습니다. Volley가 내부적으로 GetUrl여러 번 전화를 거는 것 같습니다 . 우리는 별도의 답변에 게시 된 고전적인 foreach 접근 방식으로 끝났습니다. 이것이 누가 여기에 착륙하는 데 도움이되기를 바랍니다. :)
Paolo Casciello

3 개의 매개 변수가있는 get 요청을 위해이 도우미 클래스를 호출하는 방법
kgandroid

@kgandroid, 키와 값으로 Map <String, String>을 만듭니다. 예 : Map <String, String> params = new HashMap <String, String> (); params.put ( "param1", "value1"); params.put ( "param2", "value2"); params.put ( "param3", "value3");
Andrea Motto

6

GET 매개 변수를 다루면서 Andrea Motto의 솔루션을 반복했습니다. 문제는 Volley가 GetUrl여러 번 호출 했고 그의 솔루션은 Iterator를 사용하여 원래 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 Netwok Manager 를 작성하여 Volley를 내 프로젝트로 설정하려고했습니다. 여기에는 네트워크 가용성을 확인하는 데 도움이되는 JSON 파서 및 다른 방법이 포함됩니다.

사용 ConnectionManager.class을위한 다른 방법있는 발리 문자열발리 JSON이 요청을 사용할 수 있습니다. 헤더를 사용하거나 사용하지 않고 GET, PUT, POST, DELETE 를 요청할 수 있습니다 . 여기에서 전체 문서를 읽을 수 있습니다 .

이 줄을 gradle 파일에 넣으십시오.

  dependencies { 

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

Volley 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
         */
    }
});

Volley 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
         */
    }
});

보너스

Gloxey JSON 파서

gloxey json 파서를 사용하여 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을 지원합니까
David Kariuki

예, 그렇습니다. 자세한 내용을 확인하십시오. github.com/adnanbinmustafa/Gloxey-Network-Manager
Adnan Bin Mustafa

0

POST매개 변수 를 제공하려면 매개 변수를 생성자 JSONObject 에 전송하십시오 JsonObjectRequest. 세 번째 매개 변수는 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.