删除带有标头和参数的请求 Volley

Posted

技术标签:

【中文标题】删除带有标头和参数的请求 Volley【英文标题】:Delete Request With header and Parametes Volley 【发布时间】:2016-02-06 19:39:19 【问题描述】:

您好,我想通过标头和正文参数使用 Volley 向服务器发送删除请求。但我无法成功发送请求

我的尝试

JSONObject jsonbObjj = new JSONObject();
try 
    jsonbObjj.put("nombre", Integer.parseInt(no_of_addition
            .getText().toString()));
    jsonbObjj.put("cru", crue);
    jsonbObjj.put("annee", 2010);
 catch (JSONException e) 
    // TODO Auto-generated catch block
    e.printStackTrace();

VolleyRequest mVolleyRequest = new VolleyRequest(
        Method.DELETE, url, jsonbObjj,

        new Listener<JSONObject>() 

            @Override
            public void onResponse(JSONObject jsonObject) 
                // TODO Auto-generated method stub

                if (pDialog != null) 
                    pDialog.dismiss();
                
                Log.e("Server Response", "response = "
                        + jsonObject.toString());
            

        , new ErrorListener() 

            @Override
            public void onErrorResponse(VolleyError arg0) 
                // TODO Auto-generated method stub
                if (pDialog != null) 
                    pDialog.dismiss();
                
                Log.e("Error Response",
                        "Error " + arg0.getMessage());
                Log.e("Error Response",
                        "Error = " + arg0.getCause());

            
        , mUserSession.getUserEmail(), mUserSession
                .getUserPassword(), false);

ApplicationController.getInstance().addToRequestQueue(
        mVolleyRequest, "deleteRequest");

这是我的 VolleyRequest 请求类

public class VolleyRequest extends JsonObjectRequest 

    String email, pass;
    boolean saveCookeis;

    public VolleyRequest(int method, String url, JSONObject jsonRequest,
            Listener<JSONObject> listener, ErrorListener errorListener,
            String email, String pass, boolean saveCookie) 
        super(method, url, jsonRequest, listener, errorListener);
        // TODO Auto-generated constructor stub
        this.email = email;
        this.pass = pass;
        this.saveCookeis = saveCookie;
    

    public VolleyRequest(int method, String url, JSONObject jsonRequest,
            Listener<JSONObject> listener, ErrorListener errorListener) 
        super(Method.POST, url, jsonRequest, listener, errorListener);
        // TODO Auto-generated constructor stub

    

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError 
        // TODO Auto-generated method stub
            HashMap<String, String> params = new HashMap<String, String>();

            String auth = "";
            try 
                auth = android.util.Base64.encodeToString(
                        (this.email + ":" + this.pass).getBytes("UTF-8"),
                        android.util.Base64.DEFAULT);
             catch (UnsupportedEncodingException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

            params.put("Authorization", auth);
            return params;
    

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) 
        // TODO Auto-generated method stub

        if (saveCookeis) 
            try 
                String jsonString = new String(response.data,
                        HttpHeaderParser.parseCharset(response.headers));

                ApplicationController.getInstance().checkSessionCookie(
                        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));
            
        
        return super.parseNetworkResponse(response);

    


当我尝试此代码时,我收到 400 响应代码错误如果有人可以帮助我,请告诉我.. 我做错了什么。谢谢

这里是我测试的 Delete Api 的屏幕截图,它工作正常。

【问题讨论】:

嗨!由于我没有工作凭据(用户,通过),所以我通过您的服务器 url 得到的响应代码是 500,而不是 400 :) 我觉得你可以试试params.put("Authorization", "Basic " + auth); 它不适用于参数。我在从应用程序发送请求时得到 400,但是当我从浏览器点击 URL 时它运行良好。我的用户名在图像中指定并且传递是 1234 如果你可以检查请检查它并告诉我我做错了什么。谢谢 我认为你的代码没有错。它不起作用只是因为在 DELETE 请求中忽略了正文。您可以在 HurlStack.java case Method.DELETE: connection.setRequestMethod("DELETE"); break; case Method.POST: connection.setRequestMethod("POST"); addBodyIfExists(connection, request); break; 中找到。在这里阅读一些解决方案***.com/questions/19050706/… 好的,让我检查一下,然后我会告诉你的。无论如何谢谢 【参考方案1】:

更新:

我已将我的工作示例项目发布到GitHub 以修复java.net.ProtocolException: DELETE does not support writing,请查看。


您的应用收到400 错误代码,因为数据正文尚未通过DELETE 请求发送。

在HurlStack.java 中,您会发现以下内容:

            case Method.DELETE:
                connection.setRequestMethod("DELETE");
                break;
            case Method.POST:
                connection.setRequestMethod("POST");
                addBodyIfExists(connection, request);
                break;

所以我们可以看到DELETE 请求忽略了正文数据。有一个解决方法,就是你创建一个CustomHurlStack类(复制上面HurlStack的所有内容),只做如下修改:

            case Request.Method.DELETE:
                connection.setRequestMethod("DELETE");
                addBodyIfExists(connection, request);
                break;

然后,在你的活动中,调用:

CustomHurlStack customHurlStack = new CustomHurlStack();
RequestQueue queue = Volley.newRequestQueue(this, customHurlStack);

请注意,此解决方法仅适用于 API21+(API20 我尚未测试)。从 API19-,java.net.ProtocolException: DELETE does not support writing 将被抛出。

P/S:如果您的应用程序 compileSdkVersion 23 并且在创建 CustomHurlStack 类时出现错误,请在您的 build.gradle 文件中添加 useLibrary 'org.apache.http.legacy'

希望这会有所帮助!

【讨论】:

你能告诉我如何创建像这里***.com/a/30748487/3593066http://***.com/a/… 这样的 newRequestQueue 方法。我有点困惑,请解释一下,因为我收到这个错误 java.net.ProtocolException: DELETE does not support writing 如果您可以控制服务器端应用程序(Web 服务),我建议您进行更改,以便 DELETE 请求使用 URL 参数而不是正文参数 我将新的示例项目上传到github.com/ngocchung/DeleteRequest,请看一下。但是,因为上次成功运行得到了响应I/onResponse: "reste":0,所以后面的其他请求将得到response code 400,因为没有要删除的项目:)。实际上,他们会得到 "error": "bad request", "message": "suppression impossible : pas assez de bouteilles correspondantes en cave" 感谢它完美的工作。并再次感谢您的时间。 (y) 感谢兄弟的考虑。我已经解决了。实际上我用 UTF-8 解析网络响应并且它工作。谢谢【参考方案2】:
url = "http://httpbin.org/delete"; //example URL


//constructor class
public VolleyLoader(Context context) 
        this.context = context;
        queue = Volley.newRequestQueue(context);



public void deleteData(String idData, callback callback)
  Uri uri = Uri.parse(URL+ idData).buildUpon()
                .build();

StringRequest dr = new StringRequest(Request.Method.DELETE, uri.toString, 
    new Response.Listener<String>() 
    
        @Override
        public void onResponse(String response) 
            // response
            Toast.makeText($this, response, Toast.LENGTH_LONG).show();
        
    , 
    new Response.ErrorListener() 
    
         @Override
         public void onErrorResponse(VolleyError error) 
             // error.
              
       
    
);
queue.add(dr);    



// use that method to delete data when web api only provide "id_data" to delete in header  

【讨论】:

使用接口类来帮助传输.....示例:

以上是关于删除带有标头和参数的请求 Volley的主要内容,如果未能解决你的问题,请参考以下文章

如何通过带有标头的 volley 发布 JSON 请求?

Volley JsonObjectRequest Post 请求忽略参数

在 Volley 请求中添加 JWT 令牌

在 json 对象参数 Volley post 中发送令牌头

如何发送带有标头参数的 HTTP 请求?

带有参数的 Volley jsonObjectRequest 不起作用