简体   繁体   English

从凌空JSON对象POST方法响应中捕获cookie

[英]capture cookie from volley JSON Object POST method response

I am sending a POST request using the volley library on android. 我正在使用Android上的凌空库发送POST请求。 Once I get the json response the server is sending back a cookie in the headers. 一旦收到json响应,服务器就会在标头中发送回cookie。 I can see the cookie when I check the network traffic using the profiler in android studio. 当我使用android studio中的事件探查器检查网络流量时,可以看到Cookie。

I need to be able to get the cookie from the header and assign it to a variable so that I can pass it to the next activity. 我需要能够从标题中获取cookie并将其分配给变量,以便可以将其传递给下一个活动。

I have looked at Using cookies with Android volley library and how to get cookies from volley response 我看过将Cookie与Android Volley库一起使用以及如何从Volley Response中获取Cookie

They are both several years old and I was unable to get them to work. 他们俩都几岁了,我无法让他们工作。 I am not sure if it is because they use a GET request and mine is a POST request. 我不确定是否是因为他们使用GET请求而我的请求是POST请求。

Is there a simple way to get the cookie from the server response? 有没有一种简单的方法可以从服务器响应中获取Cookie?

This is the code that I currently have in place, all is well except for grabbing the cookie. 这是我当前使用的代码,除了抓取cookie之外,一切都很好。

 JsonObjectRequest postRequest = new JsonObjectRequest(Request.Method.POST, cartUrl, jsonParams,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {

                    //Obviously this will not work becuase .getCookie() requires a url as a parameter
                    //There must be a method something like this to capture the response and get the cookie.
                    String chocolateChip = CookieManager.getInstance().getCookie(response);

                    startActivity(postIntent);

                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });

    postRequestQue.add(postRequest);

}

Did you check this answer in the same question? 您是否在同一问题中检查了此答案 It is an accepted answer and shows the implementation required to capture cookies from the response and later send them by adding cookies in subsequent requests. 这是一个可接受的答案,它显示了从响应中捕获cookie并随后通过在后续请求中添加cookie来发送它们所需的实现。

Also, please check the following screenshot. 另外,请检查以下屏幕截图。 I have taken it from this link . 我已经从此链接中获取了它。 饼干

EDITED: I understand the issue. 编辑:我了解这个问题。 Can you please try this answer. 你能试试这个答案吗? The following link explains the usage of cookies for HttpURLConnection https://developer.android.com/reference/java/net/HttpURLConnection#sessions-with-cookies 以下链接说明了HttpURLConnection的cookie用法https://developer.android.com/reference/java/net/HttpURLConnection#sessions-with-cookies

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

You can also try adding the following arguments to CookieManager constructor to accept all cookies: 您也可以尝试向CookieManager构造函数添加以下参数以接受所有cookie:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

Output: (URL: https://www.secureserver.net/api/v1/cart/508688?redirect=false ) 输出:(URL: https : //www.secureserver.net/api/v1/cart/508688?redirect=false

Note: Please try with a privateLabelId as the following output is a result of an HTTP 400 request 注意:请尝试使用privateLabelId,因为以下输出是HTTP 400请求的结果

{
  "error": {
    "statusCode": 400,
    "name": "invalid-product",
    "message": "Bad Request. Invalid {productId} in {items}"
  }
}

Headers

com.example.test E/MainActivity: Name Access-Control-Allow-Credentials Value true
com.example.test E/MainActivity: Name Cache-Control Value max-age=0, no-cache, no-store
com.example.test E/MainActivity: Name Connection Value close
com.example.test E/MainActivity: Name Content-Length Value 109
com.example.test E/MainActivity: Name Content-Type Value application/json; charset=utf-8
com.example.test E/MainActivity: Name Date Value Thu, 21 Feb 2019 06:09:34 GMT
com.example.test E/MainActivity: Name Expires Value Thu, 21 Feb 2019 06:09:34 GMT
com.example.test E/MainActivity: Name P3P Value CP="IDC DSP COR LAW CUR ADM DEV TAI PSA PSD IVA IVD HIS OUR SAM PUB LEG UNI COM NAV STA"
com.example.test E/MainActivity: Name Pragma Value no-cache
com.example.test E/MainActivity: Name Server Value nginx
com.example.test E/MainActivity: Name Vary Value Origin, Accept-Encoding
com.example.test E/MainActivity: Name X-Android-Received-Millis Value 1550729374476
com.example.test E/MainActivity: Name X-Android-Response-Source Value NETWORK 400
com.example.test E/MainActivity: Name X-Android-Selected-Protocol Value http/1.1
com.example.test E/MainActivity: Name X-Android-Sent-Millis Value 1550729373659
com.example.test E/MainActivity: Name X-ARC Value 102
com.example.test E/MainActivity: Name X-Content-Type-Options Value nosniff
com.example.test E/MainActivity: Name X-Download-Options Value noopen
com.example.test E/MainActivity: Name X-Frame-Options Value DENY
com.example.test E/MainActivity: Name X-XSS-Protection Value 1; mode=block

class VolleyJsonRequest VolleyJsonRequest类

import android.util.Log;
import android.support.annotation.Nullable;

import com.android.volley.Header;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

class VolleyJsonRequest {
    private ResponseListener listener;
    private int method;
    private String url;
    private List<Header> headers = new ArrayList<>();
    private JSONObject body;
    private int statusCode;

    private static final String TAG = VolleyJsonRequest.class.getSimpleName();

    public VolleyJsonRequest(int method, String url, JSONObject body, ResponseListener listener) {
        this.listener = listener;
        this.method = method;
        this.url = url;
        this.body = body;

    }

    public Request get() {
        return new Request(method, url, body.toString(), responseListener, errorListener);
    }

    Response.Listener<String> responseListener = new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            deliverResult(response);
        }
    };

    Response.ErrorListener errorListener = new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            statusCode = error.networkResponse.statusCode;
            headers.addAll(error.networkResponse.allHeaders);
            String json;
            try {
                json = new String(
                        error.networkResponse.data,
                        HttpHeaderParser.parseCharset(error.networkResponse.headers));
                deliverResult(json);
            } catch (
                    UnsupportedEncodingException e) {
                Log.e(TAG, Log.getStackTraceString(e));
            }
        }
    };


    private void deliverResult(String response) {
        try {
            Object object = new JSONTokener(response).nextValue();
            if (object instanceof JSONObject) {
                listener.onResponse(statusCode, headers, (JSONObject) object, null);
            } else {
                listener.onResponse(statusCode, headers, null, (JSONArray) object);
            }
        } catch (JSONException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }


    class Request extends JsonRequest {

        public Request(int method, String url, @Nullable String requestBody, Response.Listener listener, @Nullable Response.ErrorListener errorListener) {
            super(method, url, requestBody, listener, errorListener);
        }

        @Override
        protected Response parseNetworkResponse(NetworkResponse response) {
            headers.addAll(response.allHeaders);
            statusCode = response.statusCode;
            String string;
            try {
                string = new String(
                        response.data,
                        HttpHeaderParser.parseCharset(response.headers));
            } catch (
                    UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            }

            return Response.success(
                    string,
                    HttpHeaderParser.parseCacheHeaders(response));

        }
    }

    public interface ResponseListener {
        void onResponse(int statusCode, List<Header> headers, JSONObject object, JSONArray array);
    }

}

Test : 测试

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.android.volley.Header;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.List;

public class MainActivity extends AppCompatActivity implements VolleyJsonRequest.ResponseListener {

    private static final String TAG = MainActivity.class.getSimpleName();
    private RequestQueue queue;

    String requestBody = "{\n" +
            "  \"items\": [\n" +
            "    {\n" +
            "      \"id\": \"string\",\n" +
            "      \"domain\": \"string\"\n" +
            "    }\n" +
            "  ],\n" +
            "  \"skipCrossSell\": true\n" +
            "}";
    String url = "https://www.secureserver.net/api/v1/cart/508688?redirect=false";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        queue = Volley.newRequestQueue(this);
        testOne();
        testTwo();
    }

    private void testOne(){
        JsonRequest request = new JsonRequest(Request.Method.POST, url, requestBody, new Response.Listener() {
            @Override
            public void onResponse(Object response) {
                Log.e(TAG,"Response " + response.toString());
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

                try {
                    String response = new String(
                            error.networkResponse.data,
                            HttpHeaderParser.parseCharset(error.networkResponse.headers));

                    Log.e(TAG,error.networkResponse.allHeaders.toString());
                    Log.e(TAG,response);

                } catch (UnsupportedEncodingException e) {
                    Log.e(TAG,e.getMessage());
                }
            }
        }) {
            @Override
            protected Response parseNetworkResponse(NetworkResponse response) {
                try {


                    List<Header> headers = response.allHeaders;
                    for(Header header: headers){
                        Log.e(TAG,"Name " + header.getName() + " Value " + header.getValue());
                    }

                    String json = new String(
                            response.data,
                            HttpHeaderParser.parseCharset(response.headers));
                    return Response.success(
                            new JSONObject(json),
                            HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException e) {
                    return Response.error(new ParseError(e));
                } catch (JSONException e) {
                    return Response.error(new ParseError(e));
                }
            }
        };

        queue.add(request);
    }

    private  void testTwo(){

        VolleyJsonRequest jsonRequest = null;
        try {
            jsonRequest = new VolleyJsonRequest(Request.Method.POST,url, new JSONObject(requestBody),this);
            queue.add(jsonRequest.get());
        } catch (JSONException e) {
            e.printStackTrace();
        }


    }

    @Override
    public void onResponse(int statusCode, List<Header> headers, JSONObject object, JSONArray array) {


        Log.e(TAG,"-------------------------------");

        for(Header header: headers){
            Log.e(TAG,"Name " + header.getName() + " Value " + header.getValue());
        }


        if (object != null){
            // handle your json object
        }else if (array != null){
            // handle your json array
        }
    }
}

I tried two ways ie testOne and testTwo. 我尝试了两种方法,即testOne和testTwo。 both are working fine. 两者都工作正常。 testOne is pretty straight forward for testTwo i've created a VolleyJsonRequest class. testOne对于testTwo非常简单,我创建了VolleyJsonRequest类。 You don't need this class if you are using the testOne method. 如果使用testOne方法,则不需要此类。 this class is created just for the comfort/ease to use a common class structure in your project. 创建此类仅是为了使您轻松/轻松地在项目中使用通用的类结构。 This class encapsulate actual request and provides a custom interface via which you get the response. 此类封装了实际的请求,并提供了一个自定义接口,您可以通过该接口获得响应。 it has two special variables ie object and array. 它有两个特殊变量,即对象和数组。 one of these will be null in case of a valid json response. 如果有效的json响应,则其中之一将为null。 which variable will be null depends upon the response sent by Server. 哪个变量为空取决于服务器发送的响应。

Try this - 尝试这个 -

            @Override
            public String getBodyContentType() {
                return "application/json";
            }

            @Override
                protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
                    // since we don't know which of the two underlying network vehicles
                    // will Volley use, we have to handle and store session cookies manually
                    Log.i("response",response.headers.toString());
                    Map<String, String> responseHeaders = response.headers;
                    String rawCookies = responseHeaders.get("Set-Cookie");
                    Log.i("cookies",rawCookies);
                    prefLogin.setSessionId(rawCookies); // save your cookies using shared prefernece
                    return super.parseNetworkResponse(response);
                }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM