1

How to send requset after another one use OkHTTP3 ? I have to to this: 1) I send request1 using method OkHTTPRequest , to server 2)Server send response with COOKIE for request1 3) I save this cookies 4) i send request2 with saved cookies.

I have a problem on step 4. It seems that request2 send just after request1 , before request1 saved his cookies. How to resolve it? I want send reuest2 just after request save his own cookie.

  @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);

        try
        {
            // Получаем cookie и авторизируемся
            Log.d("TAG", "Вызываем  OkHTTPRequest1");
            OkHTTPRequest(postUrl, "POST", postData1);
            Log.d("TAG", "Вызываем  OkHTTPRequest2");
            OkHTTPRequest(postUrl2, "PUT", postData2);

            int a;
        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (JSONException e)
        {
            e.printStackTrace();
        }

    }

    // Сохраняем cookieFromServer
    public void saveCookie(List<Cookie> cookies)
    {
        for (int i = 0; i < cookies.size(); i++)
        {
            String str = cookies.get(i).toString();
            if (str.indexOf("issa7=") != -1)
            {
                cookieFromServer.add(cookies.get(i));
                Log.d("TAG", "Сохраняем cookie в глобальную переменную  ="+ cookies.get(i).toString());
            }
        }
    }

    // Создаем клиент OkHTTPRequest и обрабатываем запросы
    void OkHTTPRequest(String postUrl, String requestMethodType, String postData) throws IOException, JSONException
    {
        // Создаем клиент OkHTTPRequest
        OkHttpClient client = new OkHttpClient()
                .newBuilder()
                // Переопределяем методы чтобы можно было сохранять и применять ccokie в запросах
                .cookieJar(new CookieJar()
                {
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies)
                    {
                        saveCookie(cookies);
                        Log.d("TAG", "Вызываем  saveCookie ");
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url)
                    {
                        Log.d("TAG","Читаем cookie");
                        return cookieFromServer;
                    }
                })
                .build();

        Log.d("TAG","Создаем OkHttpClient клиента " + client.toString());

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, postData);
        Request request = new Request.Builder()
                .url(postUrl)
                .method(requestMethodType, body)
                .addHeader("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4")
                .addHeader("Cache-Control", "max-age=0")
                .addHeader("Connection", "keep-alive")
                .addHeader("User-Agent", "Mango Mobile Android")
                .build();

        client.newCall(request).enqueue(new Callback()
        {
            @Override
            public void onFailure(Call call, IOException e)
            {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException
            {
                // Получать response.body().string() можно только один раз. Иначе будет ошибка так реализованно.
                String html = response.body().string();
                //Log.d("TAG", "Код сайта "+ html);
                Document doc = Jsoup.parse(html);
                // Копируем содержание response.body()
                setDoc(doc);
                parseResult(bids);
                // Чтобы обращаться к компанентам из MainActivity нужно использовать runOnUiThread
                MainActivity.this.runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        // Отключаем progressBar
                        progressBar.setVisibility(View.GONE);
                        // Устанавливаем адаптер
                        adapter = new MyRecyclerViewAdapter(MainActivity.this, feedsList);
                        mRecyclerView.setAdapter(adapter);
                    }
                });


            }
        });
    }

    // Сохраняем Document код страницы
    void setDoc(Document doc)
    {
        this.doc = doc;
        // Получаем список БИДОВ
        Log.d("TAD", "Получаем список БИДОВ");
        Elements tmpBids = doc.select("a.go-product[href$=\"vats\"]");

        for (int i = 0; i < tmpBids.size(); i++)
        {
            bids.add(tmpBids.get(i).attr("href"));
            //Log.d("TAD", bids.get(i).toString());
        }
    }


    private void parseResult(List<String> bids)
    {
        // Формируем данные feedsList для адаптера
        Log.d("TAD", "Формируем данные feedsList для адаптера");
        feedsList = new ArrayList<>();
        for (int i = 0; i < bids.size(); i++)
        {
            FeedItem item = new FeedItem();
            item.setTitle(bids.get(i));
            item.setThumbnail("thumbnail");
            feedsList.add(item);
        }
    }
}
Masquitos
  • 554
  • 4
  • 22

2 Answers2

1

There are a few issues with your code.

  1. Method names should be lowercase (Stylistic) OkHTTPRequest(...) was a little confusing at first.
  2. You are firing the HTTP requests asynchronously you can either force the HTTP client to block by calling client.newCall(request).execute() I believe or as the others have suggested use a library like RxJava to handle chaining async commands.
  3. OkHttpClient is meant to be reused for multiple requests especially when using a cookie jar. Ideally you only have one instance of the OkHttpClient and reuse it for multiple requests. Your cookie jar seems like it might work but only because you are using a global list to store cookies which is probably a bad practice.

If you can add the okhttp3.JavaNetCookieJar dependency you can get a working cookie jar out of the box with the following code.

import okhttp3.JavaNetCookieJar;

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
JavaNetCookieJar cookieJar = new JavaNetCookieJar(cookieManager);

OkHttpClient client = new OkHttpClient.Builder().cookieJar(cookieJar).build();

Also, anytime you are having trouble debugging with OkHttp its nice to set up an OkHttp Logging Interceptor.

HttpLoggingInterceptor logging =
    new HttpLoggingInterceptor((msg) -> {
        Log.d(msg);
    });
logging.setLevel(Level.BODY);

client.addNetworkInterceptor(logging);
Bill O'Neil
  • 556
  • 3
  • 13
0

Check Retrofit . It is a great REST client for Android and Java, built on top of OkHttp. It makes working with RxJava a pleasure.

Here's a helpful post that can give you a bit more context on how to chain your requests with Retrofit and RxJava helpful post

Pang
  • 9,564
  • 146
  • 81
  • 122
The Riddler
  • 107
  • 8