Volley에 대한 Google IO 2013 세션을 보았고 발리로 전환 할 것을 고려하고 있습니다. Volley는 요청에 POST / GET 매개 변수 추가를 지원합니까? 그렇다면 어떻게해야합니까?
답변
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/
답변
GET 매개 변수의 경우 두 가지 대안이 있습니다.
첫째 : 질문 아래의 주석에서 제안했듯이 String을 사용하고 매개 변수 자리 표시자를 다음과 같은 값으로 바꿀 수 있습니다.
String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s¶m2=%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 예제와 함께)를 찾을 수 있습니다 .
답변
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 덕분에
답변
이 도우미 클래스는 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 매개 변수를 다루면서 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를 요청에 설정합니다.
도움이 되었기를 바랍니다.
답변
이것은 당신을 도울 수 있습니다 …
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);
}
답변
미래 독자를 위해
저는 Volley 와 함께 일하는 것을 좋아합니다 . 개발 시간을 절약하기 위해 저는 작은 편리한 라이브러리 Gloxey Netwok Manager 를 작성하여 Volley를 내 프로젝트로 설정하려고했습니다. 여기에는 네트워크 가용성을 확인하는 데 도움이되는 JSON 파서 및 다른 방법이 포함됩니다.
사용 ConnectionManager.class
을위한 다른 방법있는 발리 문자열 과 발리 JSON이 요청을 사용할 수 있습니다. 헤더를 사용하거나 사용하지 않고 GET, PUT, POST, DELETE 를 요청할 수 있습니다 . 여기에서 전체 문서를 읽을 수 있습니다 .
이 줄을 gradle 파일에 넣으십시오.
dependencies {
compile 'io.gloxey.gnm:network-manager:1.0.1'
}
메소드 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
*/
}
});
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 파서를 사용하여 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();
}