【问题标题】:how to execute PUT request in Android Volley?如何在 Android Volley 中执行 PUT 请求?
【发布时间】:2013-08-02 23:05:02
【问题描述】:

我目前正在使用 GsonRequest 来发出 rest GET 请求。不清楚在我需要发送整个 JSon 对象以进行更新的地方使用什么 PUT 请求。 Request 对象将接受 PUT,但我不确定如何放置预期的 JSon 对象。

这是我要 PUT 的 json:

 {
   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();
     }

 }

【问题讨论】:

    标签: android android-volley


    【解决方案1】:

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

    我不确定GsonRequest 的来源,但如果它没有采用Method 的构造函数,您可以自己添加一个。

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

    【讨论】:

    • 我已经用 GsonRequest 更新了我的问题。我不知道在这个请求中把 JSON 字符串放在哪里。
    • 好像不支持提交数据。您需要覆盖 getBody 和 getBodyContentType 以返回序列化对象和正确的 MIME 类型(例如,application/json)
    • 我已经发布了如何在 javascript apiary.io 中调用 put
    • 请用 getBody()、getBodyContentType() 的建议更新您的主要答案。
    • 感谢@Delyan - 覆盖getBodyContentType() 方法是我修复的原因。在看到之前,我花了太多时间试图解决这个问题。我同意应该更新答案以包含它。
    【解决方案2】:

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

    我必须在 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();
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 2012-11-26
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      相关资源
      最近更新 更多