如何在Android Volley中执行PUT请求?

时间:2013-08-02 23:05:03

标签: android android-volley

我目前正在使用GsonRequest发出其余的GET请求。不清楚PUT请求的用途,我需要通过整个JSon对象发送更新。 Request对象将接受PUT,但我不确定如何放置预期的JSon对象。

这是我的json PUT:

 {
   prop1 : true,
   prop2 : false,
   prop4 : true
 }

以下是它在apiary.io中的提交方式,例如:

  var xhr = new XMLHttpRequest();
  xhr.open('PUT', 'http://my.apiary.io/v1/records/{myid}.json');

    xhr.send("{\n    \"isEditable\": false,\n    \"isClosed\": true,\n        \"isAvail\": true\n}");

我不知道把JSON放到哪里。

由于

public class GsonRequest<T> extends Request<T> {

private final Gson gson ;
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;

public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers,
        Listener<T> listener, ErrorListener errorListener) {
    super(method, url, errorListener);

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Timestamp.class, new TimestampDeserializer());
    this.gson = gsonBuilder.create();
    this.clazz = clazz;
    this.headers = headers;
    this.listener = listener;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    return headers != null ? headers : super.getHeaders();
}

@Override
protected void deliverResponse(T response) {
    listener.onResponse(response);
}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
        String json = new String(
                response.data, HttpHeaderParser.parseCharset(response.headers));
        return Response.success(
                gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JsonSyntaxException e) {
        return Response.error(new ParseError(e));
    }
   }
}

以下是请求中的基本getBody方法。它似乎处理Method.PUT上的参数,但如果它的JSON字符串需要在正文中发送呢?

/**
 * Returns the raw POST or PUT body to be sent.
 *
 * @throws AuthFailureError in the event of auth failure
 */
public byte[] getBody() throws AuthFailureError {
    Map<String, String> params = getParams();
    if (params != null && params.size() > 0) {
        return encodeParameters(params, getParamsEncoding());
    }
    return null;
}

/**
 * Converts <code>params</code> into an application/x-www-form-urlencoded encoded string.
 */
private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
    StringBuilder encodedParams = new StringBuilder();
    try {
        for (Map.Entry<String, String> entry : params.entrySet()) {
            encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
            encodedParams.append('=');
            encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
            encodedParams.append('&');
        }
        return encodedParams.toString().getBytes(paramsEncoding);
    } catch (UnsupportedEncodingException uee) {
        throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
    }
}

建议的解决方案:

     // add a Json body.
    public String jsonBody;  

  /**
   * Returns the raw POST or PUT body to be sent.
   *
   * @throws AuthFailureError in the event of auth failure
   */



   public byte[] getBody() throws AuthFailureError {

     if ((getMethod() == Method.PUT) && (jsonBody != null))
     {
        return jsonBody.getBytes();  // Encoding required?????

     }
     else
     {
       return super.getBody();
     }

 }

2 个答案:

答案 0 :(得分:5)

抽象基类Request有一个构造函数,它将Request.Method作为第一个参数。 volley.toolbox中的所有Request实现也都有类似的构造函数。

我不确定GsonRequest来自哪里,但如果它没有带Method的构造函数,你可以自己添加一个。

编辑:您可以覆盖getBodygetBodyContentType以分别返回自定义请求正文和MIME类型。

答案 1 :(得分:0)

我知道这是一个相当古老的话题,但我不得不调整建议的解决方案以使其对我有用,所以我虽然同样的方法可以适用于其他人:

我不得不向 getHeaders 函数添加一些标题:

        /**
         * Passing some request headers
         * */
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json");
            headers.put("Accept", "*/*");
            return headers;
        }

然后我就可以将建议的解决方案与 getBody() 一起使用

@Override
        /**
         * Returns the raw POST or PUT body to be sent.
         *
         * @throws AuthFailureError in the event of auth failure
         */
        public byte[] getBody() throws AuthFailureError {
            String jsonBody = "{\"status\":\"true"}";

            if ((getMethod() == Method.PUT) && (jsonBody != null)){
                return jsonBody.getBytes();
            }else{
                return super.getBody();
            }
        }