[android] Volley를 사용하여 JSON 데이터로 POST 요청 보내기
새 JsonObjectRequest
요청 을 보내고 싶습니다 .
- JSON 데이터를 받고 싶습니다 (서버에서 응답) : OK
-
이 요청과 함께 JSON 형식의 데이터를 서버에 보내고 싶습니다.
JsonObjectRequest request = new JsonObjectRequest( Request.Method.POST, "myurl.com", null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { //... } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //... } }) { @Override protected Map<String,String> getParams() { // something to do here ?? return params; } @Override public Map<String, String> getHeaders() throws AuthFailureError { // something to do here ?? return params; } };
추신 나는 내 프로젝트에서도 GSON 라이브러리를 사용합니다.
답변
JsonObjectRequest
실제로 JSONObject
몸으로 받아 들입니다.
에서 이 블로그 글 ,
final String url = "some/url";
final JSONObject jsonBody = new JSONObject("{\"type\":\"example\"}");
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
다음은 소스 코드와 JavaDoc ( @param jsonRequest
)입니다.
/**
* Creates a new request.
* @param method the HTTP method to use
* @param url URL to fetch the JSON from
* @param jsonRequest A {@link JSONObject} to post with the request. Null is allowed and
* indicates no parameters will be posted along with request.
* @param listener Listener to receive the JSON response
* @param errorListener Error listener, or null to ignore errors.
*/
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
답변
이 스레드가 꽤 오래되었다는 것을 알고 있지만,이 문제가 있었고 많은 측면에서 Volley 라이브러리를 수정 / 확장했기 때문에 많은 사람들에게 매우 유용 할 수있는 멋진 솔루션을 찾았습니다.
지원되지 않는 일부 Volley 기능을 발견했습니다.
- 이것은
JSONObjectRequest
완벽하지 않습니다.JSON
마지막에 a를 예상해야합니다 (참조Response.Listener<JSONObject>
). - 빈 응답 (상태가 200 인 경우)은 어떻습니까?
- 에서 POJO를 직접 원하면 어떻게해야
ResponseListener
합니까?
나는 내가 인용 한 모든 문제에 대한 해결책을 갖기 위해 큰 일반 클래스에서 많은 솔루션을 어느 정도 컴파일했습니다.
/**
* Created by laurentmeyer on 25/07/15.
*/
public class GenericRequest<T> extends JsonRequest<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
// Used for request which do not return anything from the server
private boolean muteRequest = false;
/**
* Basically, this is the constructor which is called by the others.
* It allows you to send an object of type A to the server and expect a JSON representing a object of type B.
* The problem with the #JsonObjectRequest is that you expect a JSON at the end.
* We can do better than that, we can directly receive our POJO.
* That's what this class does.
*
* @param method: HTTP Method
* @param classtype: Classtype to parse the JSON coming from the server
* @param url: url to be called
* @param requestBody: The body being sent
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
* @param headers: Added headers
*/
private GenericRequest(int method, Class<T> classtype, String url, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
super(method, url, requestBody, listener,
errorListener);
clazz = classtype;
this.headers = headers;
configureRequest();
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and not muted)
*
* @param method: HTTP Method
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
* @param headers: Added headers
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (without header and not muted)
*
* @param method: HTTP Method
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
}
/**
* Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
*
* @param method: HTTP Method
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param requestBody: String to be sent to the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
*/
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
}
/**
* Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (Without header)
*
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
*/
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(Request.Method.GET, url, classtype, "", listener, errorListener);
}
/**
* Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (With headers)
*
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
* @param headers: Added headers
*/
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(Request.Method.GET, classtype, url, "", listener, errorListener, headers);
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and muted)
*
* @param method: HTTP Method
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
* @param headers: Added headers
* @param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
this.muteRequest = mute;
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (without header and muted)
*
* @param method: HTTP Method
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
* @param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
/**
* Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
*
* @param method: HTTP Method
* @param url: URL to be called
* @param classtype: Classtype to parse the JSON returned from the server
* @param requestBody: String to be sent to the server
* @param listener: Listener of the request
* @param errorListener: Error handler of the request
* @param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
// The magic of the mute request happens here
if (muteRequest) {
if (response.statusCode >= 200 && response.statusCode <= 299) {
// If the status is correct, we return a success but with a null object, because the server didn't return anything
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
}
} else {
try {
// If it's not muted; we just need to create our POJO from the returned JSON and handle correctly the errors
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
T parsedObject = gson.fromJson(json, clazz);
return Response.success(parsedObject, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
return null;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
private void configureRequest() {
// Set retry policy
// Add headers, for auth for example
// ...
}
}
약간 과한 것처럼 보일 수 있지만 모든 경우가 있으므로 이러한 모든 생성자를 갖는 것은 매우 멋지다.
(물론 가능하지만 주 생성자는 직접 사용하도록 의도되지 않았습니다).
- POJO로 구문 분석 된 응답이있는 요청 / 수동으로 설정된 헤더 / 보낼 POJO
- POJO / POJO로 파싱 된 응답이있는 요청
- POJO로 구문 분석 된 응답이있는 요청 / 보낼 문자열
- POJO (GET)로 구문 분석 된 응답이있는 요청
- POJO (GET)로 구문 분석 된 응답이있는 요청 / 수동으로 설정된 헤더
- 응답이없는 요청 (200-빈 본문) / 수동으로 설정된 헤더 / 전송할 POJO
- 응답이없는 요청 (200-빈 본문) / 보낼 POJO
- 응답이없는 요청 (200-빈 본문) / 보낼 문자열
물론 작동하려면 Google의 GSON Lib이 있어야합니다. 다음을 추가하십시오.
compile 'com.google.code.gson:gson:x.y.z'
종속성 (현재 버전은입니다 2.3.1
).
답변
final String URL = "/volley/resource/12";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
답변
-
RequestQueue
클래스 의 객체를 만듭니다 .RequestQueue queue = Volley.newRequestQueue(this);
-
StringRequest
응답 및 오류 리스너를 생성합니다 .StringRequest sr = new StringRequest(Request.Method.POST,"http://api.someservice.com/post/comment", new Response.Listener<String>() { @Override public void onResponse(String response) { mPostCommentResponse.requestCompleted(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mPostCommentResponse.requestEndedWithError(error); } }){ @Override protected Map<String,String> getParams(){ Map<String,String> params = new HashMap<String, String>(); params.put("user",userAccount.getUsername()); params.put("pass",userAccount.getPassword()); params.put("comment", Uri.encode(comment)); params.put("comment_post_ID",String.valueOf(postId)); params.put("blogId",String.valueOf(blogId)); return params; } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String,String> params = new HashMap<String, String>(); params.put("Content-Type","application/x-www-form-urlencoded"); return params; } };
-
요청을
RequestQueue
.queue.add(jsObjRequest);
-
PostCommentResponseListener
당신이 그것을 볼 수 있도록 인터페이스를 만듭니다 . 비동기 요청을위한 간단한 대리자입니다.public interface PostCommentResponseListener { public void requestStarted(); public void requestCompleted(); public void requestEndedWithError(VolleyError error); }
-
AndroidManifest.xml
파일 내에 인터넷 권한을 포함 합니다.<uses-permission android:name="android.permission.INTERNET"/>
답변
final String url = "some/url";
대신에:
final JSONObject jsonBody = "{\"type\":\"example\"}";
당신이 사용할 수있는:
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("type", "my type");
} catch (JSONException e) {
e.printStackTrace();
}
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
답변
final Map<String,String> params = new HashMap<String,String>();
params.put("email", customer.getEmail());
params.put("password", customer.getPassword());
String url = Constants.BASE_URL+"login";
doWebRequestPost(url, params);
public void doWebRequestPost(String url, final Map<String,String> json){
getmDialogListener().showDialog();
StringRequest post = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
getmDialogListener().dismissDialog();
response....
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(App.TAG,error.toString());
getmDialogListener().dismissDialog();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = json;
return map;
}
};
App.getInstance().getRequestQueue().add(post);
}
답변
클래스의 getBody()
메서드를 재정 의하여 데이터를 보낼 수도 있습니다 JsonObjectRequest
. 아래 그림과 같이.
@Override
public byte[] getBody()
{
JSONObject jsonObject = new JSONObject();
String body = null;
try
{
jsonObject.put("username", "user123");
jsonObject.put("password", "Pass123");
body = jsonObject.toString();
} catch (JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
return body.toString().getBytes("utf-8");
} catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}