Захватить cookie из ответного метода POST объекта JSON Object

Я отправляю запрос POST, используя библиотеку volley на Android. Как только я получаю ответ json, сервер отправляет файл cookie в заголовках. Я вижу файл cookie, когда проверяю сетевой трафик с помощью профилировщика в студии Android.

Мне нужно иметь возможность получить файл cookie из заголовка и назначить его переменной, чтобы я мог передать его следующему действию.

Я посмотрел на Использование файлов cookie с библиотекой Android volley и как получить куки от volley response

Им обоим несколько лет, и я не смог заставить их работать. Я не уверен, что это потому, что они используют запрос GET, а мой запрос POST.

Есть ли простой способ получить 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);

}

Пожалуйста, поделитесь версией API и ОС Android, которые вы используете

Imran 19.02.2019 15:25

@codeKracken Я отправил свой ответ. пожалуйста, проверьте

Sahil 21.02.2019 07:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
1 017
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы проверили этот ответ в том же вопросе? Это принятый ответ, который показывает реализацию, необходимую для захвата файлов cookie из ответа и последующей отправки их путем добавления файлов cookie в последующие запросы.

Кроме того, проверьте следующий снимок экрана. Я взял его из эта ссылка. Cookies

ОТРЕДАКТИРОВАНО: Я понимаю проблему. Можете ли вы попробовать этот ответ. Следующая ссылка объясняет использование файлов cookie для HttpURLConnectionhttps://developer.android.com/reference/java/net/HttpURLConnection#sessions-with-cookies

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

Вы также можете попробовать добавить следующие аргументы в конструктор CookieManager, чтобы принять все файлы cookie:

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

Я ценю, что вы изучаете это, однако ни один из этих методов не работает. AbstractHttpClient — это класс, которого у меня нет или я не знаю, как его получить, а HttpClientStack устарел. Большинству ответов, которые я могу найти, несколько лет, начиная с 2013 года или иногда старше. Никак не могу найти актуальную информацию.

codeKracken 17.02.2019 17:22

Привет, @codeKracken, я обновил свой ответ. Пожалуйста, дайте мне знать, если это поможет.

Mohit Ajwani 18.02.2019 11:19

@ Мохит Аджвани Я ценю вашу помощь, однако они вообще не работают. Кажется, это близко String rawCookies = responseHeaders.get("Set-Cookie"); Но по какой-то причине не фиксирует правильный файл cookie.

codeKracken 20.02.2019 18:25

Попробуй это -

            @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);
                }

Спасибо, это приближается, но возвращает I/cookies: currency=USD; Домен=secureserver.net; Путь=/; Expires=Wed, 19 Feb 2020 00:24:38 GMT и не возвращает полный файл cookie, самое главное, я пытаюсь захватить файл cookie ShopperId508688=somerandomestringgoeshere;

codeKracken 19.02.2019 01:27

Спасибо за предложение, но rawCookies возвращается без фактического файла cookie из заголовка.

codeKracken 20.02.2019 18:23
Ответ принят как подходящий

Выход: (URL: https://www.secureserver.net/api/v1/cart/508688?redirect=false)

Примечание. Попробуйте использовать privateLabelId, так как следующий вывод является результатом запроса HTTP 400.

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

Заголовки

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

класс 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);
    }

}

Контрольная работа:

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
        }
    }
}

Я пробовал два способа, т.е. testOne и testTwo. оба работают нормально. testOne довольно прост для testTwo, я создал Класс VolleyJsonRequest. Вам не нужен этот класс, если вы используете метод testOne. этот класс создан только для удобства/простоты использования общей структуры класса в вашем проекте. Этот класс инкапсулирует фактический запрос и предоставляет настраиваемый интерфейс, через который вы получаете ответ. он имеет две специальные переменные, т. е. объект и массив. один из них будет нулевым в случае действительного ответа json. какая переменная будет нулевой, зависит от ответа, отправленного сервером.

Вы босс! Наконец, после нескольких недель экспериментов и поиска, это, наконец, работает.

codeKracken 21.02.2019 23:30

У меня есть еще один вопрос, если у вас есть простое решение. Я пытаюсь получить имя Set-Cookie, которое начинается с ShopperID. Прямо сейчас я использую String ChocolateChip = string.valueOf(headers.get(11));String trimedCookie = ChocolateChip.substring(29, ChocolateChip.length()-1); Кажется, должен быть более простой метод.

codeKracken 21.02.2019 23:31

Кстати, я использовал ваш метод testone(). Еще раз спасибо, я очень ценю помощь, которую вы оказали.

codeKracken 21.02.2019 23:32

@codeKracken, посмотрите, поможет ли это String s = headers.get(11).getValue().split("textyouwanttoskip")[1];

Sahil 22.02.2019 05:15

Спасибо, это очень полезно. Я очень благодарен за всю помощь, которую вы оказали.

codeKracken 22.02.2019 20:27

Другие вопросы по теме